Connect an AI agent to your helpdesk
The short answer
A helpdesk integration has three jobs: decide which events deserve a response, hold on to accepted work when something fails, and deliver the right reply exactly where it belongs. Creating an app and receiving a webhook is only the start. Notes, assignments, retries and your other automations all need explicit rules.
Create the app and record the API contract
If you’re connecting to your own Intercom workspace, Intercom’s documentation describes a private-app route with an access token. If other companies will install your integration, you’ll need OAuth, the standard flow where each workspace grants your app access. Either way, start in a development workspace or another safe test setup, and give the app only the permissions its supported actions need. An app that can read every conversation and write to every contact is a larger risk than one that can only reply in a single inbox.
Write down the details you’ll need when something breaks: the workspace, data region, API version, subscribed webhook topics, who owns the credential and how to revoke it. Keep secrets on the server. Map each trusted workspace to its agent configuration explicitly, so an event from a workspace you don’t recognize is rejected rather than quietly handled by a default account.
Configure the webhook endpoint in the app, then test both the endpoint validation step and a real event. Intercom documents HTTPS endpoint setup and signed notifications. Pin the API version you tested against, so a provider-side change doesn’t silently alter the payloads you receive. If you also support Zendesk, map its ticket triggers and messaging events on their own terms. Zendesk’s event model is different, and an Intercom handler with the names changed won’t be a reliable adapter.
Provider reference: webhook configuration.
Verify, store, then acknowledge
Every webhook should prove it came from the helpdesk before you act on it. Check the signature against the raw request body, at the first point in your system that still has those exact bytes. Parsing the JSON and serializing it again can change spacing or key order, which makes a genuine signature fail (or, worse, lets you check the wrong content). The downloadable signature example shows this check with a local test secret. It covers one step, not a complete endpoint.
Next, save the accepted event to durable storage before you return a success response. Helpdesks expect a quick reply to a webhook, so the actual work should happen afterward in a background worker that can pick the event up even after a restart. Add a uniqueness constraint on provider, workspace and event ID. When the helpdesk delivers the same event twice, which providers do as part of normal retry behavior, the second delivery finds the existing receipt and stops. If the database write fails, don’t return success, because you haven’t actually accepted the work.
A receipt stops duplicate intake, but each external effect still needs its own recovery rule. A worker can crash after sending a reply and before recording that it sent it. When it restarts, it needs a way to find out what already happened. Keep a delivery record, use the provider’s idempotency support where it exists (idempotency means repeating a request has the same effect as making it once) and read back from the helpdesk or reconcile before you retry. A single in-memory flag can’t give you exactly-once delivery, so don’t design as if it does.
Decide which events start work
Most webhook events shouldn’t produce an answer. A helpdesk sends events for new customer messages, but also for teammate replies, internal notes, assignments, tag changes, closes, reopens and the agent’s own replies. If each of those starts a run, the agent will answer itself, reply on top of a colleague or loop with another bot. Write an event policy: a table that says, for each event type, whether it starts an answer, triggers another action or is deliberately ignored, and why.
Record the no-action cases as carefully as the action cases. When a customer later asks why the agent stayed silent, a logged reason such as “conversation assigned to a teammate” or “event from our own bot” answers the question in seconds. The policy should also cover your existing helpdesk automations, since a workflow that assigns, tags or auto-replies will generate events of its own.
Give each channel its own rules
Chat, email and tickets carry different evidence and fail in different ways. An email arrives with quoted history and a signature, and might be an auto-reply. An anonymous chat has no trusted identity at all. Treat each channel as its own contract, and test the case most likely to break it.
| Channel | Inspect before replying | Test deliberately |
|---|---|---|
| Signed-in chat | Latest message, trusted identity, ownership, public versus note output | Customer correction while a reply is being prepared |
| Anonymous chat | Public-only access, verification route, attachment handling | A supplied email that belongs to someone else |
| Quoted history, signature, sender, recipients, attachments and auto-reply markers | Out-of-office loop and a reply with several questions | |
| Ticket | Ticket state, public comment versus private note, native triggers | A tag update that starts another automation |
| Messaging integration | Conversation-specific events and channel capabilities | A welcome event or typing event that must not start an answer |
Treat delivery as a separate operation
Generating a reply and delivering it are two different steps, and a lot can change in between. Just before sending, check again who owns the conversation and whether a newer customer message has arrived since the run started. Route public replies, internal notes and metadata updates (tags, attributes, assignments) through separate output rules, so a note can never go out as a public message by mistake. Record the intended destination and author. For email, check which mailbox the message will be sent from, not just the sender name the customer will see.
After sending, keep the message ID the helpdesk returns and check the helpdesk record itself. A successful generation doesn’t prove delivery. A successful API call doesn’t prove the message is public, in the right thread or from the intended author. Before launch, test at least four cases: a normal reply, a private note, a send that fails and a send that races a teammate taking over the conversation.
Ask AI to explain this guide
Build decisions and checks
Use these decisions to turn the worked case into your own implementation. A check is complete only when you have evidence for the stated result.
Create the app and grant access
Required. An app can have more access than it needs, or keep working after its credentials should have been revoked.
Build. For a single Intercom workspace, check whether a private app with an access token is enough. Use OAuth when the installation requires it. Set minimum permissions, separate development credentials, the supported API version, secure token storage and what happens on uninstall.
Check. Install the app in a test workspace. Revoke its access and check that the service stops cleanly.
Receive events without losing them
Required. Helpdesks can resend events, and your worker can crash after the endpoint has already returned success.
Build. Verify the provider's signature before you trust the payload. Store the accepted event durably, then acknowledge it within the provider's time limit. Deduplicate by provider, workspace and event ID, and process events with a worker that can recover after a crash. Check authenticity where you still have the original body and signature. If another service picks up the event, pass it in an authenticated internal envelope tied to its source. Never trust a "verified" flag supplied by the caller.
Check. Replay an event, stop a worker and restart it: exactly one eligible response is delivered. Invalid signatures trigger no work. Count notes, tags, assignments, translations, business writes and metric records too. A duplicate delivery must not repeat any of them.
Define an event policy
Required. New messages, notes, assignments and the agent's own replies shouldn't all trigger an answer.
Build. Build a table covering customer messages, teammate replies, notes, bot messages, reopen and close events, tags, attachments and test events. Apply channel, inbox, takeover and exclusion rules. Treat the Intercom and Zendesk event models separately, and document how you interact with native helpdesk triggers and other bots. Add a channel matrix for chat, email and tickets: event source, reply API, visibility, quoted history, auto-replies, attachments and identity evidence.
Check. Replay each event type and confirm both the intended action and the cases where the agent should deliberately do nothing. Include an out-of-office reply, a quoted email, a native assignment trigger and a scheduled job that fires after a human takes over.
Deliver the right reply to the right place
Required. A generated answer can end up as an internal note, go to the wrong mailbox or land after a human has already replied.
Build. Keep public replies separate from private notes. Handle sender identity, email and chat formatting, quoted history, links, attachment limits and delivery IDs. Check who owns the conversation again immediately before sending.
Check. Read the message back from the helpdesk. Confirm its visibility, author and destination, and that it was delivered once.
Ask AI to apply these decisions
Templates and examples
Every file uses synthetic data. Adapt it to your own policies and test it somewhere safe before it touches customers.
- intercom_signature.pyRunnable Python example (synthetic data, no network calls)
- event-policy.csvSpreadsheet worksheet (CSV)
- channel-contract.csvSpreadsheet worksheet (CSV)
intercom_signature.py"""Synthetic signature check, not a complete webhook endpoint.
Contract source: https://developers.intercom.com/docs/references/webhooks/webhook-models
Intercom's documented notification scheme uses HMAC-SHA1 over original body bytes.
Use the real app secret from a protected server store, never a request parameter.
Run: python3 intercom_signature.py
"""
import hashlib
import hmac
def valid_signature(raw_body: bytes, signature: str | None, app_secret: bytes) -> bool:
if not signature or not app_secret:
return False
expected = 'sha1=' + hmac.new(app_secret, raw_body, hashlib.sha1).hexdigest()
return hmac.compare_digest(expected.encode('ascii'), signature.encode('utf-8')) Keep it working
Launch is the start of the work, not the end. These are the recurring jobs this part of the agent needs, and who usually owns them.
| Cadence | Owner | Work |
|---|---|---|
| Monthly | Engineering | Check credential expiry, permissions and provider API changes. |
| Daily | Engineering | Watch delivery failures, queue age and unprocessed events. Where possible, reconcile gaps against the helpdesk. |
| On change | Engineering | Add a regression test whenever you find a new event type or reply loop. |
| Daily | Engineering | Review failed deliveries and changes to provider formatting. |
Test your decision
The same event is delivered twice. Only one public reply is visible, but two assignment events are recorded. Did the test pass?
Show the expected decision
No. Define every effect the event should have, then check all of them, not just the visible reply. A second delivery must not repeat an assignment, note, tag, business action or metric record.