/// <summary>
        /// Accepts an incoming webhook request, creates a turn context,
        /// and runs the middleware pipeline for an incoming TRUSTED activity.
        /// </summary>
        /// <param name="httpRequest">Represents the incoming side of an HTTP request.</param>
        /// <param name="httpResponse">Represents the outgoing side of an HTTP request.</param>
        /// <param name="bot">The code to run at the end of the adapter's middleware pipeline.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        public override async Task ProcessAsync(HttpRequest httpRequest, HttpResponse httpResponse, IBot bot,
                                                CancellationToken cancellationToken = new CancellationToken())
        {
            string stringifiedBody;

            using (var sr = new StreamReader(httpRequest.Body))
            {
                stringifiedBody = await sr.ReadToEndAsync().ConfigureAwait(false);
            }

            if (!_authorizationHelper.VerifySignature(httpRequest.Headers[InfobipConstants.HeaderSignatureKey], stringifiedBody, _whatsAppAdapterOptions.InfobipAppSecret))
            {
                if (_whatsAppAdapterOptions.BypassAuthentication)
                {
                    _logger.LogWarning("WARNING: Bypassing authentication. Do not run this in production.");
                }
                else
                {
                    httpResponse.StatusCode = (int)HttpStatusCode.Unauthorized;
                    _logger.LogWarning("WARNING: Webhook received message with invalid signature. Request stopped and response will have unauthorized status code!");
                    return;
                }
            }

            var incomingMessage = stringifiedBody.FromInfobipIncomingMessageJson <InfobipWhatsAppIncomingResult>();
            var activities      = await _toWhatsAppActivityConverter.Convert(incomingMessage).ConfigureAwait(false);

            foreach (var activity in activities)
            {
                using (var context = new TurnContext(this, activity))
                {
                    await RunPipelineAsync(context, bot.OnTurnAsync, cancellationToken).ConfigureAwait(false);
                }
            }
        }
Beispiel #2
0
        public async Task ConvertWhatsAppTextMessageWithCallbackDataToActivity()
        {
            var incomingMessage = new InfobipIncomingMessage <InfobipWhatsAppIncomingResult>
            {
                Results = new List <InfobipWhatsAppIncomingResult>
                {
                    new InfobipWhatsAppIncomingResult
                    {
                        MessageId       = "Unique message Id",
                        From            = "subscriber-number",
                        To              = "whatsapp-number",
                        ReceivedAt      = DateTimeOffset.UtcNow,
                        IntegrationType = "WHATSAPP",
                        Message         = new InfobipIncomingWhatsAppMessage
                        {
                            Type = InfobipIncomingMessageTypes.Text,
                            Text = "Text message to bot"
                        },
                        Contact = new InfobipIncomingWhatsAppContact
                        {
                            Name = "Whatsapp Subscriber Name"
                        },
                        Price = new InfobipIncomingPrice
                        {
                            PricePerMessage = 0,
                            Currency        = "GBP"
                        },
                        CallbackData = "{\"initialMenu\": true, \"userId\": 1, \"username\":\"newUser\"}"
                    }
                },
                MessageCount        = 1,
                PendingMessageCount = 0
            };

            var activity = (await _toActivityConverter.Convert(incomingMessage).ConfigureAwait(false)).First();

            Assert.NotNull(activity);
            Assert.Equal(InfobipWhatsAppConstants.ChannelName, activity.ChannelId);
            var entity = activity.Entities.Single(x => x.Type == InfobipEntityType.CallbackData);
            var result = entity.Properties.ToDictionary();

            Assert.Equal("true", result["initialMenu"]);
            Assert.Equal("1", result["userId"]);
            Assert.Equal("newUser", result["username"]);
        }