Skip to main content

Message Templates

Message templates control how events are formatted before delivery. Templates support three output formats: Discord embeds, Slack Block Kit messages, and Telegram HTML.

Template Formats

Templates support two config versions:

v1 — Flat (single platform)

A single TemplateConfig object that applies to all platforms. This is the simpler format and is still fully supported:

{
"title": "{{.Meta.EventType}}",
"description": "New event from {{.Body.repository.full_name}}",
"color": 16750848,
"fields": [
{
"name": "Action",
"value": "{{.Body.action}}",
"inline": true
}
],
"footer": "Dispatch",
"thumbnail": "{{.Body.sender.avatar_url}}",
"author": "{{.Body.sender.login}}",
"timestamp": true
}

v2 — Multi-platform

A PlatformTemplateConfig envelope with per-platform variants. Dispatch selects the platform matching the destination type, falling back to default if no specific variant is configured:

{
"version": 2,
"platforms": {
"discord": {
"title": "{{.Meta.EventType}}",
"description": "{{.Body.repository.full_name}}",
"color": 5763719,
"fields": [
{ "name": "Action", "value": "{{.Body.action}}", "inline": true }
],
"timestamp": true
},
"slack": {
"slack_blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*{{.Meta.EventType}}* — {{.Body.repository.full_name}}"
}
}
]
},
"telegram": {
"telegram_html": "<b>{{.Meta.EventType}}</b>\n{{.Body.repository.full_name}}\n\nAction: <code>{{.Body.action}}</code>"
},
"default": {
"title": "{{.Meta.EventType}}",
"description": "{{.Body.repository.full_name}}",
"timestamp": true
}
}
}

Discord Embed Config

The Discord platform config (or v1 flat config) renders a Discord embed:

Fields

FieldTypeDescription
titlestringEmbed title (max 256 chars). Supports template syntax.
descriptionstringMain content (max 4096 chars, supports markdown). Supports template syntax.
colorintegerDecimal color code (e.g., 16711680 for red, 65280 for green)
fieldsarrayUp to 25 embed fields
footerstringFooter text. Supports template syntax.
thumbnailstringURL for thumbnail image. Supports template syntax.
authorstringAuthor name. Supports template syntax.
timestampbooleanWhether to include an ISO 8601 timestamp

Embed Fields

Each field in the fields array has:

FieldTypeDescription
namestringField label (max 256 chars). Supports template syntax.
valuestringField content (max 1024 chars). Supports template syntax.
inlinebooleanWhether to display inline (side-by-side with other inline fields)

Slack Block Kit Config

For Slack destinations, set a slack_blocks array in the platform config. This renders natively as a Slack Block Kit message. All string values inside the blocks support template expressions:

{
"slack_blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "{{upper .Meta.EventType}}"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Repository*\n{{.Body.repository.full_name}}"
},
{
"type": "mrkdwn",
"text": "*Action*\n{{.Body.action}}"
}
]
},
{
"type": "divider"
}
]
}

If slack_blocks is not set, the Discord embed fields are auto-converted to a Slack attachment format.

Telegram HTML Config

For Telegram destinations, set a telegram_html field in the platform config. This string supports template expressions and is sent as HTML. Supported HTML tags:

TagEffect
<b> / <strong>Bold
<i> / <em>Italic
<u> / <ins>Underline
<s> / <strike> / <del>Strikethrough
<code>Inline code
<pre>Code block
<blockquote>Block quote
<a href="url">Hyperlink
<tg-spoiler>Hidden spoiler
{
"telegram_html": "<b>{{upper .Meta.EventType}}</b> on <code>{{.Body.repository.full_name}}</code>\n\n{{.Body.pull_request.title}}\n\nOpened by: {{.Body.sender.login}}"
}

If telegram_html is not set, Dispatch auto-converts the Discord embed fields to Telegram HTML.

Template Variables

All template fields have access to two objects:

.Body

The full event payload as a nested map. Access any field using dot notation:

{{.Body.action}}
{{.Body.repository.full_name}}
{{.Body.pull_request.title}}
{{.Body.commits[0].message}}

.Meta

Event metadata:

VariableDescription
{{.Meta.EventType}}The extracted event type (e.g., push, pull_request)
{{.Meta.EventID}}The unique event ID (UUID)
{{.Meta.EndpointID}}The endpoint that received the event
{{.Meta.Timestamp}}ISO 8601 timestamp of when the event was received

Template Functions

The following functions are available in template expressions:

FunctionDescriptionExample
upperConvert to uppercase{{upper .Body.action}}
lowerConvert to lowercase{{lower .Body.action}}
defaultFallback value if empty{{default .Body.name "Unknown"}}
truncateTruncate to N characters{{truncate .Body.description 100}}
jsonFormat value as JSON{{json .Body.commits}}
ansiGrayDiscord ANSI gray color{{ansiGray "text"}}
ansiRedDiscord ANSI red color{{ansiRed "error"}}
ansiGreenDiscord ANSI green color{{ansiGreen "success"}}
ansiYellowDiscord ANSI yellow color{{ansiYellow "warning"}}
ansiBlueDiscord ANSI blue color{{ansiBlue "info"}}
ansiPinkDiscord ANSI pink color{{ansiPink "text"}}
ansiCyanDiscord ANSI cyan color{{ansiCyan "text"}}
ansiWhiteDiscord ANSI white color{{ansiWhite "text"}}
ansiBoldDiscord ANSI bold{{ansiBold "text"}}
ansiUnderlineDiscord ANSI underline{{ansiUnderline "text"}}
note

ANSI color functions are only meaningful inside Discord code block descriptions (```ansi ```). They have no effect in Slack or Telegram output.

Auto-Formatting

When no template is assigned to an endpoint-destination link, Dispatch uses auto-detection based on the event payload to generate an appropriate embed.

GitHub Events

If the payload contains repository and sender fields, Dispatch generates a specialized embed based on the event type:

  • push — commit summary with author, branch, and commit messages
  • pull_request — PR title, description, status, and labels
  • issues — issue title, body, assignees, and labels
  • release — release name, tag, and description
  • workflow_run — workflow name, status, and conclusion
  • And more GitHub event types with tailored formatting

GitLab Events

If the payload contains a project object with a GitLab structure, Dispatch generates embeds for:

  • Push Hook — branch, commit count, and commit messages
  • Merge Request Hook — MR title, description, and status
  • Issue Hook — issue title and description

Bitbucket Events

For Bitbucket payloads (containing repository.scm = "git" and Bitbucket-style structure):

  • repo:push — branch and commit summary
  • pullrequest:created / fulfilled / rejected — PR title, status, and participants

Jira Events

For Jira payloads (webhookEvent field present):

  • jira:issue_created — issue key, summary, type, and priority
  • jira:issue_updated — field changes with old/new values
  • jira:issue_deleted — issue key and summary

Linear Events

For Linear payloads (type and organizationId fields present):

  • Issue lifecycle events — title, status, priority, and assignee
  • Comment events — comment text and issue context
  • Project updates — project name and status changes

Stripe Events

For Stripe payloads (object field with "api_version" present, or livemode field):

  • charge.succeeded / failed — amount, currency, and customer
  • payment_intent.succeeded / payment_failed — amount and status
  • subscription.created / updated / deleted — plan name and customer
  • invoice.paid / payment_failed — amount due and customer

Slack Events

If the payload contains team_id, api_app_id, and type: event_callback, Dispatch generates Slack-specific embeds for:

  • Messages, reactions, channel events, member events, pins, files, emoji changes, and more

Default

For unrecognized payloads, Dispatch creates a simple embed with the raw JSON payload formatted as a code block.

Routing Rules

Each endpoint-destination link can have routing rules that select different templates based on event fields:

[
{
"field": "body.action",
"op": "eq",
"value": "opened",
"template_id": "uuid-for-opened-template"
},
{
"field": "body.action",
"op": "eq",
"value": "closed",
"template_id": "uuid-for-closed-template"
}
]

Rules are evaluated top-to-bottom. The first matching rule's template is used. If no rule matches, the default link template (or auto-formatting) is used. A routing rule can also specify a transform_id to override the transform for that rule.

Supported Operators

OperatorDescription
eqEquals
neqNot equals
containsContains substring
not_containsDoes not contain substring
existsField exists and is non-empty
not_existsField does not exist or is empty