Exemplo n.º 1
0
 /// <summary>
 /// Sends a proactive message to a conversation.
 /// </summary>
 /// <param name="botId">The application ID of the bot. This parameter is ignored in
 /// single tenant the Adapters (Console, Test, etc) but is critical to the BotFrameworkAdapter
 /// which is multi-tenant aware. </param>
 /// <param name="reference">A reference to the conversation to continue.</param>
 /// <param name="callback">The method to call for the resulting bot turn.</param>
 /// <param name="cancellationToken">A cancellation token that can be used by other objects
 /// or threads to receive notice of cancellation.</param>
 /// <returns>A task that represents the work queued to execute.</returns>
 /// <remarks>Call this method to proactively send a message to a conversation.
 /// Most _channels require a user to initiate a conversation with a bot
 /// before the bot can send activities to the user.</remarks>
 /// <seealso cref="RunPipelineAsync(ITurnContext, BotCallbackHandler, CancellationToken)"/>
 public virtual Task ContinueConversationAsync(string botId, ConversationReference reference, BotCallbackHandler callback, CancellationToken cancellationToken)
 {
     using (var context = new TurnContext(this, reference.GetContinuationActivity()))
     {
         return(RunPipelineAsync(context, callback, cancellationToken));
     }
 }
        /// <summary>
        /// Sends a proactive message from the bot to a conversation.
        /// </summary>
        /// <param name="botAppId">The application ID of the bot. This is the appId returned by Portal registration, and is
        /// generally found in the "MicrosoftAppId" parameter in appSettings.json.</param>
        /// <param name="reference">A reference to the conversation to continue.</param>
        /// <param name="callback">The method to call for the resulting bot turn.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="botAppId"/>, <paramref name="reference"/>, or
        /// <paramref name="callback"/> is <c>null</c>.</exception>
        /// <remarks>Call this method to proactively send a message to a conversation.
        /// Most _channels require a user to initaiate a conversation with a bot
        /// before the bot can send activities to the user.
        /// <para>This method registers the following services for the turn.<list type="bullet">
        /// <item><see cref="IIdentity"/> (key = "BotIdentity"), a claims identity for the bot.</item>
        /// <item><see cref="IConnectorClient"/>, the channel connector client to use this turn.</item>
        /// </list></para>
        /// <para>
        /// This overload differers from the Node implementation by requiring the BotId to be
        /// passed in. The .Net code allows multiple bots to be hosted in a single adapter which
        /// isn't something supported by Node.
        /// </para>
        /// </remarks>
        /// <seealso cref="ProcessActivity(string, Activity, Func{ITurnContext, Task})"/>
        /// <seealso cref="BotAdapter.RunPipeline(ITurnContext, Func{ITurnContext, Task})"/>
        public override async Task ContinueConversation(string botAppId, ConversationReference reference, Func <ITurnContext, Task> callback)
        {
            if (string.IsNullOrWhiteSpace(botAppId))
            {
                throw new ArgumentNullException(nameof(botAppId));
            }

            if (reference == null)
            {
                throw new ArgumentNullException(nameof(reference));
            }

            if (callback == null)
            {
                throw new ArgumentNullException(nameof(callback));
            }

            using (var context = new TurnContext(this, reference.GetContinuationActivity()))
            {
                // Hand craft Claims Identity.
                var claimsIdentity = new ClaimsIdentity(new List <Claim>
                {
                    // Adding claims for both Emulator and Channel.
                    new Claim(AuthenticationConstants.AudienceClaim, botAppId),
                    new Claim(AuthenticationConstants.AppIdClaim, botAppId)
                });

                context.Services.Add <IIdentity>(BotIdentityKey, claimsIdentity);
                var connectorClient = await CreateConnectorClientAsync(reference.ServiceUrl, claimsIdentity).ConfigureAwait(false);

                context.Services.Add(connectorClient);
                await RunPipeline(context, callback);
            }
        }
Exemplo n.º 3
0
 /// <summary>
 /// Sends a proactive message to a conversation.
 /// </summary>
 /// <param name="botId">The application ID of the bot. This paramter is ignored in
 /// single tenant the Adpters (Console, Test, etc) but is critical to the BotFrameworkAdapter
 /// which is multi-tenant aware. </param>
 /// <param name="reference">A reference to the conversation to continue.</param>
 /// <param name="callback">The method to call for the resulting bot turn.</param>
 /// <returns>A task that represents the work queued to execute.</returns>
 /// <remarks>Call this method to proactively send a message to a conversation.
 /// Most _channels require a user to initaiate a conversation with a bot
 /// before the bot can send activities to the user.</remarks>
 /// <seealso cref="RunPipeline(ITurnContext, Func{ITurnContext, Task})"/>
 public virtual Task ContinueConversation(string botId, ConversationReference reference, Func <ITurnContext, Task> callback, CancellationToken cancellationToken)
 {
     using (var context = new TurnContext(this, reference.GetContinuationActivity()))
     {
         return(RunPipeline(context, callback, cancellationToken));
     }
 }
Exemplo n.º 4
0
        public async Task ProcessContinueConversationEvent()
        {
            var mockCredentialProvider = new Mock <ICredentialProvider>();
            var mockHttpMessageHandler = new Mock <HttpMessageHandler>();
            var httpClient             = new HttpClient(mockHttpMessageHandler.Object);
            var adapter = new BotFrameworkAdapter(mockCredentialProvider.Object, customHttpClient: httpClient);

            ConversationReference cr = new ConversationReference
            {
                ActivityId = "activityId",
                Bot        = new ChannelAccount
                {
                    Id   = "channelId",
                    Name = "testChannelAccount",
                    Role = "bot",
                },
                ChannelId    = "testChannel",
                ServiceUrl   = "https://fake.service.url",
                Conversation = new ConversationAccount
                {
                    ConversationType = string.Empty,
                    Id      = "testConversationId",
                    IsGroup = false,
                    Name    = "testConversationName",
                    Role    = "user",
                },
                User = new ChannelAccount
                {
                    Id   = "channelId",
                    Name = "testChannelAccount",
                    Role = "bot",
                },
            };

            var activity = cr.GetContinuationActivity();

            activity.Value = "test";

            // Create ClaimsIdentity that represents Skill1-to-Skill1 communication
            var appId = "00000000-0000-0000-0000-000000skill1";

            var claims = new List <Claim>
            {
                new Claim(AuthenticationConstants.AudienceClaim, appId),
                new Claim(AuthenticationConstants.AppIdClaim, appId),
                new Claim(AuthenticationConstants.VersionClaim, "1.0")
            };
            var identity = new ClaimsIdentity(claims);

            var callback = new BotCallbackHandler(async(turnContext, ct) =>
            {
                var cr2        = turnContext.Activity.GetConversationReference();
                cr.ActivityId  = null; // activityids will be different...
                cr2.ActivityId = null;
                Assert.Equal(JsonConvert.SerializeObject(cr), JsonConvert.SerializeObject(cr2));
                Assert.Equal("test", (string)turnContext.Activity.Value);
            });

            await adapter.ProcessActivityAsync(identity, (Activity)activity, callback, default);
        /// <inheritdoc/>
        public override Task ContinueConversationAsync(ClaimsIdentity claimsIdentity, ConversationReference reference, string audience, BotCallbackHandler callback, CancellationToken cancellationToken)
        {
            _ = claimsIdentity ?? throw new ArgumentNullException(nameof(claimsIdentity));
            _ = reference ?? throw new ArgumentNullException(nameof(reference));
            _ = callback ?? throw new ArgumentNullException(nameof(callback));

            return(ProcessProactiveAsync(claimsIdentity, reference.GetContinuationActivity(), audience, callback, cancellationToken));
        }
Exemplo n.º 6
0
 /// <summary>
 /// Sends a proactive message from the bot to a conversation.
 /// </summary>
 /// <param name="claimsIdentity">A <see cref="ClaimsIdentity"/> for the conversation.</param>
 /// <param name="reference">A reference to the conversation to continue.</param>
 /// <param name="callback">The method to call for the resulting bot turn.</param>
 /// <param name="cancellationToken">Cancellation token.</param>
 /// <returns>A task that represents the work queued to execute.</returns>
 /// <remarks>Call this method to proactively send a message to a conversation.
 /// Most _channels require a user to initialize a conversation with a bot
 /// before the bot can send activities to the user.
 /// <para>This method registers the following services for the turn.<list type="bullet">
 /// <item><description><see cref="IIdentity"/> (key = "BotIdentity"), a claims claimsIdentity for the bot.
 /// </description></item>
 /// </list></para>
 /// </remarks>
 /// <seealso cref="BotAdapter.RunPipelineAsync(ITurnContext, BotCallbackHandler, CancellationToken)"/>
 public override async Task ContinueConversationAsync(ClaimsIdentity claimsIdentity, ConversationReference reference, BotCallbackHandler callback, CancellationToken cancellationToken)
 {
     using (var context = new TurnContext(this, reference.GetContinuationActivity()))
     {
         context.TurnState.Add <IIdentity>(BotIdentityKey, claimsIdentity);
         context.TurnState.Add <BotCallbackHandler>(callback);
         await RunPipelineAsync(context, callback, cancellationToken).ConfigureAwait(false);
     }
 }
Exemplo n.º 7
0
        // TODO: oauth prompt support

        /// <summary>
        /// The implementation for continue conversation.
        /// </summary>
        /// <param name="claimsIdentity">A <see cref="ClaimsIdentity"/> for the conversation.</param>
        /// <param name="reference">A <see cref="ConversationReference"/> for the conversation.</param>
        /// <param name="audience">The audience for the call.</param>
        /// <param name="callback">The method to call for the resulting bot turn.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        protected async Task ProcessProactiveAsync(ClaimsIdentity claimsIdentity, ConversationReference reference, string audience, BotCallbackHandler callback, CancellationToken cancellationToken)
        {
            // Use the cloud environment to create the credentials for proactive requests.
            var credentials = await _botFrameworkAuthentication.GetProactiveCredentialsAsync(claimsIdentity, audience, cancellationToken).ConfigureAwait(false);

            // Create the connector client to use for outbound requests.
            var connectorClient = new ConnectorClient(new Uri(reference.ServiceUrl), credentials, _httpClient);

            // Create a turn context and run the pipeline.
            using (var context = CreateTurnContext(reference.GetContinuationActivity(), claimsIdentity, audience, connectorClient, callback))
            {
                // Run the pipeline.
                await RunPipelineAsync(context, callback, cancellationToken).ConfigureAwait(false);
            }
        }
Exemplo n.º 8
0
        public async Task ContinueConversationAsync(ConversationReference reference, BotCallbackHandler logic, CancellationToken cancellationToken)
        {
            if (reference == null)
            {
                throw new ArgumentNullException(nameof(reference));
            }
            if (logic == null)
            {
                throw new ArgumentNullException(nameof(logic));
            }
            var request = reference.GetContinuationActivity().ApplyConversationReference(reference, true);

            using (var context = new TurnContext(this, request))
            {
                await RunPipelineAsync(context, logic, cancellationToken).ConfigureAwait(false);
            }
        }
        // TODO: oauth prompt support

        /// <summary>
        /// The implementation for continue conversation.
        /// </summary>
        /// <param name="claimsIdentity">A <see cref="ClaimsIdentity"/> for the conversation.</param>
        /// <param name="reference">A <see cref="ConversationReference"/> for the conversation.</param>
        /// <param name="audience">The audience for the call.</param>
        /// <param name="callback">The method to call for the resulting bot turn.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        protected async Task ProcessProactiveAsync(ClaimsIdentity claimsIdentity, ConversationReference reference, string audience, BotCallbackHandler callback, CancellationToken cancellationToken)
        {
            // Use the cloud environment to create the credentials for proactive requests.
            var proactiveCredentialsResult = await _botFrameworkAuthentication.GetProactiveCredentialsAsync(claimsIdentity, audience, cancellationToken).ConfigureAwait(false);

            // Create the connector client to use for outbound requests.
            using (var connectorClient = new ConnectorClient(new Uri(reference.ServiceUrl), proactiveCredentialsResult.Credentials, _httpClient, disposeHttpClient: _httpClient == null))
            {
                // Create a turn context and run the pipeline.
                using (var context = CreateTurnContext(reference.GetContinuationActivity(), claimsIdentity, proactiveCredentialsResult.Scope, connectorClient, callback))
                {
                    // Run the pipeline.
                    await RunPipelineAsync(context, callback, cancellationToken).ConfigureAwait(false);

                    // Cleanup disposable resources in case other code kept a reference to it.
                    context.TurnState.Set <IConnectorClient>(null);
                }
            }
        }
Exemplo n.º 10
0
        public void ConversationReferenceGetContinuationActivity()
        {
            var locale       = new CultureInfo("es-es");
            var activityId   = "activityId";
            var user         = new ChannelAccount("userId", "userName", "userRole", "userAadObjectId");
            var bot          = new ChannelAccount("botId", "botName", "botRole", "botAadObjectId");
            var conversation = new ConversationAccount();
            var channelId    = "channelId";
            var serviceUrl   = "http://myServiceUrl.com";
            var convoRef     = new ConversationReference(locale, activityId, user, bot, conversation, channelId, serviceUrl);

            var continuationActivity = convoRef.GetContinuationActivity();

            Assert.NotNull(continuationActivity);
            Assert.IsType <Activity>(continuationActivity);
            Assert.Equal(ActivityEventNames.ContinueConversation, continuationActivity.Name);
            Assert.Equal(channelId, continuationActivity.ChannelId);
            Assert.Equal(locale.ToString(), continuationActivity.Locale);
            Assert.Equal(serviceUrl, continuationActivity.ServiceUrl);
        }
        /// <summary>
        /// Sends a proactive message to a conversation.
        /// </summary>
        /// <param name="botAppId">The application ID of the bot. This parameter is ignored in
        /// single tenant the Adapters (Console, Test, etc) but is critical to the BotFrameworkAdapter
        /// which is multi-tenant aware. </param>
        /// <param name="reference">A reference to the conversation to continue.</param>
        /// <param name="callback">The method to call for the resulting bot turn.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        /// <remarks>Call this method to proactively send a message to a conversation.
        /// Most _channels require a user to initiate a conversation with a bot
        /// before the bot can send activities to the user.</remarks>
        public override async Task ContinueConversationAsync(string botAppId, ConversationReference reference, BotCallbackHandler callback, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(botAppId))
            {
                throw new ArgumentNullException(nameof(botAppId));
            }

            if (reference == null)
            {
                throw new ArgumentNullException(nameof(reference));
            }

            if (callback == null)
            {
                throw new ArgumentNullException(nameof(callback));
            }

            _logger.LogInformation($"Sending proactive message. botAppId: {botAppId}");

            await ProcessActivityAsync(reference.GetContinuationActivity(), callback, cancellationToken).ConfigureAwait(false);
        }
Exemplo n.º 12
0
        public override async Task ContinueConversationAsync(string botId, ConversationReference reference, BotCallbackHandler callback, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(botId))
            {
                throw new ArgumentNullException(nameof(botId));
            }

            if (reference == null)
            {
                throw new ArgumentNullException(nameof(reference));
            }

            if (callback == null)
            {
                throw new ArgumentNullException(nameof(callback));
            }

            using (var context = new TurnContext(this, reference.GetContinuationActivity()))
            {
                await RunPipelineAsync(context, callback, cancellationToken);
            }
        }
        /// <summary>
        /// Sends a proactive message from the bot to a conversation.
        /// </summary>
        /// <param name="botAppId">The application ID of the bot. This is the appId returned by Portal registration, and is
        /// generally found in the "MicrosoftAppId" parameter in appSettings.json.</param>
        /// <param name="reference">A reference to the conversation to continue.</param>
        /// <param name="callback">The method to call for the resulting bot turn.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="botAppId"/>, <paramref name="reference"/>, or
        /// <paramref name="callback"/> is <c>null</c>.</exception>
        /// <remarks>Call this method to proactively send a message to a conversation.
        /// Most _channels require a user to initaiate a conversation with a bot
        /// before the bot can send activities to the user.
        /// <para>This method registers the following services for the turn.<list type="bullet">
        /// <item><see cref="IIdentity"/> (key = "BotIdentity"), a claims identity for the bot.</item>
        /// <item><see cref="IConnectorClient"/>, the channel connector client to use this turn.</item>
        /// </list></para>
        /// <para>
        /// This overload differers from the Node implementation by requiring the BotId to be
        /// passed in. The .Net code allows multiple bots to be hosted in a single adapter which
        /// isn't something supported by Node.
        /// </para>
        /// </remarks>
        /// <seealso cref="ProcessActivityAsync(string, Activity, BotCallbackHandler, CancellationToken)"/>
        /// <seealso cref="BotAdapter.RunPipelineAsync(ITurnContext, BotCallbackHandler, CancellationToken)"/>
        public override async Task ContinueConversationAsync(string botAppId, ConversationReference reference, BotCallbackHandler callback, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(botAppId))
            {
                throw new ArgumentNullException(nameof(botAppId));
            }

            if (reference == null)
            {
                throw new ArgumentNullException(nameof(reference));
            }

            if (callback == null)
            {
                throw new ArgumentNullException(nameof(callback));
            }

            _logger.LogInformation($"Sending proactive message.  botAppId: {botAppId}");

            using (var context = new TurnContext(this, reference.GetContinuationActivity()))
            {
                // Hand craft Claims Identity.
                var claimsIdentity = new ClaimsIdentity(new List <Claim>
                {
                    // Adding claims for both Emulator and Channel.
                    new Claim(AuthenticationConstants.AudienceClaim, botAppId),
                    new Claim(AuthenticationConstants.AppIdClaim, botAppId),
                });

                context.TurnState.Add <IIdentity>(BotIdentityKey, claimsIdentity);
                var connectorClient = await CreateConnectorClientAsync(reference.ServiceUrl, claimsIdentity, cancellationToken).ConfigureAwait(false);

                context.TurnState.Add(connectorClient);
                await RunPipelineAsync(context, callback, cancellationToken).ConfigureAwait(false);
            }
        }
        /// <inheritdoc/>
        public override Task ContinueConversationAsync(string botAppId, ConversationReference reference, BotCallbackHandler callback, CancellationToken cancellationToken)
        {
            _ = reference ?? throw new ArgumentNullException(nameof(reference));

            return(ProcessProactiveAsync(CreateClaimsIdentity(botAppId), reference.GetContinuationActivity(), null, callback, cancellationToken));
        }