Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions packages/Telephony/Actions/PauseRecording.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Bot.Components.Telephony.Actions
{
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Components.Telephony.Common;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Telephony;
using Newtonsoft.Json;

/// <summary>
/// Stops recording the current conversation.
/// </summary>
public class PauseRecording : CommandDialog
{
private const string RecordingPause = "channel/vnd.microsoft.telephony.recording.pause";

/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Microsoft.Telephony.PauseRecording";

/// <summary>
/// Initializes a new instance of the <see cref="PauseRecording"/> class.
/// </summary>
/// <param name="sourceFilePath">Optional, source file full path.</param>
/// <param name="sourceLineNumber">Optional, line number in source file.</param>
[JsonConstructor]
public PauseRecording([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
: base()
{
// enable instances of this command as debug break point
this.RegisterSourceLocation(sourceFilePath, sourceLineNumber);

this.Name = RecordingPause;
}

public async override Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default)
{
if (dc.Context.Activity.ChannelId == Channels.Telephony)
{
return await base.BeginDialogAsync(dc, options, cancellationToken).ConfigureAwait(false);
}

return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}

public override async Task<DialogTurnResult> ContinueDialogAsync(DialogContext dc, CancellationToken cancellationToken = default)
{
// TODO: Carlos try to delete
if (dc.Context.Activity.ChannelId == Channels.Telephony)
{
return await base.ContinueDialogAsync(dc, cancellationToken).ConfigureAwait(false);
}

return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
}
}
68 changes: 68 additions & 0 deletions packages/Telephony/Actions/ResumeRecording.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Bot.Components.Telephony.Actions
{
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Components.Telephony.Common;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Telephony;
using Newtonsoft.Json;

/// <summary>
/// Resume recording the current conversation.
/// </summary>
public class ResumeRecording : CommandDialog
{
public const string RecordingResume = "channel/vnd.microsoft.telephony.recording.resume";

/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Microsoft.Telephony.PauseRecording";

/// <summary>
/// Initializes a new instance of the <see cref="ResumeRecording"/> class.
/// </summary>
/// <param name="sourceFilePath">Optional, source file full path.</param>
/// <param name="sourceLineNumber">Optional, line number in source file.</param>
[JsonConstructor]
public ResumeRecording([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
: base()
{
// enable instances of this command as debug break point
this.RegisterSourceLocation(sourceFilePath, sourceLineNumber);

this.Name = RecordingResume;
}

public async override Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default)
{
if (dc.Context.Activity.ChannelId == Channels.Telephony)
{
return await base.BeginDialogAsync(dc, options, cancellationToken).ConfigureAwait(false);
}

return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}

public override async Task<DialogTurnResult> ContinueDialogAsync(DialogContext dc, CancellationToken cancellationToken = default)
{
// TODO: Carlos try to delete
if (dc.Context.Activity.ChannelId == Channels.Telephony)
{
return await base.ContinueDialogAsync(dc, cancellationToken).ConfigureAwait(false);
}

return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
}
}
74 changes: 74 additions & 0 deletions packages/Telephony/Actions/StartRecording.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Bot.Components.Telephony.Actions
{
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Components.Telephony.Common;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Telephony;
using Newtonsoft.Json;

/// <summary>
/// Stars recording the current conversation.
/// </summary>
public class StartRecording : CommandDialog<RecordingStartSettings>
{
private const string RecordingStart = "channel/vnd.microsoft.telephony.recording.start";

/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Microsoft.Telephony.StartRecording";

/// <summary>
/// Initializes a new instance of the <see cref="StartRecording"/> class.
/// </summary>
/// <param name="sourceFilePath">Optional, source file full path.</param>
/// <param name="sourceLineNumber">Optional, line number in source file.</param>
[JsonConstructor]
public StartRecording([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
: base()
{
// enable instances of this command as debug break point
this.RegisterSourceLocation(sourceFilePath, sourceLineNumber);

this.Name = RecordingStart;

this.Data = new RecordingStartSettings()
{
RecordingChannelType = RecordingChannelType.Mixed,
RecordingContentType = RecordingContentType.AudioVideo,
};
}

public async override Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default)
{
if (dc.Context.Activity.ChannelId == Channels.Telephony)
{
return await base.BeginDialogAsync(dc, options, cancellationToken).ConfigureAwait(false);
}

return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}

public override async Task<DialogTurnResult> ContinueDialogAsync(DialogContext dc, CancellationToken cancellationToken = default)
{
// TODO: Carlos try to delete
if (dc.Context.Activity.ChannelId == Channels.Telephony)
{
return await base.ContinueDialogAsync(dc, cancellationToken).ConfigureAwait(false);
}

return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
}
}
110 changes: 110 additions & 0 deletions packages/Telephony/Common/CommandDialog.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Schema;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.Bot.Components.Telephony.Common
{
public class CommandDialog : CommandDialog<object>
{

}

public class CommandDialog<T> : Dialog
{
/// <summary>
/// Gets or sets the phone number to be included when sending the handoff activity.
/// </summary>
/// <value>
/// <see cref="StringExpression"/>.
/// </value>
protected StringExpression Name { get; set; }

/// <summary>
/// Gets or sets the phone number to be included when sending the handoff activity.
/// </summary>
/// <value>
/// <see cref="StringExpression"/>.
/// </value>
protected T Data { get; set; }

public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default)
{
// TODO: check name not null / expression has value

var startRecordingActivity = CreateCommandActivity<T>(dc.Context, this.Data, this.Name.GetValue(dc.State));

var response = await dc.Context.SendActivityAsync(startRecordingActivity, cancellationToken).ConfigureAwait(false);

return new DialogTurnResult(DialogTurnStatus.Waiting, startRecordingActivity.Name);
}

public override async Task<DialogTurnResult> ContinueDialogAsync(DialogContext dc, CancellationToken cancellationToken = default)
{
// check activity
var activity = dc.Context.Activity;

// If command result, handle it
if (activity.Type == ActivityTypes.CommandResult
&& activity.Name == this.Name.GetValue(dc.State))
{
var commandResult = TelephonyExtensions.GetCommandResultValue(activity);

if (commandResult.Error != null)
{
throw new ErrorResponseException($"{commandResult.Error.Code}: {commandResult.Error.Message}");
}

// TODO: correlate command ids

return new DialogTurnResult(DialogTurnStatus.Complete);
}

// for now, end turn and keep waiting
// TODO: Carlos add interruption model
return new DialogTurnResult(DialogTurnStatus.Waiting);
}

private static Activity CreateCommandActivity<TValue>(ITurnContext turnContext, T data, string name)
{
if (turnContext == null)
{
throw new ArgumentNullException(nameof(turnContext));
}

if (string.IsNullOrEmpty(name))
{
throw new ArgumentNullException(nameof(name));
}

var commandActivity = new Activity(type: ActivityTypes.Command);

commandActivity.Name = name;

var commandValue = new CommandValue<T>()
{
CommandId = Guid.NewGuid().ToString(),
Data = data,
};

commandActivity.Value = commandValue;

commandActivity.From = turnContext.Activity.From;

// TODO: Check with SDK crew
//commandActivity.RelatesTo = turnContext.Activity.GetConversationReference();

commandActivity.ReplyToId = turnContext.Activity.Id;
commandActivity.ServiceUrl = turnContext.Activity.ServiceUrl;
commandActivity.ChannelId = turnContext.Activity.ChannelId;

return commandActivity;
}
}
}
24 changes: 24 additions & 0 deletions packages/Telephony/Common/RecordingStartSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.Bot.Schema.Telephony
{
public enum RecordingContentType
{
Audio,
AudioVideo
}

public enum RecordingChannelType
{
Mixed,
Unmixed
}

public class RecordingStartSettings
{
public RecordingContentType RecordingContentType { get; set; }
public RecordingChannelType RecordingChannelType { get; set; }
}
}
Loading