# How to Send Help Scout New-Conversation Alerts to a Shared Room

> Verify one Help Scout conversation-created webhook and send fixed shared-phone copy without forwarding customer or ticket content.

- Published: 2026-11-07
- Author: PingRoom
- Category: Automation
- Topics: Help Scout new conversation notifications, Help Scout webhook push notifications, convo.created alerts, shared support phone alerts
- Canonical: https://pingroom.io/blog/helpscout-new-conversation-push-notifications
- Cover image: https://pingroom.io/blog/helpscout-new-conversation-push-notifications-cover.webp
- Cover description: Two PingRoom avatars keep a wooden conversation ledger closed while Pingo watches one blank signal token reach a shared tray.

**To send a Help Scout new-conversation alert to a shared group of phones, create a mailbox-filtered `convo.created` webhook with Help Scout's notification-only payload, verify its raw-body signature in a small relay, and send fixed copy to a PingRoom incoming webhook.** Help Scout remains the support record; the Room receives only a prompt to look there.

This is a webhook recipe you configure, not a native Help Scout integration. The destination Room's owner needs PingRoom Pro. You also need Help Scout API access, permission to create a webhook, and a server-side relay with durable duplicate storage.

## Start with Help Scout's own notifications

Help Scout already lets each user choose [in-app, email, browser, and mobile notifications](https://docs.helpscout.com/article/696-manage-help-scout-notifications) by Inbox. Use those first when everyone who needs the update is an appropriate Help Scout user.

| What people need                                                 | Better starting point                                     |
| ---------------------------------------------------------------- | --------------------------------------------------------- |
| The subject, customer, assignment, replies, or full conversation | Help Scout                                                |
| Ordinary updates for Help Scout users                            | Help Scout's native notifications                         |
| One fixed signal for a small, stable group                       | Signed Help Scout webhook → relay → private PingRoom Room |
| Assignment, SLA tracking, escalation, or on-call paging          | Your approved support and incident system                 |

The Room is an attention path, not another ticket queue. A Ping does not assign the conversation, prove that somebody opened it, start an SLA, or confirm a reply.

## Use Help Scout's smallest webhook body

Help Scout's normal conversation webhook contains customer, subject, preview, mailbox, owner, and other support fields. This alert does not need any of them.

The [Create Webhook endpoint](https://developer.helpscout.com/mailbox-api/endpoints/webhooks/create/) supports `notification: true`. For a conversation event, that sends only:

```json
{
  "resource_url": "https://api.helpscout.net/v2/conversations/3443157477",
  "event_type": "convo.created"
}
```

The relay extracts the numeric conversation identity from that exact URL but never fetches the resource. Customer content therefore stays in Help Scout by design, not because the relay receives it and promises to ignore it.

## Prepare one private Room and one Inbox

Create or choose a private PingRoom Room for the small group that needs this signal. Open **Settings → Connections → From another app**, add an incoming webhook named **Help Scout**, keep **Quick Ping** on **Custom message**, save it, and store the complete secret URL as `PINGROOM_WEBHOOK_URL` in your relay's secret store.

The [incoming-webhook guide](/blog/webhook-to-push-notification) covers the Room-side setup. The [webhook reference](/documents/webhooks) documents the accepted fields, idempotency behavior, cooldown, and errors. The full URL is a credential; never put it in Help Scout fields, browser code, source control, screenshots, or logs.

For the Help Scout side, record the numeric ID of exactly one Inbox. Create a random webhook signing secret no longer than 40 characters and store the same value as `HELPSCOUT_WEBHOOK_SECRET` in the relay.

## Create a notification-only Help Scout webhook

Help Scout says webhooks and API access are available on paid plans. Use an OAuth access token with the required API permission only for setup; the relay below does not need that token because it never fetches the conversation.

This illustrative request creates one `convo.created` subscription for one Inbox. Replace the placeholders in a protected environment, not in shared shell history:

```bash
curl --request POST "https://api.helpscout.net/v2/webhooks" \
  --header "Authorization: Bearer $HELPSCOUT_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data "{
    \"url\": \"$RELAY_URL\",
    \"events\": [\"convo.created\"],
    \"secret\": \"$HELPSCOUT_WEBHOOK_SECRET\",
    \"payloadVersion\": \"V3\",
    \"notification\": true,
    \"mailboxIds\": [$HELPSCOUT_MAILBOX_ID],
    \"label\": \"PingRoom new-conversation signal\"
  }"
```

The Inbox filter belongs in the subscription. The notification body contains no mailbox field, so the relay cannot rediscover that scope later. Review the stored webhook after creation and confirm its event, Inbox, notification flag, destination, and enabled state.

## Verify before parsing

Help Scout sends the event name in `X-HelpScout-Event` and a Base64 HMAC-SHA1 digest in `X-HelpScout-Signature`. Calculate the digest over the untouched request body and compare it in constant time before parsing JSON.

```js
import { createHash, createHmac, timingSafeEqual } from "node:crypto";

function validHelpScoutSignature(rawBody, supplied, secret) {
  if (!/^[A-Za-z0-9+/]{27}=$/.test(supplied ?? "")) return false;
  const actual = Buffer.from(supplied, "base64");
  if (actual.length !== 20) return false;
  const expected = createHmac("sha1", secret).update(rawBody).digest();
  return timingSafeEqual(expected, actual);
}
```

After the signature passes, require all four of these conditions:

1. The header event is exactly `convo.created`.
2. The body event is exactly `convo.created`.
3. The body has only `event_type` and `resource_url`.
4. The resource URL exactly matches `https://api.helpscout.net/v2/conversations/<positive integer>` with no query string.

Help Scout's signature has no timestamp in the documented format, so do not claim a freshness check. An exact replay of a valid request should resolve to the same event key and create no second Ping.

## Queue fixed copy before acknowledging Help Scout

Hash the extracted conversation ID into one stable key so the destination does not receive the raw Help Scout identifier:

```js
const eventKey = `helpscout-conversation:${createHash("sha256")
  .update(conversationId)
  .digest("hex")}`;
```

Insert that key into an atomic, durable queue before returning a `2xx` response to Help Scout. An in-memory `Set` is useful for a local fixture but is not durable enough for production.

The worker sends fixed copy and reuses the same key for PingRoom idempotency:

```js
await fetch(process.env.PINGROOM_WEBHOOK_URL, {
  method: "POST",
  redirect: "manual",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": eventKey,
  },
  body: JSON.stringify({
    action: null,
    title: "New Help Scout conversation",
    message: "One new conversation is waiting in Help Scout.",
    correlation_id: eventKey,
  }),
});
```

The title and message contain no customer name, email, subject, preview, conversation number, mailbox name, assignee, tag, URL, or reply text. People open Help Scout through their normal authorized route to see the record.

![Two PingRoom avatars test a small brass verification gate while Pingo watches one sealed blank token pass and an identical replay wait behind a wooden stop.](/blog/helpscout-new-conversation-push-notifications-1.webp)

[Pingo the Pigeon](/Pingo), PingRoom's fictional Chief Marketing Officer, appears beside the miniature gate. His contribution is a long look at the stopped replay. He cannot inspect Help Scout, enter a private Room, or send the Ping; people choose the Inbox, recipients, copy, and response process.

## Rehearse the privacy and retry boundaries

Use a disposable Help Scout Inbox, a private test Room, and non-sensitive sample conversations. This is an illustrative rehearsal, not a delivery guarantee.

1. A correctly signed `convo.created` notification for the selected Inbox queues one job.
2. Replaying that exact request queues no second job and produces no second Ping.
3. A different conversation resource produces a different event key.
4. An invalid signature is rejected before the body is trusted.
5. A different header event or body event creates no Ping.
6. A customer resource, foreign host, zero ID, query string, malformed JSON, extra field, wrong content type, or oversized body is rejected.
7. The queue job contains only the event key, not the raw body or resource URL.
8. The worker sends only fixed copy and the event key. A PingRoom redirect, throttle, or other non-success remains a retryable queue failure.
9. A locked test phone shows no customer, subject, preview, mailbox, assignment, conversation number, or URL.

Our recorded dependency-free fixture passed 22 boundaries with signed Help Scout notification payloads, an in-memory queue stand-in, and a local mock of PingRoom's documented contract. It did not use a live Help Scout account, public relay, PingRoom Room, customer conversation, or phone.

## Read success and failure correctly

Help Scout treats any `200`–`299` response as success. Its webhook documentation says a failed event is retried up to ten times with increasing delays, then discarded; repeated discarded events can deactivate the webhook. Queue durably before acknowledging, monitor the subscription, and keep Help Scout's Inbox authoritative.

PingRoom HTTP `200` with `success: true` means the request was accepted and created or replayed the Ping for that key. It does not prove every phone displayed an alert. Connectivity, notification permission, Focus modes, battery settings, and Room preferences still affect presentation.

PingRoom incoming webhooks accept one new Ping every five seconds by default. If the Inbox receives bursts, a shared interrupt for every conversation is the wrong shape. Keep Help Scout's native queue and notifications, or add an approved aggregation step before PingRoom.

When one fixed shared signal is genuinely useful, [create the private destination Room](/app/rooms), test one disposable conversation, and leave the customer record in Help Scout. For a custom-header support workflow instead, see the [Freshdesk urgent-ticket recipe](/blog/freshdesk-urgent-ticket-push-notifications).

_The illustrations are AI-generated editorial scenes featuring Pingo the Pigeon, PingRoom's official mascot and fictional Chief Marketing Officer, and approved PingRoom avatars. The people and scenario are illustrative, not customers or product screens; the human team remains responsible for product claims and decisions._

## Sources

- [Manage Help Scout notifications — Help Scout Support](https://docs.helpscout.com/article/696-manage-help-scout-notifications)
- [Mobile notifications — Help Scout Support](https://docs.helpscout.com/article/1176-mobile-notifications)
- [Webhooks — Help Scout Developers](https://developer.helpscout.com/webhooks/)
- [Create Webhook — Help Scout Developers](https://developer.helpscout.com/mailbox-api/endpoints/webhooks/create/)
- [Webhooks — PingRoom](https://pingroom.io/documents/webhooks)
