private static async Task <BotConversation> GetConversationByUserId(string userId) { // TODO: extract this and inject an instance of IBotConversationProvider await DocumentClient.GetDocumentCollectionAsync(); BotConversation conversation = await DocumentClient.GetItemAsync <BotConversation>(c => c.UserId == userId); return(conversation); }
private static async Task PostToConversation(IncomingSms incomingSms, BotConversation conversation, ILogger log) { log.LogInformation($"Posting message to conversationId {conversation.ConversationId}"); dynamic from = new ExpandoObject(); from.id = incomingSms.SourceNumber; from.name = incomingSms.SourceNumber; from.role = null; dynamic channelData = new ExpandoObject(); channelData.UniqueLearnerNumber = conversation.UniqueLearnerNumber; channelData.StandardCode = conversation.StandardCode; channelData.ApprenticeshipStartDate = conversation.ApprenticeshipStartDate; channelData.NotifyMessage = new NotifyMessage { Id = incomingSms.Id, DateReceived = incomingSms.DateReceived.ToString(CultureInfo.InvariantCulture), DestinationNumber = incomingSms.DestinationNumber, SourceNumber = incomingSms.SourceNumber, Message = incomingSms.Message, Type = "callback", }; var messageContent = new BotConversationMessage { Type = "message", From = from, Text = incomingSms.Message, ChannelData = channelData }; var json = JsonConvert.SerializeObject(messageContent); HttpContent content = new StringContent(json); content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); HttpResponseMessage postMessageTask = await DirectLineClient.PostAsync($"/v3/directline/conversations/{conversation.ConversationId}/activities", content); if (postMessageTask.IsSuccessStatusCode) { string response = await postMessageTask.Content.ReadAsStringAsync(); dynamic jsonResponse = JsonConvert.DeserializeObject(response); log.LogInformation($"Received response from Bot Client: {jsonResponse.id}"); } else { var message = $"Could not post conversation to DirectLineClient. {postMessageTask.StatusCode}: {postMessageTask.ReasonPhrase}"; throw new BotConnectorException(message); } }
private static async Task StartNewConversation(IncomingSms incomingSms, ILogger log) { log.LogInformation($"Starting new conversation with {incomingSms.SourceNumber}"); var content = new StringContent(string.Empty); var startConversationTask = await DirectLineClient.PostAsync("/v3/directline/conversations", content); var conversation = new BotConversation(); if (startConversationTask.IsSuccessStatusCode) { string response = await startConversationTask.Content.ReadAsStringAsync(); dynamic jsonResponse = JsonConvert.DeserializeObject(response); log.LogInformation($"Started new conversation with id {jsonResponse.conversationId}"); // TODO: write the conversation ID to a session log with the mobile phone number conversation.UserId = incomingSms.SourceNumber; // TODO: [security] hash this please! conversation.ConversationId = jsonResponse.conversationId; conversation.UniqueLearnerNumber = incomingSms.UniqueLearnerNumber; conversation.StandardCode = incomingSms.StandardCode; conversation.ApprenticeshipStartDate = incomingSms.ApprenticeshipStartDate; BotConversation newSession = await DocumentClient.UpsertItemAsync(conversation); if (newSession == null) { var message = $"Could not create session object for conversation id {conversation.ConversationId}"; throw new BotConnectorException(message); } if (incomingSms.Message != null) { await PostToConversation(incomingSms, conversation, log); } } else { var message = $"Could not start new conversation with DirectLineClient. {startConversationTask.StatusCode}: {startConversationTask.ReasonPhrase}"; throw new BotConnectorException(message); } }
public static async Task Run( [ServiceBusTrigger("%IncomingMessageQueueName%", Connection = "ServiceBusConnection")] string queueMessage, [Inject] SettingsProvider configuration, ILogger log, ExecutionContext context) { Configuration = configuration; currentContext = context; IncomingSms incomingSms = JsonConvert.DeserializeObject <IncomingSms>(queueMessage); try { log.LogInformation($"Response received from {incomingSms.SourceNumber}, sending to bot..."); string userId = incomingSms.SourceNumber; // TODO: [security] hash me please! // If we key this on unique survey to user then we can have different conversationId's per survey run for the same number BotConversation conversation = await GetConversationByUserId(userId); if (conversation == null) { await StartNewConversation(incomingSms, log); } else { await PostToConversation(incomingSms, conversation, log); } } catch (MessageLockLostException e) { log.LogError($"DeliverMessageToBot MessageLockLostException [{context.FunctionName}|{context.InvocationId}]", e, e.Message); } catch (Exception e) { log.LogError($"DeliverMessageToBot ERROR: {e.Message}", e, e.Message); DirectLineClient.CancelPendingRequests(); throw new BotConnectorException("Something went wrong when relaying the message to the bot framework", e); } }