Message Formats
Every notification is a Microsoft Teams MessageCard. The format setting decides how much appears in the message line and how much appears in the card.
The module posts the MessageCard schema rather than an Adaptive Card. MessageCard is accepted by both the Teams Workflows trigger and legacy Incoming Webhooks, and it renders without registering a bot or an Azure application. The trade-off is a smaller feature set: no interactive inputs, and no adaptive layout.
Card anatomy
| Element | Source |
|---|---|
title | The notification title, for example Invoice #1042 paid. |
summary | A plain-text version of the message, used by Teams for previews and accessibility. |
text | A short linked title in Message + Card mode, or the full body in Message only mode. |
sections[0].activityTitle | Optional branded name inside the card, from the provider Card Header Name setting. |
sections[0].activityImage | Optional branded icon inside the card, from the provider Card Icon URL setting. |
sections[0].text | The notification message, rendered as Markdown. |
sections[0].facts | The notification attributes, as name/value pairs. |
potentialAction | An OpenUri action named View in WHMCS. |
themeColor | The per-rule accent colour, six hexadecimal digits without #. |
Card branding
Two optional provider settings add a branded header inside the card:
| Setting | Key | What it does |
|---|---|---|
| Card Header Name | cardName | Shown as activityTitle above the message, for example WHMCS Notifications. Maximum 60 characters. |
| Card Icon URL | cardIcon | Shown as activityImage next to the name. Must be a publicly reachable HTTPS image, ideally about 200×200. |
{
"@type": "MessageCard",
"@context": "http://schema.org/extensions",
"themeColor": "2ECC71",
"summary": "Acme Ltd paid $49.00 USD.",
"title": "Invoice #1042 paid",
"sections": [
{
"activityTitle": "WHMCS Notifications",
"activityImage": "https://your-whmcs.com/modules/notifications/MicrosoftTeams/logo.png",
"text": "Acme Ltd paid $49.00 USD.",
"facts": [
{ "name": "Client", "value": "Acme Ltd" },
{ "name": "Total", "value": "$49.00 USD" }
],
"markdown": true
}
]
}
Format comparison
| Format | Message line | Card section | View action |
|---|---|---|---|
both (default) | Linked title | Message + facts | Yes |
message | Full Markdown body | None | Inline link |
card | None | Message + facts | Yes |
Message + Card
The default. The channel preview shows a linked title, and the card carries the message and attributes.
{
"@type": "MessageCard",
"@context": "http://schema.org/extensions",
"themeColor": "0076D7",
"summary": "Acme Ltd paid $49.00 USD.",
"title": "Invoice #1042 paid",
"text": "**[Invoice #1042 paid](https://billing.example.com/admin/invoices.php?id=1042)**",
"sections": [
{
"text": "Acme Ltd paid $49.00 USD.",
"facts": [
{ "name": "Client", "value": "[Acme Ltd](https://billing.example.com/admin/clients.php?id=7)" },
{ "name": "Total", "value": "$49.00 USD" },
{ "name": "Gateway", "value": "Stripe" }
],
"markdown": true
}
],
"potentialAction": [
{
"@type": "OpenUri",
"name": "View in WHMCS",
"targets": [ { "os": "default", "uri": "https://billing.example.com/admin/invoices.php?id=1042" } ]
}
]
}
Message only
A single Markdown body. Use it when the channel should stay compact or when cards are too heavy for the event volume.
{
"@type": "MessageCard",
"@context": "http://schema.org/extensions",
"themeColor": "2ECC71",
"summary": "Acme Ltd paid $49.00 USD.",
"title": "Invoice #1042 paid",
"text": "**[Invoice #1042 paid](https://billing.example.com/admin/invoices.php?id=1042)**\n\nAcme Ltd paid $49.00 USD.\n\n**Client:** [Acme Ltd](https://billing.example.com/admin/clients.php?id=7)\n**Total:** $49.00 USD\n**Gateway:** Stripe\n\n[View in WHMCS](https://billing.example.com/admin/invoices.php?id=1042)"
}
Card only
No separate message line: the card title introduces the notification and the section carries the detail. Useful for dashboards.
{
"@type": "MessageCard",
"@context": "http://schema.org/extensions",
"themeColor": "E74C3C",
"summary": "Service suspended for Acme Ltd.",
"title": "Service suspended",
"sections": [
{
"text": "Service suspended for Acme Ltd.",
"facts": [
{ "name": "Client", "value": "Acme Ltd" },
{ "name": "Product", "value": "Business Hosting" },
{ "name": "Reason", "value": "Overdue invoice" }
],
"markdown": true
}
],
"potentialAction": [
{
"@type": "OpenUri",
"name": "View in WHMCS",
"targets": [ { "os": "default", "uri": "https://billing.example.com/admin/services.php?id=88" } ]
}
]
}
Attributes as facts
- Empty labels and values are dropped, so no dangling separator appears.
- A missing label becomes Details; a missing value becomes an em dash.
- An attribute with a URL becomes a Markdown link in the fact value.
- HTML entities such as
&are decoded before rendering. - At most 15 facts are sent. Extra attributes are summarised as …and N more attributes.
- Fact names are capped at 100 characters and values at 1,000.
Tick Hide Attributes when the event carries sensitive billing detail that should stay in WHMCS.
Theme colour
Enter a three- or six-digit hex value, with or without #. The module expands three-digit values and sends six uppercase digits without the hash, which is what Teams expects.
| Entered | Sent |
|---|---|
#0076D7 | 0076D7 |
b40135 | B40135 |
#abc | AABBCC |
| blank | 0076D7 |
tomato | Rejected with an actionable error |
Size and truncation
- Teams accepts a card payload of roughly 28 KB. The module targets 28,000 bytes to leave room for encoding.
- Messages are truncated at 6,000 characters, closing an unterminated code fence and appending an ellipsis.
- If the encoded card is still too large, facts are removed from the end, then message text is shortened, then the summary is shortened.
- If nothing can be removed safely, the notification fails with a clear error instead of sending a broken card.
- The card title is capped at 255 characters and the summary at 255.
Mentions and formatting
- MessageCard supports basic Markdown: bold, italic, strike-through, links, headings and lists.
- HTML is not rendered. Tags are stripped and entities decoded before the payload is built.
@everyone,@here,@channeland@onlineare rewritten with a zero-width space so a client name cannot ping a channel.- New lines in the WHMCS message are preserved; runs of three or more blank lines collapse to one blank line.
Legacy format values
Rules created by another provider or an older build are tolerated. markdown is read as message, embed is read as card, and any unknown value falls back to both. No rule breaks because of a format value.