- Validated HTTPS endpoint, 200/202 responses and controlled retries.
- Subscriptions with clientState, tokens, and renewal before expiration.
- Latency throttling: Avoid slow or drop states by optimizing the backend.
Connect sensors IoT y receive notifications in Windows without having to constantly ask the server, this is possible thanks to webhooks. In essence, A webhook is an HTTP callback that a service does to your entry point when an event occurs. If you want fast, reliable alerts (for example, if a temperature sensor triggers a notification on your PC), this pattern is just what you need.
To fit it into a desktop environment, the normal thing is to expose a secure endpoint in the cloud or on your network, receive the notification, and from there spread it to Windows as a system notification or integrate it into your app. From here we will see requirements, HTTP responses, retries, validations, subscription lifecycles, practical examples (Microsoft Graph, Bot Framework, FME + Survey123, GitHub with Apps Script y Google Analytics with Cloud Run) and how to connect them so that your IoT sensors end up alerting you on your desktop without worrying about it.
What is a webhook and endpoint requirements?
A webhook is an HTTP-based callback API. Services like Microsoft Graph use it to send you notifications when something changes in a resource. To do it right, Your entry point must be public and with HTTPS, accessible via URL and capable of responding in a timely manner; otherwise, providers will stop sending you notifications.
In addition to being reachable, the endpoint has to return correct and consistent HTTP responsesIf your server doesn't respond in a timely manner, the service may start dropping notifications. Be careful: what's lost this way can't be recovered, so it's a good idea to monitor latency and scaling.
Another key aspect is authorization. Many services send or expect access tokens with expiration when creating or maintaining the subscription. If the token expires and you don't renew it, notifications won't be delivered (although they can be retried for a limited period). Preparing for periodic reauthorization is part of the design.
HTTP Responses and Retries
Providers consider a notification delivered when they receive a 2xx code. In Microsoft Graph, if the endpoint returns any other response within 10 seconds, retries are initiated for up to 4 hours with exponential backoff. Here's the practical guide:
- 200 OK when you can process the notification in a window of about 3 seconds.
- 202 Accepted If it will take longer: queue the notification internally and respond by accepting it.
- 5xx if you can't process it or queue it, then the service knows to retry.
Undelivered notifications are re-sent using a backoff pattern. This means that They can take up to 4 hours to replenish. Once your endpoint is back up and running, plan for queues and persistence in case your app needs event ordering.
Limitation: Slow or unresponsive endpoints
To protect performance and security, some services label endpoints with bad behavior. For example, in Microsoft Graph, a point is marked as slow if More than 10% of responses take longer than 10 seconds within a 10-minute window; in this state, new notifications are sent to you with an additional delay.
- Slow state: If the response rate >10 s exceeds 10% in 10 minutes, a 10-second delay when new notifications are sent. You exit this state when you return below 10%.
- Drop status: if that percentage exceeds the 15% in 10 minutesNew notifications can be deleted for up to 10 minutes. It'll be deleted when you drop below 15%.
If your endpoint does not meet these performance characteristics, consider using Event Hubs or Event Grid as an intermediate destination to absorb spikes and decouple processing.
Security: authentication, expirations and firewall
When you create a subscription, the service often sends an access token to the endpoint. This token is used to verify validity and has life cycle other than subscriptionIf it expires, notifications will no longer be delivered, but this doesn't limit your endpoint. However, the service typically retries for a period of time (for example, up to 4 hours) after the expiration in case you revalidate in time.
To anticipate expiration dates, add lifecycle notifications to the subscription if they're available. This way, you'll receive notifications when the token or subscription is about to expire, and you can renew them without interruption. Renewing your subscription typically also updates your token.
As for networking, you can configure the firewall to only allow incoming connections from the provider's trusted IPs (for example, the addresses used by Microsoft Graph). This reduces the attack surface and prevents false notifications.
Creating subscriptions and validating the endpoint
The subscription pattern is similar across platforms. In Microsoft Graph, the client application performs a POST to /subscriptions indicating the resource it wants to monitor and the notificationUrl to which notifications should be sent. If the request is valid, the service sends a validation to that URL and awaits your response in a timely manner.
During validation, an opaque token is sent in the request. Your endpoint must respond in less than 10 seconds with a 200 OK, Content-Type text/plain, and the validation token in the body (decoded as text). If you don't comply, the subscription won't be created. It's good practice to escape any input you display to prevent injections: although the provider doesn't send HTML or JavaScript, treats the token as opaque.
A subscription is usually required clientState (a secret value agreed upon between your app and the service) that will allow you to validate that the notifications you receive come from the provider and not from a third party. Each subscription has its own identifier, even if you monitor the same resource with the same notification URL.
Receiving and processing notifications
As long as the subscription is valid and there are changes, the provider sends a POST to your notificationUrl with the event details. Sometimes they send you collections of notifications in a single batch. optimize deliveriesFor Microsoft Graph, notifications include, but are not limited to, the notification ID, subscription ID, subscription expiration date, clientState, change type (created, updated, etc.), affected resource, and resource data.
When you receive a notification, validate the first clientStateIf it doesn't match the one you sent when creating the subscription, don't consider it valid: it may have originated outside the provider. After validating, apply your business logic (update UI, queue for processes, fire Windows notifications, etc.).
Lifecycle: renewal, disposal, and lifecycle notices
All subscriptions expire or are deleted. When you create one, you define a expirationDateTimeAt that time, the service deletes the subscription and stops sending you notifications. In the meantime, each notification you receive usually includes the next expiration date, allowing you to schedule your renewal ahead of time.
If you no longer need notifications, you can unsubscribe with its identifier; if all goes well, the service returns a 204 with no content. Even more interesting are the lifecycle notifications (if available): providing a lifecycleNotificationUrl You receive notifications when your access token is about to expire, when your subscription is nearing its end, or if an administrator revokes permissions to your app.
Webhooks in Messaging Channels: Bot Framework Outline
In custom messaging channels that integrate agents or representatives, events and messages are sent to the configured webhook endpoint. The typical pattern uses POST against a end point with conversation of style: {webhook_url}/v3/conversations/{conversationId}/activities.
The call is made with header Authorization (carrier obtained from the registered app) and the retry policy is straightforward: up to three attempts, with a 10-second wait time per attempt. After three failures, no further attempts are madeIf everything is ok, your endpoint responds with a 200 and the body sent is ignored for the purpose of responding.
Payloads follow the Bot Framework schema: fields such as type (message, event, or write), channelId, from (with id and name), conversation.id, textFormat (e.g., markdown), and attachments (with contentType and contentUrl) when applicable. This model allows messages, writing indicators and events of the system as join/close.
As for event names, the values sent in the name field cover situations such as AgentAccepted, AgentClosed, ConversationClosed, AgentStartSecondaryChannel and others of the interaction cycle. The list includes, among many, PrimaryAgentEndConversation, AgentDisconnected, AgentRaiseSecondaryChannel, AgentEndSecondaryChannel, CloseConversation, SupervisorForceClosedConversation, ConsultAgentInitiated, ConsultAgentFailed, ConsultAgentAcceptSession, ConsultAgentEndSession, ConsultAgentRejectSession, ConsultAgentSessionTimedOut, ConsultAgentRemoved, TransferToAgentInitiated, TransferToAgentFailed, TransferAgentAcceptSession, TransferAgentRejectSession, TransferAgentTimedOutSession, AgentEndedConsult, AgentJoinedCustomerConversation, ConsultantAgentLeftPublicConversation, TransferToQueueInitiated, TransferToQueueFailed, CustomerDisconnected, CustomerDisconnectedWaitingForAgent, AgentAssigned, OutOfOperationHoursDueToNonWorkingHours and OutOfOperationHoursDueToHolidays.
Example implementation: Webhook app on Cloud Run
With Google Cloud Run, you can deploy an HTTP service that listens for POSTs and processes webhook notifications. A simple example using Express parses JSON, reads the header, and X-Goog-Channel-Token and logs the body, returning 200 if all goes well. After deploying with gcloud run deploy, you get the public URL of the service; this will be the URI to which the provider will send you notifications.
In the Google Analytics Data API (v1alpha) flow, when creating an audience list you can include a webhookNotification with the URI and an optional channelToken to prevent spoofing. The provider expects a 200 from your endpoint; if it receives something else, it returns an error (for example, it might indicate it expected a 200 but received a 404). This way, you know what to adjust. the URL or response logic.
Status and content of notifications in Analytics
The POST request to the webhook includes a JSON representation of a long-term operation and a sentTimestamp (epoch Unix (in microseconds). You can use this flag to detect repeated notifications. When creating an audience list, you typically receive two POSTs: the first immediately, with the CREATING status; the second upon completion, with the ACTIVE or FAILED status as appropriate.
These submissions include fields such as name (resource path), audience, audienceDisplayName, dimensions, status, beginCreatingTime, quota tokens consumed, rowCount, percentage complete, and the webhookNotification block itself (with the URI and channelToken). With this structure, you can react on your server, record progress and trigger actions in Windows on each key change.
Automation with GitHub and Apps Script
Another useful case is to receive GitHub events via a webhook and transform them, for example, into an email to a distribution list. You can publish a web application with Google Apps Script (run as your account and accessible by anyone), copy its public URL and configure it in GitHub in Settings > Webhooks as Payload URL with content type application/json.
During setup on GitHub you may see options such as SSL verification; in some test scenarios it's disabled, although in production it's recommended to keep it enabled. Once the activation is complete, GitHub sends events to your URL; your script can format them and forward them to a destination (e.g., an email service). closing the cycle notification with very little code.
Geospatial flows with Survey123 and FME Server
In GIS environments, a webhook launched from Survey123 can feed a workspace on FME Server that processes the JSON and generates output (e.g., Excel with multiple sheets). To do this, FME Workbench uses a Text File Reader with the Read Entire File at Once option and a JSONFlattener to translate JSON fields into FME attributes.
When publishing the workspace on FME Server, register it at least as Job SubmitterIn its properties, enable the Send HTTP Message Body to Reader option so that the webhook body is sent directly to the Reader Text File when the process runs. This ensures that the content travels intact to your pipeline.
The webhook URL is generated from the FME Server web interface (Run Workspace > Advanced). First, a token This specifies the validity of the webhook. In the final dialog box, you'll see the URL; to integrate it with Survey123, you can select Authorization with Query String and paste it into the survey parameters.
With everything ready, every time a user submits a survey, the content will be transferred to FME Server, and in Jobs > Completed You'll be able to monitor the results. This architecture fits well with sensors that publish forms or events, and allows you to convert them into reports or alerts.
From webhook to Windows notification: a practical bridge
Once the server side is resolved (validation, security, retries), it's time to forward the notification to Windows. The idea is simple: your public endpoint receives the sensor event and push a signal to your teamYou can do this with an intermediate service that publishes to a bus and a lightweight agent on Windows that subscribes and displays the notification.
If you handle spikes, it is a good idea to incorporate queues in your backend (for example, when batches of notifications come in) and apply idempotence by event identifiers and sentTimestampThis way, you'll avoid duplicates on your desktop if the service retries or if your agent reconnects.
Passionate writer about the world of bytes and technology in general. I love sharing my knowledge through writing, and that's what I'll do on this blog, show you all the most interesting things about gadgets, software, hardware, tech trends, and more. My goal is to help you navigate the digital world in a simple and entertaining way.