Pipeline

Table of contents

  1. Overview
  2. Pipeline contract
  3. Built-In Transform Steps
  4. Slack Simple
    1. Smallest valid Slack pipeline
    2. Slack pipeline with HTML normalization
    3. Slack pipeline with prefix
    4. Full route JSON example for Slack
    5. Slack payload after transformation
  5. Telegram Simple
    1. Smallest valid Telegram pipeline
    2. Telegram pipeline with HTML normalization
    3. Telegram pipeline with prefix
    4. Full route JSON example for Telegram
    5. Telegram payload after transformation

Overview

A pipeline is the per-route transformation chain that runs only after a route rule matches an incoming email. It consumes the parsed message plus route context and emits a JSON payload; that payload is posted verbatim to the route’s endpoint.

The default step is map.generic_json, which emits the deterministic mailwebhook.generic@1 shape described in Generic JSON. Attachments stay out of the HTTP body and only their metadata is included, keeping delivery fast and reliable.

Optional transform steps can run before the terminal map.* step to normalize HTML, redact fields, rewrite values, or drop attachments before the payload is mapped. See Transform Steps for the full argument reference.

For custom outputs, map.custom_json lets you define a JsonLogic-style mapper validated by JSON Schema, producing whatever JSON shape your downstream system expects. See Custom JSON for the mapper contract and JsonLogic-style DSL for expression operators, helper calls, and runtime limits.

Slack and Telegram use terminal chat mappers:

  • map.slack_simple
  • map.telegram_simple

These mappers transform an inbound email into a short chat-ready message and emit the final payload delivered to the route endpoint. If you need a richer JSON body, use Generic JSON or Custom JSON with your own webhook endpoint instead of the simple chat mappers.

Pipeline contract

All route pipelines follow the same rules:

  1. pipeline.steps must contain at least one step.
  2. Exactly one map.* step must exist.
  3. The map.* step must be the final step.

Chat mappers accept provider-specific destination arguments:

  • Slack: channel
  • Telegram: chat_id

Useful optional arguments supported by both chat mappers:

  • max_chars
  • include_from
  • prefix

Built-In Transform Steps

These non-terminal steps can run before the final mapper:

StepUse it for
html_to_textConvert message HTML into deterministic plain text.
remove_fieldsRemove or clear selected message fields before mapping.
replace_valuesSet subject, body, or header values from literals or small templates.
strip_attachments_ifRemove attachments that match configured MIME, size, and filename conditions.

See Transform Steps for arguments, supported field paths, and examples.

Slack Simple

map.slack_simple emits a payload with the following shape:

{
  "channel": "C0123456789",
  "text": "..."
}

Smallest valid Slack pipeline

{
  "steps": [
    {
      "name": "map.slack_simple",
      "args": {
        "channel": "C0123456789"
      }
    }
  ]
}

Slack pipeline with HTML normalization

{
  "steps": [
    {
      "name": "html_to_text",
      "args": {
        "prefer": "html",
        "width": 0
      }
    },
    {
      "name": "map.slack_simple",
      "args": {
        "channel": "C0123456789",
        "max_chars": 700,
        "include_from": true
      }
    }
  ]
}

Slack pipeline with prefix

{
  "steps": [
    {
      "name": "html_to_text",
      "args": {
        "prefer": "html"
      }
    },
    {
      "name": "map.slack_simple",
      "args": {
        "channel": "C0123456789",
        "prefix": "[MailWebhook] ",
        "max_chars": 500,
        "include_from": true
      }
    }
  ]
}

Full route JSON example for Slack

{
  "name": "Invoices to Slack",
  "endpoint_id": "0f5a83e4-8220-4f0d-917e-6be20d9dc32d",
  "signing_secret_kid": "route-signing-prod",
  "enabled": true,
  "rule": {
    "to_emails": ["ap@company.com"],
    "from_domains": ["vendor.com"],
    "subject_contains": ["invoice", "receipt"]
  },
  "pipeline": {
    "steps": [
      {
        "name": "html_to_text",
        "args": {
          "prefer": "html",
          "width": 0
        }
      },
      {
        "name": "map.slack_simple",
        "args": {
          "channel": "C0123456789",
          "max_chars": 700,
          "include_from": true
        }
      }
    ]
  }
}

Slack payload after transformation

{
  "channel": "C0123456789",
  "text": "Invoice from vendor@example.com\nSubject: March invoice\n..."
}

Telegram Simple

map.telegram_simple emits a payload with the following shape:

{
  "chat_id": "-10012345",
  "text": "..."
}

Smallest valid Telegram pipeline

{
  "steps": [
    {
      "name": "map.telegram_simple",
      "args": {
        "chat_id": "-10012345"
      }
    }
  ]
}

Telegram pipeline with HTML normalization

{
  "steps": [
    {
      "name": "html_to_text",
      "args": {
        "prefer": "html",
        "width": 0
      }
    },
    {
      "name": "map.telegram_simple",
      "args": {
        "chat_id": "-10012345",
        "max_chars": 700,
        "include_from": true
      }
    }
  ]
}

Telegram pipeline with prefix

{
  "steps": [
    {
      "name": "html_to_text",
      "args": {
        "prefer": "html"
      }
    },
    {
      "name": "map.telegram_simple",
      "args": {
        "chat_id": "-10012345",
        "prefix": "[Inbox alert] ",
        "max_chars": 500,
        "include_from": true
      }
    }
  ]
}

Full route JSON example for Telegram

{
  "name": "Alerts to Telegram",
  "endpoint_id": "0f5a83e4-8220-4f0d-917e-6be20d9dc32d",
  "signing_secret_kid": "route-signing-prod",
  "enabled": true,
  "rule": {
    "to_emails": ["alerts@company.com"],
    "subject_contains": ["urgent", "down", "failure"]
  },
  "pipeline": {
    "steps": [
      {
        "name": "html_to_text",
        "args": {
          "prefer": "html",
          "width": 0
        }
      },
      {
        "name": "map.telegram_simple",
        "args": {
          "chat_id": "-10012345",
          "max_chars": 700,
          "include_from": true
        }
      }
    ]
  }
}

Telegram payload after transformation

{
  "chat_id": "-10012345",
  "text": "Alert from sender@example.com\nSubject: Service failure\n..."
}

Table of contents