// Called by external webhook to push data.
        public async Task PushDataAsync(WebhookTriggerData data)
        {
            WebhookTriggerListener dataListener = _generalListener;

            if (_listenerPerDataType.ContainsKey(data.odataType))
            {
                dataListener = _listenerPerDataType[data.odataType];
            }

            if (dataListener != null)
            {
                var exec = dataListener.Executor;

                TriggeredFunctionData input = new TriggeredFunctionData
                {
                    ParentId     = null,
                    TriggerValue = data,
                };
                FunctionResult result = await exec.TryExecuteAsync(input, CancellationToken.None);
            }
        }
            public Task <ITriggerData> BindAsync(object value, ValueBindingContext context)
            {
                WebhookTriggerData data = (WebhookTriggerData)value;
                var bindingData         = new Dictionary <string, object>();

                bindingData[AuthName] = GetTokenFromGraphClientAsync(data.client);

                JObject raw = data.Payload;
                object  userObject;

                if (_parameter.ParameterType == typeof(string)) //Non-.NET language case
                {
                    userObject = JsonConvert.SerializeObject(raw, Formatting.Indented);
                }
                else
                {
                    userObject = raw.ToObject(_parameter.ParameterType);
                }

                IValueProvider valueProvider = new ObjectValueProvider(userObject);
                var            triggerData   = new TriggerData(valueProvider, bindingData);

                return(Task.FromResult <ITriggerData>(triggerData));
            }
Esempio n. 3
0
        private async Task HandleNotifications(NotificationPayload notifications)
        {
            // A single webhook might get notifications from different users.
            List <WebhookTriggerData> resources = new List <WebhookTriggerData>();

            var subscriptionStore = _config.SubscriptionStore;

            foreach (Notification notification in notifications.Value)
            {
                var subId = notification.SubscriptionId;
                var entry = await subscriptionStore.GetSubscriptionEntryAsync(subId);

                if (entry == null)
                {
                    _log.LogError($"No subscription exists in our store for subscription id: {subId}");
                    // mapping of subscription ID to principal ID does not exist in file system
                    continue;
                }

                if (entry.Subscription.ClientState != notification.ClientState)
                {
                    _log.LogTrace($"The subscription store's client state: {entry.Subscription.ClientState} did not match the notifications's client state: {notification.ClientState}");
                    // Stored client state does not match client state we just received
                    continue;
                }

                // call onto Graph to fetch the resource
                var userId      = entry.UserId;
                var graphClient = await _manager.GetMSGraphClientFromUserIdAsync(userId);

                _log.LogTrace($"A graph client was obtained for subscription id: {subId}");

                // Prepend with / if necessary
                if (notification.Resource[0] != '/')
                {
                    notification.Resource = '/' + notification.Resource;
                }

                var url = graphClient.BaseUrl + notification.Resource;

                HttpRequestMessage request = new HttpRequestMessage
                {
                    Method     = HttpMethod.Get,
                    RequestUri = new Uri(url),
                };

                _log.LogTrace($"Making a GET request to {url} on behalf of subId: {subId}");

                await graphClient.AuthenticationProvider.AuthenticateRequestAsync(request); // Add authentication header

                var response = await graphClient.HttpProvider.SendAsync(request);

                string responseContent = await response.Content.ReadAsStringAsync();

                _log.LogTrace($"Recieved {responseContent} from request to {url}");

                var actualPayload = JObject.Parse(responseContent);

                // Superimpose some common properties onto the JObject for easy access.
                actualPayload["ClientState"] = entry.Subscription.ClientState;

                // Drive items only payload without resource data
                string odataType = null;
                if (notification.ResourceData != null)
                {
                    odataType = notification.ResourceData.ODataType;
                }
                else if (notification.Resource.StartsWith("/me/drive"))
                {
                    odataType = "#Microsoft.Graph.DriveItem";
                }

                actualPayload["@odata.type"] = odataType;

                var data = new WebhookTriggerData
                {
                    client    = graphClient,
                    Payload   = actualPayload,
                    odataType = odataType,
                };

                resources.Add(data);
            }

            _log.LogTrace($"Triggering {resources.Count} GraphWebhookTriggers");
            Task[] webhookReceipts = resources.Select(item => _config.OnWebhookReceived(item)).ToArray();

            Task.WaitAll(webhookReceipts);
            _log.LogTrace($"Finished responding to notifications.");
        }