/// <summary>
        /// Send card to SME channel and storage conversation details in storage.
        /// </summary>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="ticketDetail">Ticket details entered by user.</param>
        /// <param name="logger">Sends logs to the Application Insights service.</param>
        /// <param name="ticketDetailStorageProvider">Provider to store ticket details to Azure Table Storage.</param>
        /// <param name="applicationBasePath">Represents the Application base Uri.</param>
        /// <param name="cardElementMapping">Represents Adaptive card item element {Id, display name} mapping.</param>
        /// <param name="localizer">The current cultures' string localizer.</param>
        /// <param name="teamId">Represents unique id of a Team.</param>
        /// <param name="microsoftAppCredentials">Microsoft Application credentials for Bot/ME.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
        /// <returns>Returns message in a conversation.</returns>
        public static async Task <ConversationResourceResponse> SendRequestCardToSMEChannelAsync(
            ITurnContext <IMessageActivity> turnContext,
            TicketDetail ticketDetail,
            ILogger logger,
            ITicketDetailStorageProvider ticketDetailStorageProvider,
            string applicationBasePath,
            Dictionary <string, string> cardElementMapping,
            IStringLocalizer <Strings> localizer,
            string teamId,
            MicrosoftAppCredentials microsoftAppCredentials,
            CancellationToken cancellationToken)
        {
            Attachment smeTeamCard = new SmeTicketCard(ticketDetail).GetTicketDetailsForSMEChatCard(cardElementMapping, ticketDetail, applicationBasePath, localizer);
            ConversationResourceResponse resourceResponse = await SendCardToTeamAsync(turnContext, smeTeamCard, teamId, microsoftAppCredentials, cancellationToken);

            if (resourceResponse == null)
            {
                logger.LogError("Error while sending card to team.");
                return(null);
            }

            // Update SME team conversation details in storage.
            ticketDetail.SmeTicketActivityId = resourceResponse.ActivityId;
            ticketDetail.SmeConversationId   = resourceResponse.Id;
            bool result = await ticketDetailStorageProvider?.UpsertTicketAsync(ticketDetail);

            if (!result)
            {
                logger.LogError("Error while saving SME conversation details in storage.");
            }

            return(resourceResponse);
        }
Beispiel #2
0
        public async Task <HttpResponseMessage> ContactUser()
        {
            const string trustServiceUri = "https://api.skypeforbusiness.com/platformservice/botframework";

            MicrosoftAppCredentials.TrustServiceUrl(trustServiceUri);

            var to        = "sip:[email protected]";
            var connector = new ConnectorClient(new Uri(trustServiceUri));
            List <ChannelAccount> participants = new List <ChannelAccount>();

            participants.Add(new ChannelAccount(to, to));
            ConversationParameters       cpMessage = new ConversationParameters(true, new ChannelAccount("sip:[email protected]", "BotName"), participants, "My Test Conversation");
            ConversationResourceResponse response  = await connector.Conversations.CreateConversationAsync(cpMessage);

            var conversationID         = response.Id;
            var conversationServiceURL = response.ServiceUrl;

            for (int i = 0; i < 10; i++)
            {
                await SendMessage(response.ServiceUrl, $"{i} - The time is {DateTime.UtcNow.ToLongTimeString()}", conversationID);

                System.Threading.Thread.Sleep(1000);
            }

            return(new HttpResponseMessage(HttpStatusCode.OK));
        }
        private async Task MessageReceivedAsync(IDialogContext context, IAwaitable <object> result)//, string platform, string role, string userQuestion)
        {
            var activity = await result as Activity;

            var operatorsAccount = new ChannelAccount("429719242");      //(OperatorsClass.Id, OperatorsClass.Name);
            var userAccount      = new ChannelAccount(activity.From.Id); //("mlh89j6hg7k", "Bot");
            var connector        = new ConnectorClient(new Uri(activity.ServiceUrl));

            if (convId == null)
            {
                try
                {
                    var conversationId =
                        await connector.Conversations.CreateDirectConversationAsync(operatorsAccount, userAccount);

                    convId = conversationId;
                }
                catch
                {
                    throw new InvalidOperationException();
                }
            }

            string textForOperator = "Привет";//$"Площадка: {platform}\nРоль: {role}\nВопрос: {userQuestion}";

            IMessageActivity message = Activity.CreateMessageActivity();

            message.From         = operatorsAccount;
            message.Recipient    = userAccount;
            message.Conversation = new ConversationAccount(id: convId.Id);
            message.Text         = textForOperator;
            await connector.Conversations.SendToConversationAsync((Activity)message);

            context.Wait(MessageReceivedAsync);
        }
Beispiel #4
0
        public void ConversationResourceResponseInitsWithNoArgs()
        {
            var convoResourceResponse = new ConversationResourceResponse();

            Assert.NotNull(convoResourceResponse);
            Assert.IsType <ConversationResourceResponse>(convoResourceResponse);
        }
Beispiel #5
0
        /// <summary>
        /// Tries to establish 1:1 chat between the two given parties.
        /// Note that the conversation owner will have a new separate party in the created engagement.
        /// </summary>
        /// <param name="conversationOwnerParty">The party who owns the conversation (e.g. customer service agent).</param>
        /// <param name="conversationClientParty">The other party in the conversation.</param>
        /// <returns>The result of the operation.</returns>
        public async Task <MessageRouterResult> AddEngagementAsync(
            Party conversationOwnerParty, Party conversationClientParty)
        {
            if (conversationOwnerParty == null || conversationClientParty == null)
            {
                throw new ArgumentNullException(
                          $"Neither of the arguments ({nameof(conversationOwnerParty)}, {nameof(conversationClientParty)}) can be null");
            }

            MessageRouterResult result = new MessageRouterResult()
            {
                ConversationOwnerParty  = conversationOwnerParty,
                ConversationClientParty = conversationClientParty
            };

            Party botParty = RoutingDataManager.FindBotPartyByChannelAndConversation(
                conversationOwnerParty.ChannelId, conversationOwnerParty.ConversationAccount);

            if (botParty != null)
            {
                ConnectorClient connectorClient = new ConnectorClient(new Uri(conversationOwnerParty.ServiceUrl));

                ConversationResourceResponse response =
                    await connectorClient.Conversations.CreateDirectConversationAsync(
                        botParty.ChannelAccount, conversationOwnerParty.ChannelAccount);

                if (response != null && !string.IsNullOrEmpty(response.Id))
                {
                    // The conversation account of the conversation owner for this 1:1 chat is different -
                    // thus, we need to create a new party instance
                    ConversationAccount directConversationAccount = new ConversationAccount(id: response.Id);

                    Party acceptorPartyEngaged = new Party(
                        conversationOwnerParty.ServiceUrl, conversationOwnerParty.ChannelId,
                        conversationOwnerParty.ChannelAccount, directConversationAccount);

                    RoutingDataManager.AddParty(acceptorPartyEngaged);
                    RoutingDataManager.AddParty(
                        new Party(botParty.ServiceUrl, botParty.ChannelId, botParty.ChannelAccount, directConversationAccount), false);

                    result = RoutingDataManager.AddEngagementAndClearPendingRequest(acceptorPartyEngaged, conversationClientParty);
                    result.ConversationResourceResponse = response;
                }
                else
                {
                    result.Type         = MessageRouterResultType.Error;
                    result.ErrorMessage = "Failed to create a direct conversation";
                }
            }
            else
            {
                result.Type         = MessageRouterResultType.Error;
                result.ErrorMessage = "Failed to find the bot instance";
            }

            await HandleAndLogMessageRouterResultAsync(result);

            return(result);
        }
        protected override Task <ConversationResourceResponse> OnCreateConversationAsync(ClaimsIdentity claimsIdentity, ConversationParameters parameters, CancellationToken cancellationToken = default)
        {
            this._logger.LogWarning($"attempt to invoke {nameof(OnDeleteActivityAsync)} method, but this method is not implemented");
            var resp = new ConversationResourceResponse {
            };

            return(Task.FromResult(resp));
        }
        private async Task <ConversationReference> UpdateConversation(ConversationResourceResponse response, string userId)
        {
            var oldCon = ConversationReferences.GetValueOrDefault(userId);

            oldCon.Conversation.Id = response.Id;
            oldCon.ActivityId      = response.ActivityId;
            return(oldCon);
        }
Beispiel #8
0
        static void StartNewConversation(ConversationReference convRef, IConversations conversations)
        {
            ConversationResourceResponse convResponse =
                conversations.CreateDirectConversation(convRef.Bot, convRef.User);

            var notificationMessage = convRef.GetPostToUserMessage();

            notificationMessage.Text =
                $"Hi, I haven't heard from you in a while. Want to play?";
            notificationMessage.Conversation = new ConversationAccount(id: convResponse.Id);

            conversations.SendToConversation(notificationMessage);
        }
Beispiel #9
0
        public async Task Do(LoggerBotContext context)
        {
            var userId     = context.Activity.From.Id;
            var serviceUrl = context.Activity.ServiceUrl;
            var botId      = "28:" + LoggerBot.MicrosoftAppCredentials.MicrosoftAppId;
            var botName    = "PlaceholderName";

            var connectorClient = new ConnectorClient(
                baseUri: new Uri(serviceUrl),
                microsoftAppId: LoggerBot.MicrosoftAppCredentials.MicrosoftAppId,
                microsoftAppPassword: LoggerBot.MicrosoftAppCredentials.MicrosoftAppPassword);

            dynamic channelDataNew = new ExpandoObject();
            dynamic tenantObj      = new ExpandoObject();

            tenantObj.id          = "72f988bf-86f1-41af-91ab-2d7cd011db47";
            channelDataNew.tenant = tenantObj;

            var parameters = new ConversationParameters
            {
                Bot         = new ChannelAccount(botId, botName),
                Members     = new ChannelAccount[] { new ChannelAccount(userId) },
                ChannelData = channelDataNew,
            };

            ConversationResourceResponse conversationResource = await connectorClient.Conversations.CreateConversationAsync(parameters);

            if (conversationResource != null)
            {
                var createdActivity = new Activity
                {
                    From         = new ChannelAccount(userId),
                    Recipient    = new ChannelAccount(botId, botName),
                    Conversation = new ConversationAccount(
                        id: conversationResource.Id,
                        isGroup: false,
                        name: "PlaceholderName"),
                    ChannelId  = "msteams",
                    ServiceUrl = serviceUrl,
                };

                ConversationReference conversationReference = TurnContext.GetConversationReference(createdActivity);
                await context.Adapter.ContinueConversation(
                    LoggerBot.MicrosoftAppCredentials.MicrosoftAppId,
                    conversationReference,
                    async (ctx) =>
                {
                    await ctx.SendActivity("Proactive Message");
                });
            }
        }
Beispiel #10
0
        public void ConversationResourceResponseInits()
        {
            var activityId = "activityId";
            var serviceUrl = "http://MyServiceUrl.com";
            var id         = "myId";

            var convoResourceResponse = new ConversationResourceResponse(activityId, serviceUrl, id);

            Assert.NotNull(convoResourceResponse);
            Assert.IsType <ConversationResourceResponse>(convoResourceResponse);
            Assert.Equal(activityId, convoResourceResponse.ActivityId);
            Assert.Equal(serviceUrl, convoResourceResponse.ServiceUrl);
            Assert.Equal(id, convoResourceResponse.Id);
        }
        private Activity CreateCreateActivity(ConversationResourceResponse createConversationResult, string channelId, string serviceUrl, ConversationParameters conversationParameters)
        {
            // Create a conversation update activity to represent the result.
            var activity = Activity.CreateEventActivity();

            activity.Name         = ActivityEventNames.CreateConversation;
            activity.ChannelId    = channelId;
            activity.ServiceUrl   = serviceUrl;
            activity.Id           = createConversationResult.ActivityId ?? Guid.NewGuid().ToString("n");
            activity.Conversation = new ConversationAccount(id: createConversationResult.Id, tenantId: conversationParameters.TenantId);
            activity.ChannelData  = conversationParameters.ChannelData;
            activity.Recipient    = conversationParameters.Bot;
            return((Activity)activity);
        }
Beispiel #12
0
        public void ConnectorExtensions_Create1on1()
        {
            JsonSerializerSettings serializerSettings = new JsonSerializerSettings();

            serializerSettings.NullValueHandling = NullValueHandling.Ignore;

            var botAccount = new ChannelAccount
            {
                Id   = "BotId",
                Name = "BotName"
            };

            var userAccount = new ChannelAccount
            {
                Id   = "UserId",
                Name = "UserName"
            };

            TestDelegatingHandler testDelegatingHandler = new TestDelegatingHandler((request) =>
            {
                string data = (request.Content as StringContent).ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
                ConversationParameters receivedRequest = JsonConvert.DeserializeObject <ConversationParameters>(data, serializerSettings);

                Assert.AreEqual(receivedRequest.Bot.Id, botAccount.Id);
                Assert.IsNotNull(receivedRequest.Members);
                Assert.IsTrue(receivedRequest.Members.Count == 1);
                Assert.AreEqual(receivedRequest.Members[0].Id, userAccount.Id);

                TeamsChannelData channelData = JsonConvert.DeserializeObject <TeamsChannelData>(receivedRequest.ChannelData.ToString());

                Assert.IsNotNull(channelData);
                Assert.IsNotNull(channelData.Tenant);
                Assert.IsNotNull(channelData.Tenant.Id);
                Assert.AreEqual(channelData.Tenant.Id, "TestTenantId");

                ConversationResourceResponse resourceResponse = new ConversationResourceResponse()
                {
                    Id = "TestId"
                };
                StringContent responseContent = new StringContent(JsonConvert.SerializeObject(resourceResponse));
                var response     = new HttpResponseMessage(HttpStatusCode.OK);
                response.Content = responseContent;
                return(Task.FromResult(response));
            });

            ConnectorClient conClient = new ConnectorClient(new Uri("https://testservice.com"), "Test", "Test", testDelegatingHandler);

            Assert.IsTrue(conClient.Conversations.CreateOrGetDirectConversation(botAccount, userAccount, "TestTenantId").Id == "TestId");
        }
        public async Task <ConversationResourceResponse> CreateAndSendChannelMessage(string channelId, Activity activity)
        {
            ConversationParameters conParams = new ConversationParameters
            {
                ChannelData = new TeamsChannelData
                {
                    Channel = new ChannelInfo(channelId)
                },
                Activity = activity
            };

            ConversationResourceResponse response = await this.conClient.Conversations.CreateConversationAsync(conParams);

            return(response);
        }
Beispiel #14
0
        static void StartNewConversation(ConversationParameters convParams, IConversations conversations)
        {
            ConversationResourceResponse convResponse =
                conversations.CreateDirectConversation(convParams.Chatbot, convParams.User);
            var convAccount = new ConversationAccount(id: convResponse.Id);

            var notificationMessage = new Activity
            {
                Type         = ActivityTypes.Message,
                Conversation = convAccount,
                From         = convParams.Chatbot,
                Recipient    = convParams.User,
                Text         = $"Hi, Someone would like to schedule a meeting."
            };

            conversations.SendToConversation(notificationMessage);
        }
        protected override async Task OnMessageActivityAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            string        tenantId      = turnContext.Activity.ChannelData.tenant.id;
            var           channelId     = turnContext.Activity.TeamsGetChannelId();
            MessageSender messageSender = new MessageSender(turnContext.Activity.ServiceUrl, _id, _password);

            turnContext.Activity.RemoveRecipientMention();

            switch (turnContext.Activity.Text)
            {
            case "personal":
                ConversationResourceResponse oneToOne = await messageSender.CreateOneToOneConversation(turnContext.Activity.From.Id, tenantId);

                await turnContext.SendActivityAsync(MessageFactory.Text($"The conversation Id is {oneToOne.Id}"));

                ResourceResponse oneToOneMessageResponse = await messageSender.SendOneToOneMessage(oneToOne.Id, MessageFactory.Text("Hi from Proactive Messaging bot."));

                await turnContext.SendActivityAsync(MessageFactory.Text($"The message Id is {oneToOneMessageResponse.Id}"));

                break;

            case "channel" when turnContext.Activity.Conversation.ConversationType.Equals("channel"):
                ConversationResourceResponse channelThread = await messageSender.CreateAndSendChannelMessage(channelId, MessageFactory.Text("This is a new conversation thread"));

                await turnContext.SendActivityAsync(MessageFactory.Text($"The thread Id is {channelThread.Id}"));

                ResourceResponse replyResponse = await messageSender.SendReplyToConversationThread(channelThread.Id, MessageFactory.Text("This is a reply"));

                ResourceResponse secondReplyResponse = await messageSender.SendReplyToConversationThread(channelThread.Id, MessageFactory.Text("This is the second reply"));

                break;

            case "channel":
                await turnContext.SendActivityAsync(MessageFactory.Text("This function only works from a channel."));

                break;

            default:
                await turnContext.SendActivityAsync(MessageFactory.Text("Type 'personal' or 'channel' for a proactive message."));

                break;
            }
        }
Beispiel #16
0
        public async Task <Result <System.Dynamic.ExpandoObject> > CheckSentences(Activity activity)
        {
            var wordsEntity = await wordCache.GetAsync();

            var words = wordsEntity.Select(x => x.Word);
            // Get the conversation id so the bot answers.
            var conversationId = activity.From.Id.ToString();

            // Get a valid token
            string token = await this.GetBotApiToken();

            dynamic message = new ExpandoObject();

            // send the message back
            using (var client = new System.Net.Http.HttpClient())
            {
                // I'm using dynamic here to make the code simpler
                message.type = "message/text";
                message.text = "TEST TEST TEST";
                var    senderEmail    = Environment.GetEnvironmentVariable("BOBTHEBOT_SENDER_EMAIL");
                var    senderName     = Environment.GetEnvironmentVariable("BOBTHEBOT_SENDER_NAME");
                var    recipientEmail = Environment.GetEnvironmentVariable("BOBTHEBOT_RECIPIENT_EMAIL");
                var    recipientName  = Environment.GetEnvironmentVariable("BOBTHEBOT_RECIPIENT_NAME");
                string messages       = activity.Text.ToString();
                string from           = activity.From.Name.ToString();
                string conv           = activity.Conversation.Id;
                var    group          = conv.Split("|").Last().Split("\"").First();
                if (words.Any(c => messages.ToLower().Contains(c.ToLower())))
                {
                    //var msg = MailHelper.CreateSingleEmail(
                    //    new EmailAddress(senderEmail, senderName),
                    //    new EmailAddress("*****@*****.**", recipientName),
                    //    "Subject",
                    //    "",
                    //    messages + " from " + from + " at " + group);

                    //var response2 = await sendGridClient.SendEmailAsync(msg);

                    // Set the toekn in the authorization header.
                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

                    var appCredentials = new MicrosoftAppCredentials(configurationRoot);
                    var connector      = new ConnectorClient(new Uri(activity.ServiceUrl), appCredentials);
                    // var asd = await connector.Conversations.GetConversationMembersAsync(qwe);

                    //var newActovity = new Activity(id: "2cb6eb60-761b-11e8-b7ed-f79c3f4b062e",
                    //    serviceUrl:activity.ServiceUrl,
                    //    replyToId: "9aec9e40-7611-11e8-b7ed-f79c3f4b062e",
                    //    type:"text",
                    //    textFormat:"plain",
                    //    channelId:"emulator",
                    //    channelData: "9aec9e40-7611-11e8-b7ed-f79c3f4b062e");

                    //var qwfsv = activity.Recipient;
                    //activity.Recipient.Name = "Bot";
                    //activity.Recipient.Id = "bea98650-748a-11e8-a3ac-fb4c46d160e7";

                    var length = (activity.Text ?? string.Empty).Length;
                    var reply  = activity.CreateReply($"You send {activity.Text} which was{length} characters!");
                    //var asd = new Activity(ChannelAccount(r reply.Recipient.Id == "bea98650-748a-11e8-a3ac-fb4c46d160e7";
                    // var asd = new Activity()
                    await connector.Conversations.ReplyToActivityAsync(reply);

                    //var asd = await connector.Conversations.CreateConversationAsync(new ConversationParameters());
                    //await client.PostAsJsonAsync(
                    //"http://*****:*****@contoso.com", "Agent"));
                    ConversationParameters       parameters = new ConversationParameters(true, new ChannelAccount("sip:[email protected]", "Bot"), participants, "TestTopic");
                    ConversationResourceResponse response   = connector.Conversations.CreateConversationAsync(parameters).Result;

                    // await client.PostAsJsonAsync<ExpandoObject>(
                    //$"https://api.skype.net/v3/conversations/{conversationId}/activities",
                    //message as ExpandoObject);
                }
            }

            return(Result.Ok(message));
        }
Beispiel #17
0
        /// <summary>
        /// Tries to establish a connection (1:1 chat) between the two given parties.
        ///
        /// Note that the conversation owner will have a new separate conversation reference in the created
        /// conversation, if a new direct conversation is created.
        /// </summary>
        /// <param name="conversationReference1">The conversation reference who owns the conversation (e.g. customer service agent).</param>
        /// <param name="conversationReference2">The other conversation reference in the conversation.</param>
        /// <param name="createNewDirectConversation">
        /// If true, will try to create a new direct conversation between the bot and the
        /// conversation owner (e.g. agent) where the messages from the other (client) conversation
        /// reference are routed.
        ///
        /// Note that this will result in the conversation owner having a new separate conversation
        /// reference in the created connection (for the new direct conversation).
        /// </param>
        /// <returns>
        /// The result of the operation:
        /// - ConnectionResultType.Connected,
        /// - ConnectionResultType.Error (see the error message for more details).
        /// </returns>
        public virtual async Task <ConnectionResult> ConnectAsync(
            ConversationReference conversationReference1,
            ConversationReference conversationReference2,
            bool createNewDirectConversation)
        {
            if (conversationReference1 == null || conversationReference2 == null)
            {
                throw new ArgumentNullException(
                          $"Neither of the arguments ({nameof(conversationReference1)}, {nameof(conversationReference2)}) can be null");
            }

            ConversationReference botInstance =
                RoutingDataManager.FindConversationReference(
                    conversationReference1.ChannelId, conversationReference1.Conversation.Id, null, true);

            if (botInstance == null)
            {
                return(new ConnectionResult()
                {
                    Type = ConnectionResultType.Error,
                    ErrorMessage = "Failed to find the bot instance"
                });
            }

            ConversationResourceResponse conversationResourceResponse = null;

            if (createNewDirectConversation)
            {
                ChannelAccount conversationReference1ChannelAccount =
                    RoutingDataManager.GetChannelAccount(
                        conversationReference1, out bool conversationReference1IsBot);

                ConnectorClient connectorClient = new ConnectorClient(
                    new Uri(conversationReference1.ServiceUrl), _microsoftAppCredentials);

                try
                {
                    conversationResourceResponse =
                        await connectorClient.Conversations.CreateDirectConversationAsync(
                            botInstance.Bot, conversationReference1ChannelAccount);
                }
                catch (Exception e)
                {
                    Logger.Log($"Failed to create a direct conversation: {e.Message}");
                    // Do nothing here as we fallback (continue without creating a direct conversation)
                }

                if (conversationResourceResponse != null &&
                    !string.IsNullOrEmpty(conversationResourceResponse.Id))
                {
                    // The conversation account of the conversation owner for this 1:1 chat is different -
                    // thus, we need to re-create the conversation owner instance
                    ConversationAccount directConversationAccount =
                        new ConversationAccount(id: conversationResourceResponse.Id);


                    conversationReference1 = new ConversationReference(
                        null,
                        conversationReference1IsBot ? null : conversationReference1ChannelAccount,
                        conversationReference1IsBot ? conversationReference1ChannelAccount : null,
                        directConversationAccount,
                        conversationReference1.ChannelId,
                        conversationReference1.ServiceUrl);

                    RoutingDataManager.AddConversationReference(conversationReference1);

                    RoutingDataManager.AddConversationReference(new ConversationReference(
                                                                    null,
                                                                    null,
                                                                    botInstance.Bot,
                                                                    directConversationAccount,
                                                                    botInstance.ChannelId,
                                                                    botInstance.ServiceUrl));
                }
            }

            Connection       connection    = new Connection(conversationReference1, conversationReference2);
            ConnectionResult connectResult =
                RoutingDataManager.ConnectAndRemoveConnectionRequest(connection, conversationReference2);

            connectResult.ConversationResourceResponse = conversationResourceResponse;

            return(connectResult);
        }
        /// <summary>
        /// Tries to establish 1:1 chat between the two given parties.
        /// Note that the conversation owner will have a new separate party in the created engagement.
        /// </summary>
        /// <param name="conversationOwnerParty">The party who owns the conversation (e.g. customer service agent).</param>
        /// <param name="conversationClientParty">The other party in the conversation.</param>
        /// <returns>The result of the operation.</returns>
        public async Task <MessageRouterResult> AddEngagementAsync(
            Party conversationOwnerParty, Party conversationClientParty)
        {
            if (conversationOwnerParty == null || conversationClientParty == null)
            {
                throw new ArgumentNullException(
                          $"Neither of the arguments ({nameof(conversationOwnerParty)}, {nameof(conversationClientParty)}) can be null");
            }

            MessageRouterResult result = new MessageRouterResult()
            {
                ConversationOwnerParty  = conversationOwnerParty,
                ConversationClientParty = conversationClientParty
            };

            Party botParty = RoutingDataManager.FindBotPartyByChannelAndConversation(
                conversationOwnerParty.ChannelId, conversationOwnerParty.ConversationAccount);

            if (botParty != null)
            {
                ConnectorClient connectorClient = new ConnectorClient(new Uri(conversationOwnerParty.ServiceUrl));

                try
                {
                    ConversationResourceResponse response =
                        await connectorClient.Conversations.CreateDirectConversationAsync(
                            botParty.ChannelAccount, conversationOwnerParty.ChannelAccount);

                    // ResponseId and conversationOwnerParty.ConversationAccount.Id are not consistent
                    // with each other across channels. Here we need the ConversationAccountId to route
                    // messages correctly across channels, e.g.:
                    // * In Slack they are the same:
                    //      * response.Id: B6JJQ7939: T6HKNHCP7: D6H04L58R
                    //      * conversationOwnerParty.ConversationAccount.Id: B6JJQ7939: T6HKNHCP7: D6H04L58R
                    // * In Skype they are not:
                    //      * response.Id: 8:daltskin
                    //      * conversationOwnerParty.ConversationAccount.Id: 29:11MZyI5R2Eak3t7bFjDwXmjQYnSl7aTBEB8zaSMDIEpA
                    if (response != null && !string.IsNullOrEmpty(conversationOwnerParty.ConversationAccount.Id))
                    {
                        // The conversation account of the conversation owner for this 1:1 chat is different -
                        // thus, we need to create a new party instance
                        ConversationAccount directConversationAccount =
                            new ConversationAccount(id: conversationOwnerParty.ConversationAccount.Id);

                        Party acceptorPartyEngaged = new EngageableParty(
                            conversationOwnerParty.ServiceUrl, conversationOwnerParty.ChannelId,
                            conversationOwnerParty.ChannelAccount, directConversationAccount);

                        RoutingDataManager.AddParty(acceptorPartyEngaged);
                        RoutingDataManager.AddParty(
                            new EngageableParty(botParty.ServiceUrl, botParty.ChannelId, botParty.ChannelAccount, directConversationAccount), false);

                        result = RoutingDataManager.AddEngagementAndClearPendingRequest(acceptorPartyEngaged, conversationClientParty);
                        result.ConversationResourceResponse = response;
                    }
                    else
                    {
                        result.Type         = MessageRouterResultType.Error;
                        result.ErrorMessage = "Failed to create a direct conversation";
                    }
                }
                catch (Exception e)
                {
                    result.Type         = MessageRouterResultType.Error;
                    result.ErrorMessage = $"Failed to create a direct conversation: {e.Message}";
                }
            }
            else
            {
                result.Type         = MessageRouterResultType.Error;
                result.ErrorMessage = "Failed to find the bot instance";
            }

            return(result);
        }
Beispiel #19
0
        // Forward message to Slack
        private async Task <bool> SendTeamsMessageAsync(User recipient, object messageContent)
        {
            if (recipient == null || messageContent == null)
            {
                return(false);
            }

            var isSuccess = false;

            try
            {
                var toId        = recipient.Id;
                var toName      = recipient.Name;
                var fromId      = recipient.BotId;
                var fromName    = recipient.BotName;
                var serviceUrl  = recipient.ServiceUrl;
                var tenantId    = recipient.TenantId; // Required for Microsoft Teams
                var userAccount = new ChannelAccount(toId, toName);
                var botAccount  = new ChannelAccount(fromId, fromName);

                var attachment = new Attachment
                {
                    ContentType = "application/vnd.microsoft.card.adaptive",
                    Content     = messageContent,
                };

                var message = Activity.CreateMessageActivity();
                message.From        = botAccount;
                message.Recipient   = userAccount;
                message.Attachments = new List <Attachment>()
                {
                    attachment
                };

                MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);
                var account = new MicrosoftAppCredentials(_appId, _password);
                var client  = new ConnectorClient(new Uri(serviceUrl), account);

                // Reuse existing conversation if recipient is a channel
                string conversationId;
                ConversationResourceResponse conversation = null;
                if (recipient.IsGroupChannel)
                {
                    var conversationParameters = new ConversationParameters
                    {
                        IsGroup     = true,
                        ChannelData = new TeamsChannelData
                        {
                            Channel = new ChannelInfo(recipient.Id),
                        },
                        Activity = (Activity)message,
                    };
                    conversation = await client.Conversations.CreateConversationAsync(conversationParameters);
                }
                else
                {
                    conversation         = client.Conversations.CreateOrGetDirectConversation(botAccount, userAccount, tenantId);
                    conversationId       = conversation.Id;
                    message.Conversation = new ConversationAccount(id: conversationId);
                    var response = await client.Conversations.SendToConversationAsync((Activity)message);

                    _logger.LogInformation($"Response id: {response.Id}");
                }

                isSuccess = true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message);
            }

            return(isSuccess);
        }
Beispiel #20
0
        /// <summary>
        /// Tries to establish 1:1 chat between the two given parties.
        ///
        /// Note that the conversation owner will have a new separate party in the created
        /// conversation, if a new direct conversation is created.
        /// </summary>
        /// <param name="conversationOwnerParty">The party who owns the conversation (e.g. customer service agent).</param>
        /// <param name="conversationClientParty">The other party in the conversation.</param>
        /// <param name="createNewDirectConversation">If true, will try to create a new direct conversation between
        /// the bot and the conversation owner (e.g. agent) where the messages from the other (client) party are routed.
        /// Note that this will result in the conversation owner having a new separate party in the created connection
        /// (for the new direct conversation).</param>
        /// <returns>
        /// The result of the operation:
        /// - MessageRouterResultType.Connected, if successfully connected OR
        /// - MessageRouterResultType.Error in case of an error (see the error message).
        ///
        /// The result will also contain the connected parties and note that the client's identity
        /// will have changed, if a new direct conversation was created!
        /// </returns>
        public virtual async Task <MessageRouterResult> ConnectAsync(
            Party conversationOwnerParty, Party conversationClientParty, bool createNewDirectConversation)
        {
            if (conversationOwnerParty == null || conversationClientParty == null)
            {
                throw new ArgumentNullException(
                          $"Neither of the arguments ({nameof(conversationOwnerParty)}, {nameof(conversationClientParty)}) can be null");
            }

            MessageRouterResult result = new MessageRouterResult()
            {
                ConversationOwnerParty  = conversationOwnerParty,
                ConversationClientParty = conversationClientParty
            };

            Party botParty = RoutingDataManager.FindBotPartyByChannelAndConversation(
                conversationOwnerParty.ChannelId, conversationOwnerParty.ConversationAccount);

            if (botParty != null)
            {
                if (createNewDirectConversation)
                {
                    ConnectorClient connectorClient = new ConnectorClient(new Uri(conversationOwnerParty.ServiceUrl));
                    ConversationResourceResponse conversationResourceResponse = null;

                    try
                    {
                        conversationResourceResponse =
                            await connectorClient.Conversations.CreateDirectConversationAsync(
                                botParty.ChannelAccount, conversationOwnerParty.ChannelAccount);
                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Debug.WriteLine($"Failed to create a direct conversation: {e.Message}");
                        // Do nothing here as we fallback (continue without creating a direct conversation)
                    }

                    if (conversationResourceResponse != null && !string.IsNullOrEmpty(conversationResourceResponse.Id))
                    {
                        // The conversation account of the conversation owner for this 1:1 chat is different -
                        // thus, we need to re-create the conversation owner instance
                        ConversationAccount directConversationAccount =
                            new ConversationAccount(id: conversationResourceResponse.Id);

                        conversationOwnerParty = new Party(
                            conversationOwnerParty.ServiceUrl, conversationOwnerParty.ChannelId,
                            conversationOwnerParty.ChannelAccount, directConversationAccount);

                        RoutingDataManager.AddParty(conversationOwnerParty);
                        RoutingDataManager.AddParty(new Party(
                                                        botParty.ServiceUrl, botParty.ChannelId, botParty.ChannelAccount, directConversationAccount), false);

                        result.ConversationResourceResponse = conversationResourceResponse;
                    }
                }

                result = RoutingDataManager.ConnectAndClearPendingRequest(conversationOwnerParty, conversationClientParty);
            }
            else
            {
                result.Type         = MessageRouterResultType.Error;
                result.ErrorMessage = "Failed to find the bot instance";
            }

            return(result);
        }
Beispiel #21
0
        public async Task CloudAdapterCreateConversation()
        {
            // Arrange
            var claimsIdentity = new ClaimsIdentity();

            var authenticateRequestResult = new AuthenticateRequestResult
            {
                ClaimsIdentity   = claimsIdentity,
                ConnectorFactory = new TestConnectorFactory(),
                Audience         = "audience",
                CallerId         = "callerId"
            };

            var userTokenClient = new TestUserTokenClient("appId");

            var conversationResourceResponse = new ConversationResourceResponse();
            var createResponse = new HttpOperationResponse <ConversationResourceResponse> {
                Body = conversationResourceResponse
            };

            // note Moq doesn't support extension methods used in the implementation so we are actually mocking the underlying CreateConversationWithHttpMessagesAsync method
            var conversationsMock = new Mock <IConversations>();

            conversationsMock.Setup(cm => cm.CreateConversationWithHttpMessagesAsync(It.IsAny <ConversationParameters>(), It.IsAny <Dictionary <string, List <string> > >(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(createResponse));

            var connectorMock = new Mock <IConnectorClient>();

            connectorMock.SetupGet(m => m.Conversations).Returns(conversationsMock.Object);

            var expectedServiceUrl = "http://serviceUrl";
            var expectedAudience   = "audience";

            var connectorFactoryMock = new Mock <ConnectorFactory>();

            connectorFactoryMock.Setup(cf => cf.CreateAsync(It.Is <string>(serviceUrl => serviceUrl == expectedServiceUrl), It.Is <string>(audience => audience == expectedAudience), It.IsAny <CancellationToken>())).Returns(Task.FromResult(connectorMock.Object));

            var cloudEnvironmentMock = new Mock <BotFrameworkAuthentication>();

            cloudEnvironmentMock.Setup(ce => ce.AuthenticateRequestAsync(It.IsAny <Activity>(), It.IsAny <string>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(authenticateRequestResult));
            cloudEnvironmentMock.Setup(ce => ce.CreateConnectorFactory(It.IsAny <ClaimsIdentity>())).Returns(connectorFactoryMock.Object);
            cloudEnvironmentMock.Setup(ce => ce.CreateUserTokenClientAsync(It.IsAny <ClaimsIdentity>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult <UserTokenClient>(userTokenClient));

            var expectedChannelId = "expected-channel-id";
            var actualChannelId   = string.Empty;

            BotCallbackHandler callback1 = (t, c) =>
            {
                actualChannelId = t.Activity.ChannelId;

                return(Task.CompletedTask);
            };

            var conversationParameters = new ConversationParameters
            {
                IsGroup  = false,
                Bot      = new ChannelAccount {
                },
                Members  = new ChannelAccount[] { },
                TenantId = "tenantId",
            };

            // Act
            var adapter = new CloudAdapter(cloudEnvironmentMock.Object);
            await adapter.CreateConversationAsync("botAppId", expectedChannelId, expectedServiceUrl, expectedAudience, conversationParameters, callback1, CancellationToken.None);

            // Assert
            Assert.Equal(expectedChannelId, actualChannelId);
        }
Beispiel #22
0
        //---------------------------------------------УЧАСТОК КОДА С ПЕРЕНАПРАВЛЕНИЕМ СООБЩЕНИЙ ОПЕРАТОРУ-------------------------------------

        public async Task ToOperator(IDialogContext context, Activity activity)
        {
            try
            {
                _operatorsConversation = true;

                string operatorId = "429719242";
                bool   toOperator = true;

                if (activity.From.Id == operatorId)
                {
                    toOperator = false;

                    if (String.IsNullOrEmpty(_userId))
                    {
                        await context.PostAsync("Ни одного пользователя не подключено к оператору");

                        return;
                    }
                }
                else
                {
                    _userId = activity.From.Id;
                }

                var serverAccount   = new ChannelAccount(activity.Recipient.Id, activity.Recipient.Name);
                var operatorAccount = new ChannelAccount(operatorId);
                var userAccount     = new ChannelAccount(_userId);

                var connector = new ConnectorClient(new Uri(activity.ServiceUrl));

                if (toOperator)
                {
                    var conversationId =
                        connector.Conversations.CreateDirectConversation(serverAccount, operatorAccount);
                    convId = conversationId;
                }
                else
                {
                    var conversationId =
                        connector.Conversations.CreateDirectConversation(serverAccount, userAccount);
                    convId = conversationId;
                }

                string textForOperator = $"Площадка: {_platform}\n\nРоль: {_role}\n\nСообщение: {activity.Text}";

                IMessageActivity message = Activity.CreateMessageActivity();

                message.From = serverAccount;

                if (toOperator)
                {
                    message.Recipient = operatorAccount;
                    message.Text      = textForOperator;
                }
                else
                {
                    message.Recipient = userAccount;
                    message.Text      = activity.Text;
                }

                message.Conversation = new ConversationAccount(id: convId.Id);

                await connector.Conversations.SendToConversationAsync((Activity)message);
            }
            catch
            {
                await context.PostAsync("Что-то пошло не так");
            }
            context.Wait(MessageReceivedAsync);
        }