Example #1
0
        protected async Task <T> InvokeChannelApiAsync <T>(ClaimsIdentity claimsIdentity, string method, string conversationId, params object[] args)
        {
            var skillConversation = new SkillConversation(conversationId);

            var channelApiInvokeActivity = Activity.CreateInvokeActivity();

            channelApiInvokeActivity.Name         = InvokeActivityName;
            channelApiInvokeActivity.ChannelId    = "unknown";
            channelApiInvokeActivity.ServiceUrl   = skillConversation.ServiceUrl;
            channelApiInvokeActivity.Conversation = new ConversationAccount(id: skillConversation.ConversationId);
            channelApiInvokeActivity.From         = new ChannelAccount(id: "unknown");
            channelApiInvokeActivity.Recipient    = new ChannelAccount(id: "unknown", role: RoleTypes.Bot);

            var activityPayload = args?.Where(arg => arg is Activity).Cast <Activity>().FirstOrDefault();

            if (activityPayload != null)
            {
                // fix up activityPayload with original conversation.Id and id
                activityPayload.Conversation.Id = skillConversation.ConversationId;
                activityPayload.ServiceUrl      = skillConversation.ServiceUrl;

                // use the activityPayload for channel accounts, it will be in From=Bot/Skill Recipient=User,
                // We want to send it to the bot as From=User, Recipient=Bot so we have correct state context.
                channelApiInvokeActivity.ChannelId = activityPayload.ChannelId;
                channelApiInvokeActivity.From      = activityPayload.Recipient;
                channelApiInvokeActivity.Recipient = activityPayload.From;

                // We want ActivityPayload to also be in User->Bot context, if it is outbound it will go through context.SendActivity which will flip outgoing to Bot->User
                // regardless this gives us same memory context of User->Bot which is useful for things like EndOfConversation processing being in the correct memory context.
                activityPayload.From      = channelApiInvokeActivity.From;
                activityPayload.Recipient = channelApiInvokeActivity.Recipient;
            }

            var channelApiArgs = new ChannelApiArgs
            {
                Method = method,
                Args   = args
            };

            channelApiInvokeActivity.Value = channelApiArgs;

            // We call our adapter using the BotAppId claim, so turnContext has the bot claims
            // var claimsIdentity = new ClaimsIdentity(new List<Claim>
            // {
            //     new Claim(AuthenticationConstants.AudienceClaim, this.BotAppId),
            //     new Claim(AuthenticationConstants.AppIdClaim, this.BotAppId),
            //     new Claim(AuthenticationConstants.ServiceUrlClaim, skillConversation.ServiceUrl),
            // });

            // send up to the bot to process it...
            await ChannelAdapter.ProcessActivityAsync(claimsIdentity, (Activity)channelApiInvokeActivity, Bot.OnTurnAsync, CancellationToken.None).ConfigureAwait(false);

            if (channelApiArgs.Exception != null)
            {
                throw channelApiArgs.Exception;
            }

            // Return the result that was captured in the middleware handler.
            return((T)channelApiArgs.Result);
        }
Example #2
0
        private async Task CallChannelApiAsync(ITurnContext turnContext, NextDelegate next, ChannelApiArgs invokeArgs, CancellationToken cancellationToken)
        {
            try
            {
                var adapter = turnContext.Adapter as BotFrameworkAdapter;

                switch (invokeArgs.Method)
                {
                // Send activity(activity)
                case ChannelApiMethods.SendToConversation:
                {
                    var activityPayload = (Activity)invokeArgs.Args[0];
                    if (activityPayload.Type == ActivityTypes.EndOfConversation)
                    {
                        await ProcessEndOfConversationAsync(turnContext, next, activityPayload, cancellationToken).ConfigureAwait(false);

                        invokeArgs.Result = new ResourceResponse(id: Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture));
                        return;
                    }

                    invokeArgs.Result = await turnContext.SendActivityAsync(activityPayload, cancellationToken).ConfigureAwait(false);

                    return;
                }

                // Send activity(replyToId, activity)
                case ChannelApiMethods.ReplyToActivity:
                {
                    var activityPayload = (Activity)invokeArgs.Args[1];
                    activityPayload.ReplyToId = (string)invokeArgs.Args[0];

                    if (activityPayload.Type == ActivityTypes.EndOfConversation)
                    {
                        await ProcessEndOfConversationAsync(turnContext, next, activityPayload, cancellationToken).ConfigureAwait(false);

                        invokeArgs.Result = new ResourceResponse(id: Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture));
                        return;
                    }

                    invokeArgs.Result = await turnContext.SendActivityAsync(activityPayload, cancellationToken).ConfigureAwait(false);

                    return;
                }

                // UpdateActivity(activity)
                case ChannelApiMethods.UpdateActivity:
                    invokeArgs.Result = await turnContext.UpdateActivityAsync((Activity)invokeArgs.Args[0], cancellationToken).ConfigureAwait(false);

                    return;

                // DeleteActivity(activityId)
                case ChannelApiMethods.DeleteActivity:
                    await turnContext.DeleteActivityAsync((string)invokeArgs.Args[0], cancellationToken).ConfigureAwait(false);

                    break;

                // SendConversationHistory(history)
                case ChannelApiMethods.SendConversationHistory:
                    throw new NotImplementedException($"{ChannelApiMethods.SendConversationHistory} is not supported");

                // GetConversationMembers()
                case ChannelApiMethods.GetConversationMembers:
                    if (adapter != null)
                    {
                        invokeArgs.Result = await adapter.GetConversationMembersAsync(turnContext, cancellationToken).ConfigureAwait(false);
                    }

                    break;

                // GetConversationPageMembers((int)pageSize, continuationToken)
                case ChannelApiMethods.GetConversationPagedMembers:
                    throw new NotImplementedException($"{ChannelApiMethods.SendConversationHistory} is not supported");

                //if (adapter != null)
                //{
                //    invokeArgs.Result = await adapter.GetConversationsAsync((int)invokeArgs.Args[0], (string)invokeArgs.Args[1], cancellationToken).ConfigureAwait(false);
                //}

                // DeleteConversationMember(memberId)
                case ChannelApiMethods.DeleteConversationMember:
                    if (adapter != null)
                    {
                        await adapter.DeleteConversationMemberAsync(turnContext, (string)invokeArgs.Args[0], cancellationToken).ConfigureAwait(false);
                    }

                    break;

                // GetActivityMembers(activityId)
                case ChannelApiMethods.GetActivityMembers:
                    if (adapter != null)
                    {
                        invokeArgs.Result = await adapter.GetActivityMembersAsync(turnContext, (string)invokeArgs.Args[0], cancellationToken).ConfigureAwait(false);
                    }

                    break;

                case ChannelApiMethods.UploadAttachment:
                    throw new NotImplementedException($"{ChannelApiMethods.UploadAttachment} is not supported");
                }
            }
#pragma warning disable CA1031 // Do not catch general exception types (excluding, we use the general exception to store it in the inokeArgs).
            catch (Exception ex)
            {
                invokeArgs.Exception = ex;
            }
#pragma warning restore CA1031 // Do not catch general exception types
        }