/// <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); }
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); }
public void ConversationResourceResponseInitsWithNoArgs() { var convoResourceResponse = new ConversationResourceResponse(); Assert.NotNull(convoResourceResponse); Assert.IsType <ConversationResourceResponse>(convoResourceResponse); }
/// <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); }
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); }
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"); }); } }
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); }
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); }
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; } }
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)); }
/// <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); }
// 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); }
/// <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); }
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); }
//---------------------------------------------УЧАСТОК КОДА С ПЕРЕНАПРАВЛЕНИЕМ СООБЩЕНИЙ ОПЕРАТОРУ------------------------------------- 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); }