Пример #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);
        }