/// <inheritdoc /> public override async Task <DialogTurnResult> ExecuteAsync(DialogContext dc, CancellationToken cancellationToken) { string message = dc.Context.Activity.Text.ToLowerInvariant(); var strings = message.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); var mobileNumber = strings[1]; var trigger = new IncomingSms { Id = Guid.NewGuid().ToString(), SourceNumber = mobileNumber, DestinationNumber = null, Message = "bot--dialog--start afb-v6", DateReceived = DateTime.UtcNow, UniqueLearnerNumber = "uln_here", ApprenticeshipStartDate = DateTime.Now.AddYears(-1), StandardCode = 23, }; var queueMessage = new SmsIncomingMessage(trigger); await this.queue.SendAsync(dc.Context.Activity.Conversation.Id, queueMessage, this.notifyConfig.IncomingMessageQueueName); await dc.Context.SendActivityAsync($"OK. Sending survey to {mobileNumber}", cancellationToken : cancellationToken); return(await dc.ContinueDialogAsync(cancellationToken)); }
internal static BotMessage CreateMessage(string phoneNumber, string message) { var sms = new IncomingSms() { DateReceived = DateTime.UtcNow, DestinationNumber = "00000000000", SourceNumber = phoneNumber, Message = message }; var msg = new BotMessage(); dynamic channelData = new ExpandoObject(); channelData.NotifyMessage = sms; dynamic from = new ExpandoObject(); from.Id = sms.SourceNumber; msg.ChannelData = channelData; msg.From = from; return(msg); }
public async Task HandleAsync(TriggerSurveyInvitesCommand command, CancellationToken cancellationToken = default(CancellationToken)) { var batchSize = _settingService.GetInt("ApprenticeBatchSize"); var apprenticeDetails = await _surveyDetailsRepo.GetApprenticeSurveyInvitesAsync(batchSize); foreach (var apprenticeDetail in apprenticeDetails) { var now = DateTime.Now; var trigger = new IncomingSms() { Type = SmsType.SurveyInvitation, Id = Guid.NewGuid().ToString(), SourceNumber = apprenticeDetail.MobileNumber.ToString(), DestinationNumber = null, Message = $"bot--dialog--start {apprenticeDetail.SurveyCode}", DateReceived = now, UniqueLearnerNumber = apprenticeDetail.UniqueLearnerNumber, StandardCode = apprenticeDetail.StandardCode, ApprenticeshipStartDate = apprenticeDetail.ApprenticeshipStartDate }; await _surveyDetailsRepo.SetApprenticeSurveySentAsync(apprenticeDetail.Id); try { var serviceBusMessage = new SmsIncomingMessage(trigger); await _queueClient.SendAsync(serviceBusMessage); } catch (Exception ex) { _logger.LogError($"Failed to put message on the queue for apprentice survey detail id: {apprenticeDetail.Id}. Reverting survey sent status"); await _surveyDetailsRepo.SetApprenticeSurveyNotSentAsync(apprenticeDetail.Id); } } }
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); } }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, [ServiceBus("%IncomingMessageQueueName%", Connection = "ServiceBusConnection", EntityType = Microsoft.Azure.WebJobs.ServiceBus.EntityType.Queue)] IAsyncCollector <IncomingSms> queue, ILogger log, ExecutionContext context) { try { string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); IncomingSms receivedSms = JsonConvert.DeserializeObject <IncomingSms>(requestBody); receivedSms.Type = SmsType.NotifySms; log.LogInformation($"Message received from {receivedSms.SourceNumber}"); if (receivedSms.Message == null || receivedSms.DestinationNumber == null || receivedSms.SourceNumber == null) { return(new BadRequestObjectResult( "Expecting a text message payload. Please see the Notify callback documentation for details: https://www.notifications.service.gov.uk/callbacks")); } await queue.AddAsync(receivedSms); return(new OkObjectResult(receivedSms)); } catch (MessageLockLostException e) { log.LogError($"ReceiveNotifyMessage MessageLockLostException [{context.FunctionName}|{context.InvocationId}]", e, e.Message); return(new ExceptionResult(e, true)); } catch (Exception e) { log.LogError($"ReceiveNotifyMessage ERROR: {e.Message}", e, e.Message); return(new ExceptionResult(e, true)); } }
public SmsIncomingMessage(IncomingSms trigger) : base(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(trigger))) { }