Gabbex

Webhook bots

A webhook bot posts into a room whenever something sends it an HTTP request. Use it for deploy notices, build results, alerts, form submissions, or anything else that can call a URL.

Set one up

  1. Open a room you created. Only a room's creator can add bots to it.
  2. Tap the room name at the top, then Bots.
  3. Under Available, find Webhook and tap Install.
  4. The bot joins the room and its webhook URL appears. Copy it.

The bot shows in the member list with a small robot mark and posts under its own name and photo. Change its name with the gear icon on the Bots page; add a photo from Profile โ†’ Bots.

Your webhook URL

Each room a bot is in gets its own URL. It looks like this:

https://<your-gabbex-api>/api/hooks/<install-id>/<token>

The URL is the password. There is no other sign-in: anyone who has it can post into the room as the bot. Keep it in a secret store (GitHub Actions secrets, your CI's protected variables, an environment variable), not in code you commit.

You can see and copy the current URL any time from the bot's settings (gear icon on the room's Bots page). If it leaks, tap Make a new URL: the old one stops working immediately.

Send a message

Send a POST request with a JSON body. The simplest body has one field:

{
  "text": "Deploy finished for v2.4.1 ๐Ÿš€"
}
FieldTypeDetails
textstringThe message to post, up to 2,000 characters after trimming spaces. Line breaks are kept. If text is present it always wins over a template.

Templates

Many services (GitHub, monitoring tools, form builders) send their own JSON and can't be told to send text. For those, set a template in the bot's settings. When a request has no text field, the bot fills the template from the request's JSON and posts the result.

Placeholders are field names in double braces. Use dots to reach into nested objects:

Template:  Deploy {{status}} on {{build.branch}} by {{build.author.name}}

Request:   {
             "status": "succeeded",
             "build": { "branch": "main", "author": { "name": "ana" } }
           }

Posts:     Deploy succeeded on main by ana
Value in the JSONWhat the placeholder becomes
StringThe text as is.
Number or true/falseAs written in the JSON, e.g. 42, 3.5, true.
Missing, null, object or arrayNothing (an empty string).

Responses

Every response is JSON. Errors carry a message explaining what went wrong.

StatusBodyMeaning
200{ "ok": true }Posted.
400{ "message": "โ€ฆ" }The body isn't JSON, is over 64 KB, text is over 2,000 characters, the message came out empty, or there's no text and no template is set.
403{ "message": "This bot is disabled." }The bot is switched off in this room.
404{ "message": "Not found." }The URL is wrong, was replaced with a new one, or the bot was removed from the room.
429{ "message": "โ€ฆ" }Too many requests. Wait the number of seconds in the Retry-After header, then try again.

Only retry on 429 and on network errors or 5xx. A 400, 403 or 404 won't succeed on a retry; fix the request or the URL first.

Limits

If you expect bursts (for example a big CI matrix), combine results into one message instead of posting each one.

Examples

In each example, $GABBEX_WEBHOOK_URL holds the URL you copied.

curl

curl -X POST "$GABBEX_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{"text": "Backup completed in 4m 12s"}'

JavaScript (Node 18+ or the browser)

const res = await fetch(process.env.GABBEX_WEBHOOK_URL, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ text: 'New signup: @ana just joined ๐ŸŽ‰' }),
});
if (!res.ok) console.error(res.status, await res.json());

Python

import os, requests

res = requests.post(
    os.environ["GABBEX_WEBHOOK_URL"],
    json={"text": "Nightly report is ready"},
    timeout=10,
)
res.raise_for_status()

GitHub Actions

Save the URL as a repository secret named GABBEX_WEBHOOK_URL, then add a step:

- name: Tell the room
  if: always()
  run: |
    curl -sS -X POST "$URL" \
      -H "Content-Type: application/json" \
      -d "{\"text\": \"${{ github.repository }} ${{ github.ref_name }}: ${{ job.status }}\"}"
  env:
    URL: ${{ secrets.GABBEX_WEBHOOK_URL }}

GitHub repository webhooks (with a template)

GitHub sends its own JSON, so use a template. In the bot's settings set the template to:

{{pusher.name}} pushed to {{repository.full_name}}: {{head_commit.message}}

Then in GitHub open Settings โ†’ Webhooks โ†’ Add webhook, paste the URL as the payload URL, choose application/json, and select Just the push event. Each push posts a line such as ana pushed to acme/site: Fix the header on mobile.

Monitoring and alerts

Most uptime tools let you edit the JSON they send. Point them at the URL and send a text field:

{
  "text": "๐Ÿ”ด api.acme.com is down (HTTP 503) โ€” @oncall please look"
}

Manage the bot

Open the room, tap the room name, then Bots. Each installed bot has:

Renaming a bot updates it everywhere it posts, and the room sees a "now known as" line, like a nickname change.

Troubleshooting