Message Formats
Stoat renders Markdown on the client. The module builds that Markdown, or an embed, or both.
The three formats
| Format | Message body | Embed | Best for |
|---|---|---|---|
Message + Embedboth |
Linked notification title | Title, full message, attributes and link | Default. Rich card with a readable push preview. |
Message onlymarkdown |
Title, message, attributes and a view link | None | Channels without SendEmbeds, or a compact audit feed. |
Embed onlyembed |
Empty | Everything | A quiet feed where the card should carry all detail. |
Markdown message
A “Message only” notification is assembled in this order:
**[Invoice #1042 paid](https://billing.example.com/admin/invoices.php?id=1042)**
A payment of $49.00 has been received.
**Client:** [Jane Doe](https://billing.example.com/admin/clients.php?id=7)
**Invoice:** #1042
**Total:** $49.00
[View in WHMCS](https://billing.example.com/admin/invoices.php?id=1042)
If the notification has no URL the title is sent as bold text instead of a link. If it has no attributes, that block is omitted.
Supported Markdown
- Bold, italic and strikethrough
- Inline code and fenced code blocks
- Links
- Quotes and headings
- Lists
Stoat renders these in the client. The webhook transports the raw text, so a client that does not render a construct will show it literally rather than dropping content.
Message + Embed
The default format sends a short linked title as the message body and the detail as an embed. This keeps the push preview meaningful while the card carries the substance.
{
"content": "**[Invoice #1042 paid](https://billing.example.com/...)**",
"embeds": [
{
"title": "Invoice #1042 paid",
"description": "A payment of $49.00 has been received.\n\n**Client:** Jane Doe\n**Invoice:** #1042\n**Total:** $49.00",
"url": "https://billing.example.com/...",
"colour": "#2ecc71"
}
],
"masquerade": { "name": "WHMCS" }
}
Embed fields
Stoat embeds are deliberately small. Only these properties are sent:
| Property | Source | Limit |
|---|---|---|
title | Notification title | 100 characters |
description | Message plus attribute lines | 2,000 characters |
url | Notification URL, only if 256 characters or fewer | 256 characters |
colour | Rule Embed Colour | 128 characters, CSS colour grammar |
There is no fields[], no timestamp and no numeric color. Those belong to other chat platforms; Stoat rejects or ignores them, so the module never sends them.
Attributes
WHMCS supplies attributes such as Client, Invoice, Total, Department or Priority. Each becomes a Markdown line:
**Client:** Jane Doe
**Invoice:** #1042
**Total:** $49.00
- If an attribute has a URL, the value becomes a Markdown link.
- Only
httpandhttpsURLs are linked; anything else is sent as text. - Labels and values are collapsed to a single line so a multi-line address cannot break the layout.
- At most 15 attributes are rendered; the rest are summarised as “…and N more”.
- Attributes Inline joins them with dots instead of line breaks.
Limits and truncation
| Value | Limit | Behaviour |
|---|---|---|
| Message content | 2,000 | Truncated to 1,998 characters with an ellipsis |
| Embed description | 2,000 | Truncated the same way |
| Embed title | 100 | Truncated with an ellipsis |
| Masquerade name | 32 | Truncated with an ellipsis |
| Embed URL / avatar URL | 256 | Omitted if longer; the content link is still sent |
Truncation is Markdown-aware: if the cut lands inside a fenced code block, the module appends a closing fence so the rest of the message cannot be swallowed by an unclosed block.
Embed colours
Stoat accepts CSS colours. Valid examples:
| Input | Result |
|---|---|
#2ecc71 | Hex colour |
rgb(46, 204, 113) | RGB function |
rgba(46, 204, 113, 1) | RGBA function |
red | Named colour |
5793266 | Legacy decimal, converted to #5865f2 |
linear-gradient(90deg, #2ecc71, #5865f2) | Gradient |
Anything outside the grammar is rejected before a request is made, with an error naming the value.
Mentions
Notification text can include user-supplied values such as a ticket subject. To stop a subject like @everyone please read from pinging the server, @everyone, @here and @online are neutralised with a zero-width space before sending. The words remain readable; the mention does not trigger.
Sender identity
- Sender Name sets the masquerade name, for example
WHMCS. - Sender Avatar URL sets the masquerade avatar.
- Both require the webhook’s
Masqueradepermission. - Clear the name to post as the webhook’s own identity and avoid the permission entirely.