Subscribe to message_posted; format and forward to a Slack incoming-webhook.
Drive the chat from your code.
Pre-authenticate visitors so contacts are known, open and close the widget on demand, and stream support events to your stack — all from your existing JavaScript and server.
Install
Paste this once in your site's <head>. Everything else is optional.
<!-- Paste once, just before </head> --> <script async src="https://your-helpbird-host/api/embed?id=YOUR_PROJECT_ID"></script>
Replace YOUR_PROJECT_ID with your own project ID from Admin → Install. The async loader injects the chat button and iframe (it never blocks your page) and exposes a global window.HelpBird object. If the project is inactive or the widget is hidden, the script is an empty no-op — a stale tag never breaks the host page.
HelpBird.identify()
Tell the widget who the visitor is so the conversation lands on a known contact — the email matches or creates the contact and attaches their cross-conversation history.
Signature
HelpBird.identify(user_id, email, name, hmac?)
Parameters
user_id— your own identifier for the visitor. optionalemail— used to match or create the contact and build their history. requiredname— display name shown to your agents. optionalhmac— server-signed digest for verified identity. optional
Safe to call any time after the loader has run — the widget picks it up even if the visitor hasn't opened the chat yet.
<script>
// Any time after the loader has run:
HelpBird.identify(
"your-internal-user-42", // user_id (your own identifier)
"jane@acme.com", // email — matches/creates the contact
"Jane Doe", // display name shown to agents
"<hmac from your server>" // optional — verified identity
);
</script>open() & close()
Show or hide the chat widget from your own UI — wire it to a "Contact support" button, a help menu, or an exit-intent flow.
Methods
HelpBird.open()— open the widget panel.HelpBird.close()— collapse the widget back to the launcher.
Both are safe to call any time after the loader has run.
<button onclick="HelpBird.open()">Contact support</button>
Verified identity
Pre-authenticate your visitors with your existing login system. Sign the visitor's identifier server-side with your project's identity secret, pass the digest to identify, and the contact arrives already known — with a verified badge your agents can trust.
How it works
- The digest is
HMAC-SHA256(secret, identifier), hex-encoded. The identifier is theuser_idyou pass toidentify(), or the email if you don't pass one. - The secret is your project's identity-verification secret (Admin → Settings). Keep it server-side — never ship it in page JavaScript.
- On a valid signature the conversation is marked verified, so agents know exactly who they're helping.
Why use it
- Visitors never re-type their name or email — the contact is known from the first message.
- Identity is verified, so an impostor can't claim someone else's email.
- Conversation history attaches to the right contact every time.
// Sign once per page load, server-side.
import { createHmac } from "node:crypto";
// Identifier: your user_id if you pass one to identify(), else the email.
const hmac = createHmac("sha256", process.env.HELPBIRD_IDENTITY_SECRET)
.update(String(user.id))
.digest("hex");
// Render it into the page, then:
// HelpBird.identify(String(user.id), user.email, user.fullName, hmac);Webhooks
Subscribe to support events from outside the browser — Slack notifications, CRM sync, Zapier flows, custom analytics, anything. We POST a signed JSON payload; you verify the signature and process.
Configure
Admin → Integrations → Webhooks. Add a URL, pick events, and keep the shared secret somewhere safe — it signs every delivery.
Events
message_posted— a new message from a visitor or an agent.mention_received— a teammate is @mentioned in a conversation.message_pinned— a message is pinned in a conversation.
Headers
Content-Type: application/jsonX-Helpbird-Event— the event name (matches the body'seventfield).X-Helpbird-Signature— hex-encoded HMAC-SHA256 over the raw request body, keyed with your shared secret.
Behavior
- Best-effort delivery. We don't queue or retry — design your receiver to be idempotent.
- 6-second timeout per delivery. Slow receivers are recorded as failed and we move on.
- The last HTTP status and error per endpoint are visible in the admin panel.
Payload
{
"event": "message_posted",
"project_id": 123,
"data": {
"room_id": 12345,
"message_id": 67890,
"from": "contact",
"contact": { "name": "Jane Doe", "email": "jane@acme.com" },
"text": "Hi, my order shipped to the wrong address."
}
}Verifying the signature
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(rawBody: Buffer, headerSig: string, secret: string): boolean {
const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
return (
expected.length === headerSig.length &&
timingSafeEqual(Buffer.from(expected), Buffer.from(headerSig))
);
}Common patterns
On message_posted, upsert the contact into your CRM — the email makes a clean key.
On mention_received, page the on-call lead so an at-risk conversation gets picked up fast.