Based on: A worked playbook on Intercom's conversation webhooks and REST API; the investigation uses whatever read-only tools the machine has.
The situation
A support reply is only as good as the look behind it. The usual first answer, "could you tell us a bit more?", costs the customer a round trip that the logs could have saved. In this playbook, when a customer writes, the skill reads the thread and the contact, then the logs, Sentry and the database (read-only), drafts the reply, and decides: it replies through Intercom when the answer is certain; otherwise it leaves an internal note with what it found and asks a person in the inbox, with the draft as a choice.
How it runs
- Intercom. An app for the workspace with a webhook subscribed to
conversation.user.createdandconversation.user.replied, pointed at the skill's hosted URL. Intercom signs each delivery with the app's client secret:X-Hub-Signature: sha1=…, an HMAC-SHA1 of the body. - The machine. skillhook's generic
hmacscheme verifies it (header, prefix, algorithm and encoding in the frontmatter) with the secret in its.env;whenkeeps the topics to the customer's messages;dedupeon Intercom's notification id means one run per notification, however often it is retried. - The job. It fetches the conversation and the contact through the API rather than trusting the payload, then investigates with whatever read-only tools the machine has: the documentation, the database through a read-only connection string (
SELECTonly), the hosting provider's logs, Sentry through a token or its MCP server. It drafts, then decides. A certain answer is sent as a reply (message_type: comment); anything else becomes an internal note (message_type: note) and a question. - The inbox. The job under the customer's question, the draft and the facts in the question's context, three buttons. The
needs_humanalert goes to the organisation's channels.
Set it up with your agent
Paste this into Claude Code or Codex with the skillhook plugin. It installs skillhook, has you create the Intercom app and store its token, client secret and your admin id in your own terminal, finds the read-only tools the machine has, creates the skill, turns on the hosted URL and walks you through Intercom's webhook page and a test message. Paste the SKILL.md from the next section as your second message.
The skill
Intercom has no preset in skillhook, so the frontmatter spells its scheme out with the generic hmac fields. The body keeps the investigation read-only, names the two Intercom calls it makes, and gives the one question it may ask with its three options. Every frontmatter field is one skillhook validates.
SELECT only, by the customer's own id, and nothing from it reaches the customer but their own account's facts.Where a person comes in
- The question. "Reply to <name> about <topic>?" with the draft and the facts as context, and the choices Send the draft, Edit and Escalate, one recommended. The run waits up to fifteen minutes with its timeout clock paused.
- The answers. Send the draft sends it; Edit sends the text the person typed instead; Escalate assigns the conversation to a person and ends the run saying who has it.
- No answer in time. The run ends with
needs_human, the same question and options as its headline and buttons. The inbox lists it under Needs input, the alert goes out, and the pick resumes the agent's session where it left off. - Already handled. A teammate's reply after the customer's message, or a closed conversation, ends the run with
nothing_to_do; the skill re-reads the thread before every send.
What to check after
- Deliveries. Intercom's "Send test request" as an accepted delivery whose job ends with
nothing_to_do(the example conversation does not exist); a rejected delivery names the reason, which isinvalid_signaturewhen the client secret in.envis not the app's. - The job. The investigation and the draft in its summary, the conversation as its
sourcelink, the Sentry issue aslog, the reply asmessage; the internal note in Intercom is the audit trail on their side. - Replay once a cause is fixed (the token, the connection string, a missing tool):
replay_deliveryruns the notification again; the skill re-reads the thread first and never sends the same reply twice.