コード例 #1
0
        public async Task Handle(HttpContext context, Func <EventGridEvent, Task> callback)
        {
            string response = string.Empty;

            using var reader = new StreamReader(context.Request.Body);
            var requestContent = await reader.ReadToEndAsync();

            log.LogDebug($"Received events: {requestContent}");

            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            EventGridEvent[] eventGridEvents = JsonConvert.DeserializeObject <EventGridEvent[]>(requestContent);

            var validationEvent = eventGridEvents.FirstOrDefault(e => e.EventType == "Microsoft.EventGrid.SubscriptionValidationEvent");

            if (validationEvent != null)
            {
                await InActivityContext(context, validationEvent, async() =>
                {
                    var result = HandleValidation(validationEvent);

                    context.Response.ContentType = "application/json";
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(result));
                });

                return;
            }

            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                await InActivityContext(context, eventGridEvent, () => callback(eventGridEvent));
            }

            context.Response.StatusCode = 202;
        }
コード例 #2
0
        public IActionResult Post([FromBody] JArray requestJArray)
        {
            var requestContent = requestJArray.ToString();

            _logger.LogInformation($"Received events: {requestContent}");

            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestContent);

            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                if (eventGridEvent.Data is SubscriptionValidationEventData eventData)
                {
                    _logger.LogInformation($"Got SubscriptionValidation event data, validationCode: {eventData.ValidationCode},  validationUrl: {eventData.ValidationUrl}, topic: {eventGridEvent.Topic}");
                    // Do any additional validation (as required) such as validating that the Azure resource ID of the topic matches
                    // the expected topic and then return back the below response
                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };

                    return(Ok(responseData));
                }
                else
                {
                    var statement        = new StatementExtension((JObject)eventGridEvent.Data);
                    var statementWrapper = new StatementWrapper(eventGridEvent.Subject, statement);
                    _decisionChannel.Next(statementWrapper);
                }
            }

            return(Ok(null));
        }
コード例 #3
0
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequestMessage req, TraceWriter log)
        {
            log.Info("C# HTTP trigger function processed a request.");

            string requestContent = await req.Content.ReadAsStringAsync();

            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestContent);

            foreach (EventGridEvent azevents in eventGridEvents)
            {
                if (azevents.Data is SubscriptionValidationEventData)
                {
                    var EventData    = (SubscriptionValidationEventData)azevents.Data;
                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = EventData.ValidationCode
                    };
                    return(req.CreateResponse(HttpStatusCode.OK, responseData));
                }
                else
                {
                    var jsonString = JsonConvert.SerializeObject(azevents);
                    var content    = new StringContent(jsonString, Encoding.UTF8, "application/json");
                    var response   = await client.PostAsync("https://webhook.site/9d2ae6bf-cd79-4896-b44c-0e60a9e2061a", content);
                }
            }
            return(req.CreateResponse(HttpStatusCode.OK));
        }
コード例 #4
0
        public async Task <IActionResult> Post()
        {
            string       response = string.Empty;
            const string SmsDeliveryReportEvent = "Microsoft.Communication.SMSDeliveryReportReceived";
            string       requestContent         = await new StreamReader(Request.Body).ReadToEndAsync();

            _logger.LogInformation($"Received events: {requestContent}");

            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            eventGridSubscriber.AddOrUpdateCustomEventMapping(SmsDeliveryReportEvent, typeof(SmsDeliveryReportEventData));
            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestContent);

            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                if (eventGridEvent.Data is SubscriptionValidationEventData eventData)
                {
                    _logger.LogInformation($"Got SubscriptionValidation event data, validation code: {eventData.ValidationCode}, topic: {eventGridEvent.Topic}");
                    // Do any additional validation (as required) and then return back the below response

                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };
                    return(new OkObjectResult(responseData));
                }
                else if (eventGridEvent.Data is SmsDeliveryReportEventData deliveryReportEventData)
                {
                    _logger.LogInformation($"Got SmsDeliveryReport event data, messageId: {deliveryReportEventData.MessageId}, DeliveryStatus: {deliveryReportEventData.DeliveryStatus}");
                    return(new OkObjectResult(deliveryReportEventData.MessageId));
                }
            }
            return(new OkObjectResult(response));
        }
コード例 #5
0
        public async Task Run([EventGridTrigger] string eventGridEvent, ILogger logger)
        {
            try
            {
                logger.LogInformation($"JobOutputStatusFunction::Run triggered: message={LogHelper.FormatObjectForLog(eventGridEvent)}");

                // Events use inheritance and in order to correctly deserialize them, EventGridSubscriber should be used
                var eventGridSubscriber = new EventGridSubscriber();

                // as a work around, json is modified to have a list of events
                var parsedEventGridEvents = eventGridSubscriber.DeserializeEventGridEvents($"[{eventGridEvent}]");

                // there should be only one event triggered for EventGridTrigger
                var jobOutputStatusModel = this.eventGridService.ParseEventData(parsedEventGridEvents.FirstOrDefault(), logger);
                if (jobOutputStatusModel != null)
                {
                    var result = await this.jobOutputStatusService.ProcessJobOutputStatusAsync(jobOutputStatusModel, logger).ConfigureAwait(false);

                    logger.LogInformation($"JobOutputStatusFunction::Run completed: result={LogHelper.FormatObjectForLog(result)}");
                }
                else
                {
                    logger.LogInformation($"JobOutputStatusFunction::Run event data skipped: result={LogHelper.FormatObjectForLog(eventGridEvent)}");
                }
            }
            catch (Exception e)
            {
                logger.LogError($"JobOutputStatusFunction::Run failed: exception={e.Message} eventGridEvent={LogHelper.FormatObjectForLog(eventGridEvent)}");
                // in case of error, exception is thrown in order to trigger reprocess.
                throw;
            }
        }
コード例 #6
0
        /// <summary>
        /// Validates Azure event subscription and calls the appropriate event handler. Responds HttpOk.
        /// </summary>
        /// <param name="request">HttpRequest received from Azure</param>
        /// <param name="eventTypeHandlers">Dictionary of eventType strings and their associated handlers.</param>
        /// <returns>OkObjectResult</returns>
        /// <remarks>Reference https://docs.microsoft.com/en-us/azure/event-grid/receive-events</remarks>
        public async static Task <OkObjectResult> HandleAzureEvents(HttpRequest request,
                                                                    Dictionary <string, Func <EventGridEvent, Task> > eventTypeHandlers)
        {
            var response       = string.Empty;
            var requestContent = await new StreamReader(request.Body).ReadToEndAsync();

            if (string.IsNullOrWhiteSpace(requestContent))
            {
                return(new OkObjectResult(response));
            }

            var eventGridSubscriber = new EventGridSubscriber();
            var eventGridEvents     = eventGridSubscriber.DeserializeEventGridEvents(requestContent);

            foreach (var eventGridEvent in eventGridEvents)
            {
                if (eventGridEvent.Data is SubscriptionValidationEventData eventData)
                {
                    // Might want to enable additional validation: subject, topic etc.

                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };

                    return(new OkObjectResult(responseData));
                }
                else if (eventTypeHandlers.ContainsKey(eventGridEvent.EventType))
                {
                    await eventTypeHandlers[eventGridEvent.EventType](eventGridEvent);
                }
            }

            return(new OkObjectResult(response));
        }
コード例 #7
0
ファイル: Webhook.cs プロジェクト: Cisien/event-grid-webhook
        public async Task <IActionResult> Post()
        {
            var subscriber = new EventGridSubscriber();

            using var ms = new MemoryStream();
            await Request.Body.CopyToAsync(ms); ms.Position = 0;

            using var sr = new StreamReader(ms);
            var message = await sr.ReadToEndAsync();

            ms.Position = 0;
            var events = subscriber.DeserializeEventGridEvents(ms);

            _logger.LogInformation($"{events.Length} Message(s) Received");

            foreach (var evt in events)
            {
                _logger.LogInformation($"Handling {evt.EventType}: {evt.GetType().Name}");
                evt.Validate();
                _ = evt.Data switch
                {
                    SubscriptionValidationEventData validationEvent => HandleValidationEvent(validationEvent),
                    IotHubDeviceTelemetryEventData iotData => await HandleIotData(iotData),
                    _ => HandleUnknown(evt.Data)
                };
            }
            return(Ok());
        }
        public async Task <IActionResult> ReceiveEvents()
        {
            using var reader = new StreamReader(Request.Body, Encoding.UTF8);
            string requestContent = await reader.ReadToEndAsync().ConfigureAwait(false);

            logger.LogInformation($"Received events: {requestContent}");

            var eventGridSubscriber = new EventGridSubscriber();

            foreach (var key in acceptedEventTypes.Keys)
            {
                eventGridSubscriber.AddOrUpdateCustomEventMapping(key, typeof(EventGridEventData));
            }

            var eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestContent);

            foreach (var eventGridEvent in eventGridEvents)
            {
                if (!Guid.TryParse(eventGridEvent.Id, out Guid eventId))
                {
                    throw new InvalidDataException($"Invalid Guid for EventGridEvent.Id '{eventGridEvent.Id}'");
                }

                if (eventGridEvent.Data is SubscriptionValidationEventData subscriptionValidationEventData)
                {
                    logger.LogInformation($"Got SubscriptionValidation event data, validationCode: {subscriptionValidationEventData!.ValidationCode},  validationUrl: {subscriptionValidationEventData.ValidationUrl}, topic: {eventGridEvent.Topic}");

                    // Do any additional validation (as required) such as validating that the Azure resource ID of the topic matches
                    // the expected topic and then return back the below response
                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = subscriptionValidationEventData.ValidationCode,
                    };

                    return(Ok(responseData));
                }
                else if (eventGridEvent.Data is EventGridEventData eventGridEventData)
                {
                    if (!Guid.TryParse(eventGridEventData.ItemId, out Guid contentId))
                    {
                        throw new InvalidDataException($"Invalid Guid for EventGridEvent.Data.ItemId '{eventGridEventData.ItemId}'");
                    }

                    var cacheOperation = acceptedEventTypes[eventGridEvent.EventType];

                    logger.LogInformation($"Got Event Id: {eventId}: {eventGridEvent.EventType}: Cache operation: {cacheOperation} {eventGridEventData.Api}");

                    var result = await webhookService.ProcessMessageAsync(cacheOperation, eventId, contentId, eventGridEventData.Api).ConfigureAwait(false);

                    LogResult(eventId, contentId, result);
                }
                else
                {
                    throw new InvalidDataException($"Invalid event type '{eventGridEvent.EventType}' received for Event Id: {eventId}, should be one of '{string.Join(",", acceptedEventTypes.Keys)}'");
                }
            }

            return(Ok());
        }
コード例 #9
0
        private async Task <EventGridEvent[]> GetEventGridEventsAsync()
        {
            using var reader = new StreamReader(Request.Body, Encoding.UTF8);
            string body = await reader.ReadToEndAsync();

            var eventGridSubscriber = new EventGridSubscriber();

            return(eventGridSubscriber.DeserializeEventGridEvents(body));
        }
コード例 #10
0
        public async Task ProcessAsync(HttpRequest httpRequest, HttpResponse httpResponse, IBot bot,
                                       CancellationToken cancellationToken = default)
        {
            if (httpRequest == null)
            {
                throw new ArgumentNullException(nameof(httpRequest));
            }

            if (httpResponse == null)
            {
                throw new ArgumentNullException(nameof(httpResponse));
            }

            if (bot == null)
            {
                throw new ArgumentNullException(nameof(bot));
            }

            string body;

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

            var eventGridSubscriber = new EventGridSubscriber();
            var eventGridEvents     = eventGridSubscriber.DeserializeEventGridEvents(body);

            foreach (var eventGridEvent in eventGridEvents)
            {
                if (eventGridEvent.Data is SubscriptionValidationEventData eventData)
                {
                    // Do any additional validation (as required) and then return back the below response
                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };
                    httpResponse.StatusCode = (int)HttpStatusCode.OK;
                    var responseJson      = JsonConvert.SerializeObject(responseData);
                    var responseDataBytes = Encoding.UTF8.GetBytes(responseJson);
                    await httpResponse.Body.WriteAsync(responseDataBytes, 0, responseDataBytes.Length).ConfigureAwait(false);
                }
                else
                {
                    var activity = RequestToActivity(eventGridEvent);

                    using (var context = new TurnContext(this, activity))
                    {
                        context.TurnState.Add("httpStatus", HttpStatusCode.OK.ToString("D"));
                        await RunPipelineAsync(context, bot.OnTurnAsync, cancellationToken).ConfigureAwait(false);

                        httpResponse.StatusCode = (int)HttpStatusCode.OK;
                    }
                }
            }
        }
コード例 #11
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation($"C# HTTP trigger function begun");
            string response = string.Empty;

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();

            log.LogInformation($"Received events: {requestBody}");

            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            eventGridSubscriber.AddOrUpdateCustomEventMapping("eventTypeSms", typeof(SmsContent));

            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestBody);

            List <string> outputs = new List <string>();

            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                if (eventGridEvent.Data is SmsContent)
                {
                    var eventData = (SmsContent)eventGridEvent.Data;
                    log.LogInformation($"Got SubscriptionValidation event data, data: '{eventData}', topic: {eventGridEvent.Topic}");

                    outputs.Add(eventData.ToString());
                }

                // NEEDED TO SUBSCRIBE OUR WEBHOOK
                if (eventGridEvent.Data is SubscriptionValidationEventData)
                {
                    var eventData = (SubscriptionValidationEventData)eventGridEvent.Data;
                    log.LogInformation($"Got SubscriptionValidation event data, validation code: {eventData.ValidationCode}, topic: {eventGridEvent.Topic}");
                    // Do any additional validation (as required) and then return back the below response

                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };

                    return(new OkObjectResult(responseData));
                }
            }

            return(new OkObjectResult(outputs));
        }
コード例 #12
0
        public async Task <IActionResult> Post([FromBody] object request)
        {
            //Deserializing the request
            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(request.ToString());


            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                // Validate whether EventType is of "Microsoft.EventGrid.SubscriptionValidationEvent"
                if (eventGridEvent.EventType == "Microsoft.EventGrid.SubscriptionValidationEvent")
                {
                    var eventData = (SubscriptionValidationEventData)eventGridEvent.Data;
                    // Do any additional validation (as required) such as validating that the Azure resource ID of the topic matches
                    // the expected topic and then return back the below response
                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };


                    if (responseData.ValidationResponse != null)
                    {
                        return(Ok(responseData));
                    }
                }
                else
                {
                    dynamic configMessage = eventGridEvent.Data;

                    string key = configMessage.Key.ToString();

                    if (configMessage.Key == "TestApp:Settings:Message")
                    {
                        var result = await AppConfigConnector.GetValue(key, _config);

                        var message = JsonConvert.DeserializeObject <AppConfigMessage>(result);

                        await _hubContext.Clients.All.SendAsync("SendMessage", message.Value);
                    }
                }
            }

            return(Ok());
        }
コード例 #13
0
        public IoTHubToTwins(IConfiguration configuration, ILogger <IoTHubToTwins> log)
        {
            this.configuration = configuration;
            this.log           = log;

            eventGridSubscriber = new EventGridSubscriber();

            this.cred = new DefaultAzureCredential(new DefaultAzureCredentialOptions {
                SharedTokenCacheTenantId = tenantId,
                ManagedIdentityClientId  = clientId
            });
            this.client = new DigitalTwinsClient(
                new Uri(adtServiceUrl), this.cred, new DigitalTwinsClientOptions
            {
                Transport = new HttpClientTransport(httpClient)
            });
        }
コード例 #14
0
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"C# HTTP trigger function begun");
            string       response         = string.Empty;
            const string CustomTopicEvent = "Contoso.Items.ItemReceived";

            string requestContent = await req.Content.ReadAsStringAsync();

            log.Info($"Received events: {requestContent}");

            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            eventGridSubscriber.AddOrUpdateCustomEventMapping(CustomTopicEvent, typeof(ContosoItemReceivedEventData));
            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestContent);

            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                if (eventGridEvent.Data is SubscriptionValidationEventData)
                {
                    var eventData = (SubscriptionValidationEventData)eventGridEvent.Data;
                    log.Info($"Got SubscriptionValidation event data, validationCode: {eventData.ValidationCode},  validationUrl: {eventData.ValidationUrl}, topic: {eventGridEvent.Topic}");
                    // Do any additional validation (as required) such as validating that the Azure resource ID of the topic matches
                    // the expected topic and then return back the below response
                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };

                    return(req.CreateResponse(HttpStatusCode.OK, responseData));
                }
                else if (eventGridEvent.Data is StorageBlobCreatedEventData)
                {
                    var eventData = (StorageBlobCreatedEventData)eventGridEvent.Data;
                    log.Info($"Got BlobCreated event data, blob URI {eventData.Url}");
                }
                else if (eventGridEvent.Data is ContosoItemReceivedEventData)
                {
                    var eventData = (ContosoItemReceivedEventData)eventGridEvent.Data;
                    log.Info($"Got ContosoItemReceived event data, item SKU {eventData.ItemSku}");
                }
            }

            return(req.CreateResponse(HttpStatusCode.OK, response));
        }
コード例 #15
0
        public static IEnumerable <T> Parse <T>(HttpRequestMessage request)
        {
            string requestContent = request.Content.ReadAsStringAsync().GetAwaiter().GetResult();
            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            eventGridSubscriber.AddOrUpdateCustomEventMapping(typeof(T).FullName, typeof(T));
            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestContent);

            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                if (eventGridEvent.Data is SubscriptionValidationEventData)
                {
                    var eventData = (SubscriptionValidationEventData)eventGridEvent.Data;
                }
                else if (eventGridEvent.Data.GetType() == typeof(T))
                {
                    yield return((T)eventGridEvent.Data);
                }
            }
        }
コード例 #16
0
        public IActionResult Post([FromBody] object request)
        {
            //Deserializing the request
            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(request.ToString());


            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                // Validate whether EventType is of "Microsoft.EventGrid.SubscriptionValidationEvent"
                if (eventGridEvent.EventType == "Microsoft.EventGrid.SubscriptionValidationEvent")
                {
                    var eventData = (SubscriptionValidationEventData)eventGridEvent.Data;
                    // Do any additional validation (as required) such as validating that the Azure resource ID of the topic matches
                    // the expected topic and then return back the below response
                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };


                    if (responseData.ValidationResponse != null)
                    {
                        return(Ok(responseData));
                    }
                }
                else
                {
                    var truck = JsonConvert.DeserializeObject <Truck>(eventGridEvent.Data.ToString());

                    object[] args = { truck.TruckId, truck };

                    _hubContext.Clients.All.SendCoreAsync("SendMessage", args);

                    Console.WriteLine(truck);
                }
            }

            return(Ok());
        }
コード例 #17
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();

            EventGridEvent[] events = new EventGridSubscriber().DeserializeEventGridEvents(requestBody);

            var sw = new StringWriter();

            foreach (EventGridEvent eventGridEvent in events)
            {
                if (eventGridEvent.Data is SubscriptionValidationEventData)
                {
                    //todo: move to separate method
                    var eventData = (SubscriptionValidationEventData)eventGridEvent.Data;
                    log.LogInformation($"Got SubscriptionValidation event data, validation code: {eventData.ValidationCode}, topic: {eventGridEvent.Topic}");
                    // Do any additional validation (as required) and then return back the below response

                    var validationResponseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };

                    return(new OkObjectResult(validationResponseData));
                }
                if (eventGridEvent.Data is StorageBlobCreatedEventData)
                {
                    //todo: move to separate method
                    var blobEventData = (StorageBlobCreatedEventData)eventGridEvent.Data;
                    //do whatever with the blob event info
                    await sw.WriteLineAsync($"Url: {blobEventData.Url}, Length: {blobEventData.ContentLength}");

                    await sw.WriteLineAsync();
                }
            }
            return(new OkObjectResult(sw.ToString()));
        }
コード例 #18
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
            [CosmosDB(
                 databaseName: "icecream",
                 collectionName: "products",
                 CreateIfNotExists = true,
                 ConnectionStringSetting = "CosmosDbConnectionString")] IAsyncCollector <dynamic> products,
            ILogger log)
        {
            var requestBody = await new StreamReader(req.Body).ReadToEndAsync();

            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestBody);

            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                if (eventGridEvent.Data is SubscriptionValidationEventData)
                {
                    var eventData = (SubscriptionValidationEventData)eventGridEvent.Data;

                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };

                    return(new OkObjectResult(responseData));
                }

                if (eventGridEvent.EventType == "Microsoft.Storage.BlobCreated" &&
                    eventGridEvent.Subject.ToLower().EndsWith(".json"))
                {
                    await products.AddAsync(eventGridEvent.Data);
                }
            }

            return(new OkResult());
        }
コード例 #19
0
        static Task ProcessEventHandler(ProcessEventArgs eventArgs)
        {
            // Write the body of the event to the console window
            Console.WriteLine("\tRecevied event: {0}", Encoding.UTF8.GetString(eventArgs.Data.Body.ToArray()));

            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(Encoding.UTF8.GetString(eventArgs.Data.Body.ToArray()));
            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                // All possible events: https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.eventgrid.models?view=azure-dotnet
                // We are only processing events for "StorageBlobCreatedEventData"
                if (eventGridEvent.Data is StorageBlobCreatedEventData)
                {
                    DateTime msgUtcNow = DateTime.UtcNow;
                    Console.WriteLine($"RCVD: Event ID:{eventGridEvent.Id} [Latency:{msgUtcNow.Subtract(eventGridEvent.EventTime)}]");
                    var eventData = (StorageBlobCreatedEventData)eventGridEvent.Data;
                    Console.WriteLine($"Got BlobCreated event data, blob URI {eventData.Url}");
                }
            }

            return(Task.CompletedTask);
        }
コード例 #20
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            string requestContent = await new StreamReader(req.Body).ReadToEndAsync();

            log.LogInformation($"Received events: {requestContent}");

            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestContent);

            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                switch (eventGridEvent.Data)
                {
                case SubscriptionValidationEventData subscriptionValidation:
                    log.LogInformation($"Got SubscriptionValidation event data, validationCode: {subscriptionValidation.ValidationCode},  validationUrl: {subscriptionValidation.ValidationUrl}, topic: {eventGridEvent.Topic}");
                    // Do any additional validation (as required) such as validating that the Azure resource ID of the topic matches
                    // the expected topic and then return back the below response
                    return(new OkObjectResult(new SubscriptionValidationResponse()
                    {
                        ValidationResponse = subscriptionValidation.ValidationCode
                    }));

                case StorageBlobCreatedEventData storageBlobCreated:
                    log.LogInformation($"Got BlobCreated event data, blob URI {storageBlobCreated.Url}");
                    break;

                // Handle other messages here
                default:
                    return(new BadRequestResult());
                }
            }

            return(new OkResult());
        }
コード例 #21
0
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function)] HttpRequestMessage req, TraceWriter log)
        {
            log.Info("C# HTTP trigger function processed a request.");
            // parse query parameter
            var content = req.Content;

            string jsonContent = await content.ReadAsStringAsync();

            log.Info($"Received Event with payload: {jsonContent}");

            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(jsonContent);

            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                if (eventGridEvent.Data is SubscriptionValidationEventData)
                {
                    var eventData = (SubscriptionValidationEventData)eventGridEvent.Data;
                    log.Info($"Got SubscriptionValidation event data, validationCode: {eventData.ValidationCode},  validationUrl: {eventData.ValidationUrl}, topic: {eventGridEvent.Topic}");
                    // Do any additional validation (as required) such as validating that the Azure resource ID of the topic matches
                    // the expected topic and then return back the below response
                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };

                    return(req.CreateResponse(HttpStatusCode.OK, responseData));
                }
            }


            return(jsonContent == null
            ? req.CreateResponse(HttpStatusCode.BadRequest, "Pass a name on the query string or in the request body")
            : req.CreateResponse(HttpStatusCode.OK, "Hello " + jsonContent));
        }
コード例 #22
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            string response = string.Empty;

            string requestContent = await new StreamReader(req.Body).ReadToEndAsync();

            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestContent);

            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                if (eventGridEvent.Data is SubscriptionValidationEventData)
                {
                    var eventData = (SubscriptionValidationEventData)eventGridEvent.Data;
                    log.LogInformation($"Got SubscriptionValidation event data, validation code: {eventData.ValidationCode}, topic: {eventGridEvent.Topic}");

                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };

                    return(new OkObjectResult(responseData));
                }
                else
                {
                    log.LogInformation(eventGridEvent.Data.ToString());

                    log.LogInformation($"EventType {eventGridEvent.EventType}");
                }
            }

            return(new OkObjectResult(string.Empty));
        }
コード例 #23
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation($"C# HTTP trigger function begun");
            var response = string.Empty;

            var requestContent = await new StreamReader(req.Body).ReadToEndAsync();

            log.LogInformation($"Received events: {requestContent}");

            var eventGridSubscriber = new EventGridSubscriber();

            var eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestContent);

            foreach (var eventGridEvent in eventGridEvents)
            {
                if (eventGridEvent.Data is SubscriptionValidationEventData)
                {
                    var eventData = (SubscriptionValidationEventData)eventGridEvent.Data;
                    log.LogInformation($"Got SubscriptionValidation event data, validation code: {eventData.ValidationCode}, topic: {eventGridEvent.Topic}");
                    // Do any additional validation (as required) and then return back the below response

                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };

                    return(new OkObjectResult(responseData));
                }

                return(new ObjectResult(eventGridEvent.Data));
            }

            return(new OkObjectResult(response));
        }
コード例 #24
0
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function)] HttpRequestMessage req, TraceWriter log)
        {
            var          content          = req.Content;
            const string CustomTopicEvent = "EventGridDoc-Topic";

            string jsonContent = await content.ReadAsStringAsync();

            /*
             * jsonContent = @"[{'data':
             * {
             *  'Date1':'12/12/2018 6:11:21 PM',
             *  'Date2':null,
             *  'Event':10,
             *  'IsForce':false,
             *  'PropertyID':'10139104',
             *  'JobID': '12345'
             * },
             * 'eventTime':'12/12/2018 6:11:21 PM',
             * 'eventType':'allEvents',
             * 'id':'6d740f89-90e3-4652-9a82-1bb0117e7864',
             * 'subject':'Turn Process : JOB_AND_CONTRACTS_SUBMITTED_TO_YARDI',
             * 'topic':''
             * }]";
             *
             * jsonContent = @"[{'data':
             * {
             *  'Date1':'12/12/2018 6:11:21 PM',
             *  'Date2':null,
             *  'Event':1001,
             *  'IsForce':false,
             *  'PropertyID':'10139104'
             * },
             * 'eventTime':'12/12/2018 6:11:21 PM',
             * 'eventType':'allEvents',
             * 'id':'6d740f89-90e3-4652-9a82-1bb0117e7864',
             * 'subject':'Turn Process : ASSIGN_PROJECT_MANAGER',
             * 'topic':''
             * }]";
             */
            log.Info($"Received Event with payload: {jsonContent}");
            //CRMCall(log);
            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            eventGridSubscriber.AddOrUpdateCustomEventMapping(CustomTopicEvent, typeof(GridEvent <DataPayLoad>));

            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(jsonContent);

            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                if (eventGridEvent.Data is SubscriptionValidationEventData)
                {
                    var eventData = (SubscriptionValidationEventData)eventGridEvent.Data;
                    log.Info($"Got SubscriptionValidation event data, validationCode: {eventData.ValidationCode},  validationUrl: {eventData.ValidationUrl}, topic: {eventGridEvent.Topic}");
                    // Do any additional validation (as required) such as validating that the Azure resource ID of the topic matches
                    // the expected topic and then return back the below response
                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };

                    return(req.CreateResponse(HttpStatusCode.OK, responseData));
                }
                else if (eventGridEvent.Data is StorageBlobCreatedEventData)
                {
                    var eventData = (StorageBlobCreatedEventData)eventGridEvent.Data;
                    log.Info($"Got BlobCreated event data, blob URI {eventData.Url}");
                }
                else if (eventGridEvent.Data is object)
                {
                    DataPayLoad tr = JsonConvert.DeserializeObject <DataPayLoad>(eventGridEvent.Data.ToString());
                    if (tr is DataPayLoad)
                    {
                        OrganizationWebProxyClient _service = CRMCall(log);
                        if (_service is OrganizationWebProxyClient)
                        {
                            Entity azrIntegrationCallEntity = new Entity(Constants.AzureIntegrationCalls.LogicalName);
                            azrIntegrationCallEntity[Constants.AzureIntegrationCalls.EventName] = tr.Event.ToString();
                            azrIntegrationCallEntity[Constants.AzureIntegrationCalls.EventData] = jsonContent;

                            azrIntegrationCallEntity.Id = _service.Create(azrIntegrationCallEntity);
                            log.Info($"Event Successfully Posted to D365 with Integration Call ID : {azrIntegrationCallEntity.Id.ToString()}");
                        }
                    }
                    log.Info($"Got ContosoItemReceived event data, item Topic {eventGridEvent.Topic}");
                }
            }


            return(jsonContent == null
            ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a name on the query string or in the request body")
            : req.CreateResponse(HttpStatusCode.OK, "Hello " + jsonContent));
        }
コード例 #25
0
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function)] HttpRequestMessage req, TraceWriter log)
        {
            log.Info("C# HTTP trigger function processed a request.");
            // parse query parameter
            var          content          = req.Content;
            const string CustomTopicEvent = "Contoso.Items.ItemReceived";

            // Get content
            string jsonContent = await content.ReadAsStringAsync();

            log.Info($"Received Event with payload: {jsonContent}");

            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            eventGridSubscriber.AddOrUpdateCustomEventMapping(CustomTopicEvent, typeof(GridEvent));

            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(jsonContent);

            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                if (eventGridEvent.Data is SubscriptionValidationEventData)
                {
                    var eventData = (SubscriptionValidationEventData)eventGridEvent.Data;
                    log.Info($"Got SubscriptionValidation event data, validationCode: {eventData.ValidationCode},  validationUrl: {eventData.ValidationUrl}, topic: {eventGridEvent.Topic}");
                    // Do any additional validation (as required) such as validating that the Azure resource ID of the topic matches
                    // the expected topic and then return back the below response
                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode
                    };

                    return(req.CreateResponse(HttpStatusCode.OK, responseData));
                }
                else if (eventGridEvent.Data is StorageBlobCreatedEventData)
                {
                    var eventData = (StorageBlobCreatedEventData)eventGridEvent.Data;
                    log.Info($"Got BlobCreated event data, blob URI {eventData.Url}");
                }
                else if (eventGridEvent.Data is GridEvent)
                {
                    var eventData = (GridEvent)eventGridEvent.Data;
                    ReceiveAndProcess(log, eventData).GetAwaiter().GetResult();
                    log.Info($"Got ContosoItemReceived event data, item Topic {eventData.Topic}");
                }
            }

            /*
             * IEnumerable<string> headerValues;
             * if (req.Headers.TryGetValues("Aeg-Event-Type", out headerValues))
             * {
             *  // Handle Subscription validation (Whenever you create a new subscription we send a new validation message)
             *  var validationHeaderValue = headerValues.FirstOrDefault();
             *  if (validationHeaderValue == "SubscriptionValidation")
             *  {
             *      var events = JsonConvert.DeserializeObject<GridEvent[]>(jsonContent);
             *      var code = events[0].Data["validationCode"];
             *      return req.CreateResponse(HttpStatusCode.OK,
             *      new { validationResponse = code });
             *  }
             *  // React to new messages and receive
             *  else
             *  {
             *      ReceiveAndProcess(log, JsonConvert.DeserializeObject<GridEvent[]>(jsonContent)).GetAwaiter().GetResult();
             *  }
             * }
             */
            return(jsonContent == null
            ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a name on the query string or in the request body")
            : req.CreateResponse(HttpStatusCode.OK, "Hello " + jsonContent));
        }
コード例 #26
0
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestMessage req,
            ILogger log)
        {
            string response       = string.Empty;
            string requestContent = string.Empty;

            if (req?.Content == null)
            {
                log.LogInformation("Received events: null");
            }
            else
            {
                requestContent = await req.Content.ReadAsStringAsync();

                log.LogInformation($"Received events: {requestContent}");
            }

            if (string.IsNullOrWhiteSpace(requestContent))
            {
                log.LogInformation("Request content was empty.");
            }
            else
            {
                log.LogInformation("Prepping deserialize");
                EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();
                EventGridEvent[]    eventGridEvents     = null;

                try
                {
                    eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestContent);
                    log.LogInformation("eventGridEvents null? " + (eventGridEvents == null));
                }
                catch (Exception ex)
                {
                    log.LogError("eventGridEvents error: " + ex.Message);
                }

                if (eventGridEvents != null)
                {
                    foreach (EventGridEvent eventGridEvent in eventGridEvents)
                    {
                        log.LogInformation("eventGridEvent null? " + (eventGridEvent == null));

                        if (eventGridEvent.Data is SubscriptionValidationEventData)
                        {
                            var eventData = (SubscriptionValidationEventData)eventGridEvent.Data;

                            log.LogInformation($"Got SubscriptionValidation event data, validationCode: {eventData.ValidationCode},  validationUrl: {eventData.ValidationUrl}, topic: {eventGridEvent.Topic}");

                            // Do any additional validation (as required) such as validating that the Azure resource ID of the topic matches
                            // the expected topic and then return back the below response
                            var responseData = new SubscriptionValidationResponse()
                            {
                                ValidationResponse = eventData.ValidationCode
                            };

                            return(req.CreateResponse(HttpStatusCode.OK, responseData));
                        }
                        else
                        {
                            log.LogInformation("Data " + eventGridEvent.Data.ToString());
                        }
                    }
                }
            }

            return(req.CreateResponse(HttpStatusCode.OK, response));
        }
コード例 #27
0
        public WebhookRequestModel ExtractEvent(string requestBody)
        {
            var webhookRequestModel = new WebhookRequestModel();

            logger.LogInformation($"Received events: {requestBody}");

            var eventGridSubscriber = new EventGridSubscriber();

            foreach (var key in acceptedEventTypes.Keys)
            {
                eventGridSubscriber.AddOrUpdateCustomEventMapping(key, typeof(EventGridEventData));
            }

            var eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestBody);

            foreach (var eventGridEvent in eventGridEvents)
            {
                if (!Guid.TryParse(eventGridEvent.Id, out Guid eventId))
                {
                    throw new InvalidDataException($"Invalid Guid for EventGridEvent.Id '{eventGridEvent.Id}'");
                }

                if (eventGridEvent.Data is SubscriptionValidationEventData subscriptionValidationEventData)
                {
                    logger.LogInformation($"Got SubscriptionValidation event data, validationCode: {subscriptionValidationEventData!.ValidationCode},  validationUrl: {subscriptionValidationEventData.ValidationUrl}, topic: {eventGridEvent.Topic}");

                    webhookRequestModel.WebhookCommand = WebhookCommand.SubscriptionValidation;
                    webhookRequestModel.SubscriptionValidationResponse = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = subscriptionValidationEventData.ValidationCode,
                    };

                    return(webhookRequestModel);
                }
                else if (eventGridEvent.Data is EventGridEventData eventGridEventData)
                {
                    if (!Guid.TryParse(eventGridEventData.ItemId, out Guid contentId))
                    {
                        throw new InvalidDataException($"Invalid Guid for EventGridEvent.Data.ItemId '{eventGridEventData.ItemId}'");
                    }

                    if (!Uri.TryCreate(eventGridEventData.Api, UriKind.Absolute, out Uri? url))
                    {
                        throw new InvalidDataException($"Invalid Api url '{eventGridEventData.Api}' received for Event Id: {eventId}");
                    }

                    var cacheOperation = acceptedEventTypes[eventGridEvent.EventType];

                    logger.LogInformation($"Got Event Id: {eventId}: {eventGridEvent.EventType}: Cache operation: {cacheOperation} {url}");

                    var messageContentType = DetermineMessageContentType(url.ToString());
                    if (messageContentType == MessageContentType.None)
                    {
                        logger.LogError($"Event Id: {eventId} got unknown message content type - {messageContentType} - {url}");
                        return(webhookRequestModel);
                    }

                    webhookRequestModel.WebhookCommand = DetermineWebhookCommand(messageContentType, cacheOperation);
                    webhookRequestModel.EventId        = eventId;
                    webhookRequestModel.EventType      = eventGridEvent.EventType;
                    webhookRequestModel.ContentId      = contentId;
                    webhookRequestModel.Url            = url;
                }
                else
                {
                    throw new InvalidDataException($"Invalid event type '{eventGridEvent.EventType}' received for Event Id: {eventId}, should be one of '{string.Join(",", acceptedEventTypes.Keys)}'");
                }
            }

            return(webhookRequestModel);
        }
コード例 #28
0
        public async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "DeadLetter/api/updates")] HttpRequestMessage req, ILogger log)
        {
            Initialise(req);

            log.LogInformation($"C# HTTP trigger function begun");
            string response = string.Empty;

            string requestContent = await req.Content.ReadAsStringAsync().ConfigureAwait(false);

            log.LogInformation($"Received events: {requestContent}");

            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();

            EventGridEvent[] eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestContent);

            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                if (eventGridEvent.Data.GetType() == typeof(SubscriptionValidationEventData))
                {
                    var eventData = eventGridEvent.Data as SubscriptionValidationEventData;

                    if (eventData == null)
                    {
                        throw new InvalidDataException($"{nameof(SubscriptionValidationEventData)} in EventGridEvent {eventGridEvent.Id} is null");
                    }

                    log.LogInformation($"Got SubscriptionValidation event data, validation code: {eventData.ValidationCode}, topic: {eventGridEvent.Topic}");

                    var responseData = new SubscriptionValidationResponse()
                    {
                        ValidationResponse = eventData.ValidationCode,
                    };

                    return(new HttpResponseMessage(HttpStatusCode.OK)
                    {
                        Content = new StringContent(JsonConvert.SerializeObject(responseData), Encoding.UTF8, "application/json"),
                    });
                }
                else if (eventGridEvent.Data.GetType() == typeof(StorageBlobCreatedEventData))
                {
                    if (options.CurrentValue.DeadLetterBlobContainerName == null)
                    {
                        throw new ArgumentException(nameof(options.CurrentValue.DeadLetterBlobContainerName));
                    }

                    var eventData = eventGridEvent.Data as StorageBlobCreatedEventData;

                    if (eventData == null)
                    {
                        throw new InvalidDataException($"{nameof(StorageBlobCreatedEventData)} in EventGridEvent {eventGridEvent.Id} is null");
                    }

                    if (eventData?.Url.Contains(options.CurrentValue.DeadLetterBlobContainerName, StringComparison.OrdinalIgnoreCase) == true)
                    {
                        log.LogInformation("Processing Dead Lettered Event");

                        var blobString = $"{options.CurrentValue.DeadLetterBlobContainerName}/{options.CurrentValue.TopicName}/";

                        int startIndex     = eventData.Url.IndexOf(blobString, StringComparison.OrdinalIgnoreCase) + blobString.Length;
                        int endIndex       = eventData.Url.IndexOf("/", startIndex, StringComparison.OrdinalIgnoreCase);
                        var subscriberName = eventData.Url[startIndex..endIndex];
コード例 #29
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            var stackexchangeResponseItem = new StackExchangeResponseItem();

            log.LogInformation("C# HTTP trigger function processed a request.");
            log.LogInformation($"Received event: {req.Body}");

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();

            EventGridSubscriber eventGridSubscriber = new EventGridSubscriber();
            EventGridEvent      eventGridEvent      = eventGridSubscriber.DeserializeEventGridEvents(requestBody)[0];

            var data = JsonConvert.SerializeObject(eventGridEvent.Data);

            stackexchangeResponseItem = JsonConvert.DeserializeObject <StackExchangeResponseItem>(data);



            var card     = new ToTeams();
            var tags     = string.Join('|', stackexchangeResponseItem.tags);
            var section1 = new Section()
            {
                activityTitle = stackexchangeResponseItem.title, activityText = stackexchangeResponseItem.owner.user_id.ToString(), activitySubtitle = "Tags used: " + tags, activityImage = "stackexchangeResponseItem.owner.profile_image"
            };

            var image = new Image();

            image.image = stackexchangeResponseItem.owner.profile_image;

            var potentialAction = new PotentialAction();

            potentialAction.context = "http://shema.org";
            potentialAction.type    = "ViewAction";
            potentialAction.name    = "Open in browser";
            potentialAction.target  = new List <string>();
            potentialAction.target.Add(stackexchangeResponseItem.link);
            potentialAction.id = "SELink";


            card.content = new Content()
            {
                title = "New Question", summary = "Summary", sections = new List <Section>()
            };
            card.content.sections.Add(section1);
            card.content.potentialAction = new List <PotentialAction>();
            card.content.potentialAction.Add(potentialAction);

            var contentJson = "";

            log.LogInformation("content json: " + contentJson);
            try
            {
                contentJson = JsonConvert.SerializeObject(card.content, Formatting.None, new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore
                });
            }
            catch (Exception ex)
            {
                log.LogInformation(ex.Message);
                throw;
            }
            var requestUri = "https://outlook.office.com/webhook/cd95bc39-d4b6-47f5-af91-d1bb60673ea5@72f988bf-86f1-41af-91ab-2d7cd011db47/IncomingWebhook/34d5542e15ea4494a397f6081eb1ffbf/ccd20272-10db-42f9-81ff-7ef56c960fc0";

            var content = new StringContent(contentJson);
            HttpRequestMessage request = new HttpRequestMessage
            {
                Content = content
            };

            var postResponse = await httpClient.PostAsync(requestUri, content);

            var postResponseContent = await postResponse.Content.ReadAsStringAsync();

            var postResponseHeaders = postResponse.Headers;

            return((ActionResult) new OkObjectResult(requestBody));
        }