diff --git a/.gitignore b/.gitignore
index 1635c14d55..54da99a7b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -383,6 +383,7 @@ experimental/generator-dotnet-yeoman/node_modules
# Allow the root-level /packages/ directory or it gets confused with NuGet directories
!/[Pp]ackages/*
+!/tests/[Pp]ackages/*
# Allow the packages directory under tests
!/tests/unit/[Pp]ackages/*
diff --git a/build/yaml/pipelines/telephony.yml b/build/yaml/pipelines/telephony.yml
index d18a52503d..7d92da5200 100644
--- a/build/yaml/pipelines/telephony.yml
+++ b/build/yaml/pipelines/telephony.yml
@@ -7,8 +7,6 @@ pool:
extends:
template: ../templates/component-template.yml
- parameters:
- PublishPackageArtifacts: # parameter is set in ADO
variables:
BuildConfiguration: 'Release'
diff --git a/build/yaml/templates/nuget-versioning-steps.yml b/build/yaml/templates/nuget-versioning-steps.yml
index 9192584a46..022e483ed7 100644
--- a/build/yaml/templates/nuget-versioning-steps.yml
+++ b/build/yaml/templates/nuget-versioning-steps.yml
@@ -53,7 +53,7 @@ steps:
# Configure version suffix based on deployment ring
if ($deploymentRing.ToLowerInvariant() -ne "stable") {
- $nugetVersionSuffix = $deploymentRing + $vs;
+ $nugetVersionSuffix = $deploymentRing;
"Version Suffix = $nugetVersionSuffix";
$packageVersion += "-" + $nugetVersionSuffix;
}
@@ -73,4 +73,4 @@ steps:
NugetPackageVersion: $(NugetPackageVersion)
continueOnError: true
-- template: debug-workspace-steps.yml
\ No newline at end of file
+- template: debug-workspace-steps.yml
diff --git a/packages/Microsoft.Bot.Components.sln b/packages/Microsoft.Bot.Components.sln
index 649edc2e7c..ffc6cf54e9 100644
--- a/packages/Microsoft.Bot.Components.sln
+++ b/packages/Microsoft.Bot.Components.sln
@@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Components.Ad
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Components.Teams", "Teams\dotnet\Microsoft.Bot.Components.Teams.csproj", "{FD29CBA6-C18F-498B-9F00-A3C34C1BEC5F}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Bot.Components.Telephony", "Telephony\Microsoft.Bot.Components.Telephony.csproj", "{A854B5EC-3A34-4D1F-8080-F0846DEDF63F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -27,6 +29,10 @@ Global
{FD29CBA6-C18F-498B-9F00-A3C34C1BEC5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD29CBA6-C18F-498B-9F00-A3C34C1BEC5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD29CBA6-C18F-498B-9F00-A3C34C1BEC5F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A854B5EC-3A34-4D1F-8080-F0846DEDF63F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A854B5EC-3A34-4D1F-8080-F0846DEDF63F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A854B5EC-3A34-4D1F-8080-F0846DEDF63F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A854B5EC-3A34-4D1F-8080-F0846DEDF63F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/packages/Telephony/Actions/CallTransfer.cs b/packages/Telephony/Actions/CallTransfer.cs
new file mode 100644
index 0000000000..d89250c1f5
--- /dev/null
+++ b/packages/Telephony/Actions/CallTransfer.cs
@@ -0,0 +1,71 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System.Runtime.CompilerServices;
+using System.Threading;
+using System.Threading.Tasks;
+using AdaptiveExpressions.Properties;
+using Microsoft.Bot.Builder.Dialogs;
+using Microsoft.Bot.Builder.Dialogs.Adaptive.Actions;
+using Microsoft.Bot.Connector;
+using Newtonsoft.Json;
+
+namespace Microsoft.Bot.Components.Telephony.Actions
+{
+ ///
+ /// Transfers call to given phone number.
+ ///
+ public class CallTransfer : SendHandoffActivity
+ {
+ ///
+ /// Class identifier.
+ ///
+ [JsonProperty("$kind")]
+ public new const string Kind = "Microsoft.Telephony.CallTransfer";
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Optional, source file full path.
+ /// Optional, line number in source file.
+ [JsonConstructor]
+ public CallTransfer([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ : base()
+ {
+ // enable instances of this command as debug break point
+ this.RegisterSourceLocation(sourceFilePath, sourceLineNumber);
+ }
+
+ ///
+ /// Gets or sets the phone number to be included when sending the handoff activity.
+ ///
+ ///
+ /// .
+ ///
+ [JsonProperty("phoneNumber")]
+ public StringExpression PhoneNumber { get; set; }
+
+ ///
+ /// Called when the dialog is started and pushed onto the dialog stack.
+ ///
+ /// The for the current turn of conversation.
+ /// Optional, initial information to pass to the dialog.
+ /// A cancellation token that can be used by other objects
+ /// or threads to receive notice of cancellation.
+ /// A representing the asynchronous operation.
+ public async override Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ if (dc.Context.Activity.ChannelId == Channels.Telephony)
+ {
+ var phoneNumber = this.PhoneNumber?.GetValue(dc.State);
+
+ // Create handoff event, passing the phone number to transfer to as context.
+ HandoffContext = new { TargetPhoneNumber = phoneNumber };
+
+ return await base.BeginDialogAsync(dc, options, cancellationToken).ConfigureAwait(false);
+ }
+
+ return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/Telephony/Actions/PauseRecording.cs b/packages/Telephony/Actions/PauseRecording.cs
new file mode 100644
index 0000000000..b80b5f81bf
--- /dev/null
+++ b/packages/Telephony/Actions/PauseRecording.cs
@@ -0,0 +1,63 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System.Runtime.CompilerServices;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Bot.Builder.Dialogs;
+using Microsoft.Bot.Components.Telephony.Common;
+using Microsoft.Bot.Connector;
+using Newtonsoft.Json;
+
+namespace Microsoft.Bot.Components.Telephony.Actions
+{
+ ///
+ /// Pauses recording the current conversation.
+ ///
+ public class PauseRecording : CommandDialog
+ {
+ ///
+ /// Class identifier.
+ ///
+ [JsonProperty("$kind")]
+ public const string Kind = "Microsoft.Telephony.PauseRecording";
+
+ private const string RecordingPause = "channel/vnd.microsoft.telephony.recording.pause";
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Optional, source file full path.
+ /// Optional, line number in source file.
+ [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.CommandName = RecordingPause;
+ }
+
+ public async override Task 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 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/Telephony/Actions/ResumeRecording.cs b/packages/Telephony/Actions/ResumeRecording.cs
new file mode 100644
index 0000000000..c089f20ae3
--- /dev/null
+++ b/packages/Telephony/Actions/ResumeRecording.cs
@@ -0,0 +1,63 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System.Runtime.CompilerServices;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Bot.Builder.Dialogs;
+using Microsoft.Bot.Components.Telephony.Common;
+using Microsoft.Bot.Connector;
+using Newtonsoft.Json;
+
+namespace Microsoft.Bot.Components.Telephony.Actions
+{
+ ///
+ /// Resume recording the current conversation.
+ ///
+ public class ResumeRecording : CommandDialog
+ {
+ public const string RecordingResume = "channel/vnd.microsoft.telephony.recording.resume";
+
+ ///
+ /// Class identifier.
+ ///
+ [JsonProperty("$kind")]
+ public const string Kind = "Microsoft.Telephony.ResumeRecording";
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Optional, source file full path.
+ /// Optional, line number in source file.
+ [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.CommandName = RecordingResume;
+ }
+
+ public async override Task 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 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/Telephony/Actions/StartRecording.cs b/packages/Telephony/Actions/StartRecording.cs
new file mode 100644
index 0000000000..82d2a5c3f9
--- /dev/null
+++ b/packages/Telephony/Actions/StartRecording.cs
@@ -0,0 +1,65 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System.Runtime.CompilerServices;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Bot.Builder.Dialogs;
+using Microsoft.Bot.Components.Telephony.Common;
+using Microsoft.Bot.Connector;
+using Newtonsoft.Json;
+
+namespace Microsoft.Bot.Components.Telephony.Actions
+{
+ ///
+ /// Starts recording the current conversation.
+ ///
+ public class StartRecording : CommandDialog
+ {
+ ///
+ /// Class identifier.
+ ///
+ [JsonProperty("$kind")]
+ public const string Kind = "Microsoft.Telephony.StartRecording";
+
+ private const string RecordingStart = "channel/vnd.microsoft.telephony.recording.start";
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Optional, source file full path.
+ /// Optional, line number in source file.
+ [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.CommandName = RecordingStart;
+ }
+
+ ///
+ public async override Task 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 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/Telephony/Common/CommandDialog.cs b/packages/Telephony/Common/CommandDialog.cs
new file mode 100644
index 0000000000..6e39ed7905
--- /dev/null
+++ b/packages/Telephony/Common/CommandDialog.cs
@@ -0,0 +1,12 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Bot.Components.Telephony.Common
+{
+ ///
+ /// Generic dialog to orchestrate issuing command activities and releasing control once a command result is received.
+ ///
+ public class CommandDialog : CommandDialog