// 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)); }
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."); }