How to Send New Intercom Conversation Alerts to a Shared Room
Verify one Intercom conversation-created webhook, discard customer content, and queue a fixed, replay-safe signal for a shared PingRoom Room.

To send a new Intercom conversation alert to a shared group of phones, subscribe a private Intercom app to conversation.user.created, verify the signed raw request in a small relay, and queue one fixed Ping to a private PingRoom Room. Keep Intercom's Inbox and mobile app as the support workspace. The shared Ping should say only that a conversation is waiting—not who wrote it or what they said.
This is a webhook recipe, not a native Intercom integration. The destination Room's owner needs PingRoom Pro. You also need an Intercom paid or development workspace, access to Developer Hub, and a server-side relay with durable duplicate storage.
Use Intercom mobile push first
Intercom's mobile app already lets teammates receive notifications, open assigned or unassigned inboxes, reply, add notes, assign conversations, snooze them, and close them. If everyone who needs the alert is an Intercom teammate, start with the Intercom mobile app.
| What the team needs | Better starting point |
|---|---|
| Customer message, history, assignment, reply, or teammate notes | Intercom Inbox |
| Normal phone alerts for Intercom teammates | Intercom mobile push |
| One terse signal for a stable shared group | Intercom webhook → verified relay → PingRoom Room |
| Paging, escalation, or an SLA workflow | Your approved support or on-call system |
PingRoom carries an attention signal, not the conversation. This recipe never copies the contact name, email, subject, message, conversation ID, assignment, URL, or other support detail into the Room.
Fix the message before connecting anything
The Room receives the same copy for every accepted event:
New Intercom conversation
One new customer conversation is waiting in Intercom.
That message tells the group where to look. It does not assign the conversation, identify its owner, prove that someone replied, start an escalation, or say that every phone displayed the Ping.
Create the private Room and incoming webhook
Create a private Room for the stable group that needs the signal. In the PingRoom browser app, open Settings → Connections → From another app, add an incoming webhook, and store the complete secret URL as PINGROOM_WEBHOOK_URL in your relay's secret store.
The incoming-webhook walkthrough covers the Room setup. The webhook reference documents request fields, idempotency, cooldowns, and errors. Treat the complete PingRoom URL as a credential; never put it in Intercom data, client code, or logs.
Intercom sends to the relay, not directly to PingRoom. The relay is where you verify Intercom, reject unrelated events, remove the conversation object, and queue one stable signal.
Store these values server-side:
INTERCOM_APP_ID: the app ID that owns this subscription;INTERCOM_CLIENT_SECRET: the app's client secret used to verify the signature;PINGROOM_WEBHOOK_URL: the complete secret PingRoom incoming-webhook URL.
Subscribe to the contact-created conversation topic
In Intercom's Developer Hub, create or open the app for this workspace. Give it the Read conversations permission, add your relay's public HTTPS endpoint, and subscribe to conversation.user.created.
Intercom documents this as the event fired when a contact starts a conversation. Keep the subscription that narrow. An admin reply, assignment change, close, or reopen is a different event and should not wake this Room.
The current Intercom webhook overview describes the app and workspace setup. Its webhook topic reference documents the topic, notification envelope, signature, timeout, and retry behavior.
Verify the raw body before parsing JSON
Intercom signs the exact request body in X-Hub-Signature using HMAC-SHA1 and the app client secret. The header is shaped like sha1=<hex>. Read the raw bytes once, enforce a size limit, calculate the expected digest, and compare the two byte sequences in constant time before trusting the JSON.
import { createHmac, timingSafeEqual } from "node:crypto"; function validSignature(rawBody, supplied, secret) { if (!secret || !supplied?.startsWith("sha1=")) return false; const suppliedHex = supplied.slice(5); if (!/^[a-f0-9]{40}$/i.test(suppliedHex)) return false; const expected = createHmac("sha1", secret).update(rawBody).digest(); return timingSafeEqual(expected, Buffer.from(suppliedHex, "hex")); }
Do not parse and reserialize the body before checking the signature. Even harmless whitespace changes produce a different digest.
After verification, require all four boundaries:
app_idequals your configured Intercom app ID.topicequalsconversation.user.created.typeequalsnotification_event.data.item.typeequalsconversation.
The payload contains a full conversation object because Intercom expects the receiver to use it. This relay deliberately does not. It reads only the envelope fields needed for selection and replay identity, then discards the original body.

Pingo the Pigeon, PingRoom's fictional Chief Marketing Officer, is studying the stopped duplicate. He cannot inspect an Intercom conversation, access a private Room, or send a Ping; the human team chose the boundary and the relay enforces it.
Queue before Intercom's five-second deadline
Intercom says a webhook endpoint has five seconds to respond. Do not wait for PingRoom delivery inside that request. Derive a stable key from the Intercom notification ID and app ID, insert it into durable duplicate storage, enqueue a job containing only that key, then return 202.
import { createHash } from "node:crypto"; function eventKey({ appId, notificationId }) { const source = `${appId}:${notificationId}`; return `intercom-conversation:${createHash("sha256").update(source).digest("hex")}`; } await queue.enqueueOnce(key, { eventKey: key }); return new Response(null, { status: 202 });
The queue's uniqueness rule must be durable and atomic. An in-memory set is useful for a test, not for production. Queue only the derived key—never the conversation or contact object.
Intercom warns that webhook events can be duplicated, retried, or delivered out of order. Its current reference also says a failed request gets only a limited retry. The endpoint therefore needs replay safety, but this route is still a best-effort attention cue rather than an exactly-once system.
Send one fixed Ping from the worker
The worker reuses the same stable key as PingRoom's Idempotency-Key and correlation_id:
await fetch(env.PINGROOM_WEBHOOK_URL, { method: "POST", redirect: "manual", headers: { "Content-Type": "application/json", "Idempotency-Key": job.eventKey, }, body: JSON.stringify({ action: null, title: "New Intercom conversation", message: "One new customer conversation is waiting in Intercom.", correlation_id: job.eventKey, }), });
Treat redirects, throttles, and every other non-success response as a queue failure. Retry the identical request with the identical key. Never create a fresh key for a retry.
Rehearse with a disposable conversation
Before connecting normal support work, use a test workspace or a harmless disposable conversation and a test Room:
- A correctly signed event from the expected app, topic, notification type, and conversation object queues one job.
- Replaying the same notification queues no second job.
- A missing, malformed, or incorrect signature is rejected before JSON is trusted.
- Another app, topic, notification type, or item type creates no Ping.
- A malformed notification ID, malformed JSON, oversized body, or wrong content type is rejected.
- The queue job contains only the derived event key.
- The PingRoom request contains only the fixed title, message, and derived key.
- A redirect, throttle, or other non-success remains a retryable queue failure.
- A locked test phone reveals no contact, subject, message, conversation ID, assignment, or URL.
For this article, the dependency-free relay passed 15 controlled boundaries with Intercom-shaped signed requests, a test client secret, an idempotent in-memory queue, and a local mock of PingRoom's documented incoming-webhook contract. One unique mock signal was queued and delivered, and the mock verified that conversation fields did not reach PingRoom. No live Intercom workspace, public relay, PingRoom Room, phone, or customer data was used.
Keep Intercom authoritative
This Room is not a second Inbox. A Ping does not assign the conversation, confirm ownership, preserve message history, prove a reply, enforce an SLA, or guarantee display. Device permissions, connectivity, Focus modes, Room settings, and operating-system behavior can affect what a recipient sees.
Use Intercom for conversation state, teammate work, history, and customer communication. Use an approved paging system for emergency escalation. Use PingRoom only when one newly started conversation deserves a separate, privacy-minimal signal for a stable group.
If that boundary fits your team, create the private Room, deploy the relay with durable duplicate storage, and test one disposable conversation before enabling the production subscription.
Intercom is a trademark of Intercom, Inc. PingRoom is not affiliated with or endorsed by Intercom.
PingRoom
Short-form communication.


