Integration
The integration for systems nobody wrote a connector for
A generic webhook integration connects a Telegram bot to any system that can send or receive an HTTP request. It is how bespoke ERPs, in-house tools and long-tail SaaS get connected. Every webhook is at-least-once, which means every handler must be idempotent — this is the whole discipline.
Generic webhooks integration: auth, limits and availability
- Auth model
- HMAC-signed
- Delivery semantics
- At-least-once in effectively every system that implements it
- GCC availability
- Any system that speaks HTTP, including on-premise GCC logistics stacks
- Data flow
- 5 hops, worker-mediated
As of 2025-10-01, Telegram Bot API 13.4
Why this integration exists
Most businesses have at least one system nobody built a connector for. An ERP a consultancy customised in 2016, an in-house dispatch tool, a booking platform popular in one country. These systems can usually send an HTTP request when something happens and accept one when something should. That is enough.
The reason generic webhook work goes wrong is that people treat it as simpler than a real integration. A documented API tells you about rate limits, retry behaviour and delivery guarantees. A webhook from a bespoke system tells you nothing, so the assumptions have to be made explicitly and conservatively: assume it will be delivered twice, assume it will arrive out of order, assume it will occasionally not arrive at all.
Those three assumptions produce the whole design. Idempotency keys so a duplicate is a no-op. State-based rather than increment-based handling so ordering does not matter. Reconciliation so a missing delivery is noticed rather than waited for. A webhook integration built on those assumptions works with almost anything; one built on the assumption of exactly-once delivery works until the day the sender retries.
How the data actually moves
Inbound webhooks are authenticated with an HMAC signature over the raw body using a shared secret, with a timestamp checked for freshness so a captured request cannot be replayed later. Where the sending system cannot sign, a secret in a header is the fallback and the endpoint path is treated as sensitive — weaker, and stated as such rather than presented as equivalent.
Auth model: HMAC-signed requests
Their limits, and what they mean for you
Webhook delivery is at-least-once in effectively every system that implements it.
Handlers are idempotent on a key from the payload. Assuming exactly-once works until the first retry, which typically arrives during whatever incident caused the sender to retry.
Delivery order is not guaranteed, especially after a retry.
Handlers reason about the state described rather than applying a delta. An out-of-order pair then produces the correct final state instead of an inverted one.
Most senders time out in a few seconds and treat a slow response as a failure.
The endpoint acknowledges quickly and does the work afterwards. Doing the work inline produces retries, which produces duplicates, which produces the exact problem idempotency exists to absorb.
Bespoke systems frequently cannot sign requests.
A shared secret in a header plus an unguessable path is the fallback, and it is weaker. Saying so plainly is better than presenting it as equivalent security.
How it fails, and what happens when it does
The same event is delivered twice and the customer is notified twice.
Dedupe on an idempotency key. This is the single most common defect in webhook integrations and the most visible to a customer.
A status update arrives before the event that created the record.
The handler creates or updates from the state in the payload rather than assuming a prior record. Insisting on ordering means dropping events that arrive first.
The sender stops delivering and nobody notices.
A staleness check alerts when an expected feed goes quiet for longer than its normal interval. Silence is the hardest failure to notice and the most expensive to discover late.
The endpoint responds slowly and the sender retries the same event repeatedly.
Acknowledge first, process after. A slow handler turns one event into a storm of duplicates, and the sender is behaving correctly throughout.
Availability in the UAE and the wider GCC
Any system that speaks HTTP
The point of this integration. Where a documented connector exists it is usually better; where one does not, this is the answer.
On-premise systems
Common in GCC logistics and manufacturing. Outbound webhooks usually work; inbound requires the system to be reachable, which is a network conversation rather than a code one.
Systems with no callback capability
Polling is the fallback, at whatever interval the system tolerates. Slower and noisier, and sometimes the only option.
Regulated data flows
A generic webhook carries whatever the sender puts in it. Where that includes personal or financial data, the transport and retention need the same scrutiny as any other integration.
When not to use this integration
- A documented connector already exists for the system. It will handle pagination, auth refresh and rate limits you would otherwise rebuild.
- The sending system cannot sign requests and the data is sensitive. A secret in a header is weaker, and pretending otherwise is the wrong trade for personal or financial data.
- You need guaranteed exactly-once processing end to end. Webhooks cannot provide it; idempotency makes at-least-once safe, which is a different guarantee.
- The system can neither send nor receive HTTP. Then this is not the integration and polling a database or a file drop is the honest answer.
What it runs on
| Component | Version | Why |
|---|---|---|
| Cloudflare Workers | current | Signature verification, fast acknowledgement and deferred processing. |
| Cloudflare D1 | current | Idempotency keys, event log and staleness tracking. |
| Zod | 4.4 | Validation of payloads whose shape you do not control and cannot rely on. |
| grammY | 1.45 | Outbound notification into Telegram. |
Questions that come up during scoping
Why does every handler need to be idempotent?
Because webhook delivery is at-least-once in effectively every system that implements it. A sender that does not get a fast acknowledgement retries, and it is right to. Idempotency is what makes that safe rather than duplicative.
What if events arrive out of order?
Handlers reason about the state described in the payload rather than applying a delta to whatever they hold. An out-of-order pair then converges on the correct final state instead of inverting it.
How fast does the endpoint have to respond?
Fast enough that the sender does not time out, which is usually a few seconds. Acknowledge first and do the work afterwards — a slow handler turns one event into a storm of retries while the sender behaves correctly throughout.
What if the sending system cannot sign requests?
A shared secret in a header plus an unguessable path is the fallback. It is weaker than an HMAC and we say so rather than presenting it as equivalent, because the difference matters if the data is sensitive.
How do we know if a feed has stopped?
A staleness check alerts when an expected feed goes quiet for longer than its normal interval. Silence is the hardest failure to spot, because nothing errors and every dashboard looks healthy.
Is this cheaper than a proper connector?
Usually, and only because the surface is smaller. The discipline is the same and skipping it produces an integration that works in testing and duplicates customer notifications in production.
Related reading
Where the connection can be assembled without code at all, consider the Zapier integration.
The most common consumer of an inbound webhook is the dispatch build.
Consignments arriving from an existing system use exactly this pattern in the delivery tracking build.
Where the other system is really a spreadsheet, the simpler route is the Google Sheets integration.