Custom templates

AdminUpdated Sep 24, 2026

Custom templates

A template tells Shippified two things about a kind of message: how to recognise it (detection rules) and where to find each order detail in it (field mappings). Shippified includes built-in templates for common monitor bots and major retailers. When a bot or retailer isn't covered, or isn't read the way you want, you can build your own from a real sample.

Custom templates run through the same engine as the built-ins. Anything a built-in template can read, a custom one can too.

The Templates page

Open Templates in the sidebar. At the top:

  • Webhook / Email switches between templates for Discord webhook payloads and templates for emails.

  • Re-run parsing rebuilds your existing orders using your current templates (see Applying changes to existing orders).

  • Build template opens the builder.

Below that are two sections:

Section

What's in it

Your templates

The custom templates in your workspace. Each card shows the event type, how many rules and mappings it has, and the first few mappings. Use the pencil icon to edit and the trash icon to delete.

Built-in

Templates maintained by Shippified, marked Live. You can't edit these, but you can override them with a custom template (custom templates are tried first).

Note: Deleting a custom template happens immediately, without a confirmation step. Bots that had it pinned show missing and go back to automatic detection. Existing orders keep their values until you re-run parsing.

Which template wins

Every incoming payload is checked against templates in this order:

  1. Webhooks only: the template pinned on the receiving bot. It is always used, whether or not its rules pass.

  2. Your custom templates of the matching kind (webhook or email), newest first. Your templates on the Templates page lists them in this same order, and the order stays the same from one message to the next.

  3. Built-in templates.

The first template whose detection rules all pass is used. After that, Shippified runs a generic pass that fills in any field the template didn't extract, such as quantity, tracking number or carrier. You only need to map what's specific to the message.

For email, an inbox can be limited to certain templates using Templates this source parses against in its settings (see Connect email). The chosen templates are then tried in the order you set.

Important: A template with no detection rules only runs when a Discord bot pins it as its Parser template. It's never chosen automatically, and that includes email: an email template with no rules never matches, even if an inbox lists it under Templates this source parses against. Always give email templates at least one rule, such as a sender filter. The builder reminds you of this while the rule list is empty.

The builder

Click Build template, or the pencil icon on one of your templates. The builder has a settings column on the left and an Extraction map column on the right.

Template settings

Field

Options

Template name

Shown in the library, in the bot's Parser template list and on orders.

Source

Webhook JSON or Email HTML / text.

Event type

Other, Order placed, Order shipped, Order update, Order delivered, Order canceled.

Event type fixes the lifecycle event for every message this template handles, and that drives the order's status. Choose Other when one template covers several events, which is common for monitor bots that send the same layout for everything. Shippified then works out the event from the wording ("shipped", "delivered", "canceled", "out for delivery", "successful checkout" and so on).

Note: Choose the Source before you start mapping. Changing it replaces your mappings with the starter mappings for the new source, and if you've edited the sample, Shippified asks before replacing it too (Replace the sample payload?). Once a template is saved, its source is fixed: when you edit it, leave Source as it is. To read the other kind of message, build a new template.

There's no store picker in the builder. Shippified works out the store from the sender's address (email), from the embed text (webhooks), or from a store mapping. It currently recognises Target, Walmart, Amazon and Best Buy. Orders from other retailers are filed under Unknown Store. A template created through the API can have a fixed store; editing it in the builder keeps that store.

The sample payload

Sample payload is the reference message your rules and mappings are tested against.

  • Webhook: paste the JSON body your bot posts, usually { "embeds": [ ... ] }. You can copy it from a bot's activity log, or click Load from Discord to use an embed captured with the embed copier.

  • Email: paste the raw email, including headers. In Gmail, use Show original. At minimum, include From: and Subject: lines, then a blank line, then the HTML or text body.

Use one sample per template. If a retailer's "order placed" and "order shipped" emails look different, build two templates.

Detection rules

Detection rules decide whether the template applies. Click Add rule to add one. Each rule has a Type, a Selector, an Operator and a Value. Email rules also have a Scope.

As you edit, each rule shows matched or no match against the sample, and Resolved against sample: shows the exact value the selector found. Use it to check that your selector is reading what you expect.

Selector types

Type (UI label)

Selector example

What it reads

JSON path

embeds[0].footer.text

A value in the webhook JSON. Use dots between keys and [n] for list positions; a leading $. is optional. Webhooks only.

Embed field name

Order #

Webhook: the embed field with this name, ignoring case. Otherwise, a Name: value line in the text; the value runs to the end of the line, or to the first comma or |.

Regex capture

Subject:\s*([^\n]+)

Searches the message and uses the first capture group, or the whole match if there's no group.

Operators

Operator

Passes when

equals

The resolved value equals Value exactly (ignoring case).

contains

The resolved value contains Value (ignoring case).

regex

Value is a regular expression that matches the resolved value (ignoring case).

exists

The selector found any non-empty value. Value isn't used.

A rule whose selector finds nothing fails, except that exists is simply false. All rules must pass for the template to apply.

Scope (email only)

Scope

Looks at

header

The decoded From:, To:, Subject: and Date: lines.

body

The email body: first the HTML, then its plain-text version.

auto

header when the selector starts with a header name such as From, Subject or To; otherwise body.

For email templates, Filter by sender above the rule list is a shortcut. Type part of the sender address (for example @mail.example-shop.com) and Shippified adds a hidden rule: "From header contains this text". Leave it empty for no sender filter.

Tip: Header lines are joined in the order From, To, Subject, Date. A regex that starts with ^ only matches at the very start (the From: line), so ^Subject: won't match. Write Subject:\s*([^\n]+), or (?:^|\n)Subject:\s*([^\n]+) as the builder's placeholder suggests, or use Embed field name with the selector Subject.

Field mappings

Mappings in the Extraction map column say where each order detail comes from. Click Add mapping, choose a target field and a selector type, then enter the selector. Every mapping shows its Extracted value from the sample. Click Preview to refresh them all.

Target

Use it for

orderNumber

The retailer's order number. Messages with the same order number are merged into one order.

itemSummary

The product name.

customerName

Customer, profile or account name.

total, price

Money amounts. The cost on the order comes from price if it's set, otherwise total.

quantity

Units. Only the digits are used.

trackingNumber, carrier

Shipping details. If you don't map a carrier, it's detected from the tracking number.

sku, size

Product variant details.

productUrl, imageUrl

Links shown on the order.

eventTime

When the event happened, if the message says.

store

Only works if the value names a recognised retailer.

eventType

Only used when Event type is Other. The value can be an event name (order_shipped) or wording such as "Shipped".

custom

Any extra value. Give it a custom key, and it's stored on the order under that name.

How mappings behave:

  • Several mappings for one target act as fallbacks. The first one that returns a value wins, so put the most specific one first.

  • Regex mappings search the email HTML first, then the plain-text version, then the header lines. Matching always ignores case, and . also matches line breaks, so prefer [^\n<]+ over .* to stop at the end of the value.

  • Values are cleaned automatically. HTML tags and entities are removed, Discord formatting (||spoiler||, **bold**, __underline__, backticks) is removed, and extra spaces are collapsed. <strong>$49.99</strong> becomes $49.99.

Tip: Writing a regex for an HTML email? Write it against how the email reads as plain text (the Label: value wording). If it doesn't match the raw HTML, Shippified tries it again on the plain-text version.

The "In production" panel

Under the mappings, In production runs the real parser on your sample, with your draft tried ahead of your saved templates. It never creates or changes an order, so it's the place to test a template without touching your data. (The Import an email by hand panel under Links → Emails is different: it runs the same parser but adds the result to your orders.) It tells you:

  • This template handles it: your draft's rules pass, so it would handle this message.

  • Handled by name (marked (built-in) if it's a built-in): your draft's rules don't all pass, so another template would handle it.

  • No template matches — generic parsing: nothing matched, so only the generic pass would run.

  • Ignored — not recognised as order mail (email only): this message wouldn't become an order at all.

It also previews the order that would be created: Status, Event, Store, Order #, Item, Total, Qty and Tracking. A dash means that value is missing.

Note: The panel doesn't take bot pins or inbox template lists into account. A pinned template always wins for that bot, whatever the panel shows. It also tries your draft first, while live intake tries custom templates newest first. If you're editing an older template and a newer one also matches the sample, the newer one wins in production.

Saving and validation errors

Click Save template (or Save changes when editing). Rules and mappings with an empty selector are dropped when you save. An invalid regular expression stops the save and shows an error above the button, for example:

Rule 2 selector is not a valid regex: Invalid regular expression: /Order (#/is: Unterminated group
Rule 3 value is not a valid regex: Invalid regular expression: /*shipped/is: Nothing to repeat
Mapping 1 (orderNumber) is not a valid regex: Invalid regular expression: /[A-Z/is: Unterminated character class

The part between the slashes is your pattern. The message after it tells you what's wrong: an unclosed ( or [, or a * or + with nothing in front of it. To match those characters literally, put a backslash before them, for example \( or \*.

If you don't use Filter by sender, the rule number in an error matches the Rule N label in the builder. If you do, the error counts the sender filter as rule 1, so its number is one higher than the label: an error about Rule 2 refers to the rule labelled Rule 1. Mapping numbers always match the mapping's position in the list.

Worked example 1: an email template for a new retailer

A fictional retailer, Northwind Outfitters, sends this order confirmation:

From: Northwind Outfitters <[email protected]>
To: [email protected]
Subject: Your Northwind order NW-448812 is confirmed

<html><body>
<h1>Thanks for your order!</h1>
<p>Order number: <strong>NW-448812</strong></p>
<p>Item: <strong>Trail Runner 2 Jacket - Size M</strong></p>
<p>Quantity: 2</p>
<p>Order total: <strong>$189.98</strong></p>
</body></html>
  1. Click Build template. Set Source to Email HTML / text, Template name to "Northwind — placed" and Event type to Order placed.

  2. Paste the email into Sample payload.

  3. In Filter by sender, enter @mail.northwind-outfitters.example.

  4. The builder starts with a rule that checks for a different sender. Remove it with its trash icon.

  5. Add a subject rule:

    Type

    Selector

    Operator

    Value

    Scope

    Regex capture

    Subject:\s*([^\n]+)

    contains

    is confirmed

    header

  6. Replace the starter mappings with these:

    Target

    Type

    Selector

    orderNumber

    Regex capture

    Order number:\s*(NW-\d+)

    itemSummary

    Regex capture

    Item:\s*([^\n<]+)

    total

    Regex capture

    Order total:\s*(\$[\d,.]+)

  7. Check that In production reads This template handles it, with order NW-448812, the jacket as the item, $189.98 as the total and a quantity of 2. You didn't map quantity: the generic pass found Quantity: 2.

  8. Click Save template.

Because Northwind isn't a recognised retailer, the order's store is Unknown Store. Map itemSummary whenever you can: an order with an unknown store and no item is flagged as Issue for review.

Worked example 2: a second template for shipping emails

The same retailer's shipping email has the subject "Your Northwind order NW-448812 has shipped" and a line reading Tracking number: 1Z999AA10123456784. Build a second template:

  • Event type: Order shipped

  • Filter by sender: @mail.northwind-outfitters.example

  • Rules:

    Type

    Selector

    Operator

    Value

    Scope

    Regex capture

    Subject:\s*([^\n]+)

    contains

    has shipped

    header

    Regex capture

    Tracking number:\s*(\w+)

    exists

    body

  • Mappings: orderNumber with the same regex as before, and trackingNumber with Tracking number:\s*(\w+).

The shipping email carries the same order number, so it's merged into the order from example 1. That order moves to shipped, gets the tracking number, and its carrier is detected automatically. Each template's subject rule keeps it from claiming the other email.

Worked example 3: a Discord monitor embed

A fictional monitor, Lumen, posts this webhook:

{
  "username": "Lumen",
  "embeds": [{
    "title": "Successful Checkout",
    "author": { "name": "Lumen Monitors" },
    "thumbnail": { "url": "https://cdn.example.com/p/earbuds.png" },
    "fields": [
      { "name": "Site", "value": "Target" },
      { "name": "Product", "value": "**Wireless Earbuds Pro**" },
      { "name": "Price", "value": "$129.99" },
      { "name": "Qty", "value": "1" },
      { "name": "Order", "value": "||912000111222||" },
      { "name": "Profile", "value": "Main 01" }
    ],
    "footer": { "text": "Lumen Monitors v3.2" }
  }]
}
  1. Click Build template with the Webhook tab selected. Set Source to Webhook JSON and Event type to Order placed.

  2. Paste the JSON, or click Load from Discord and pick the captured embed.

  3. Set these rules:

    Type

    Selector

    Operator

    Value

    JSON path

    embeds[0].footer.text

    contains

    Lumen

    JSON path

    embeds[0].title

    regex

    success(ful)? checkout

  4. Set these mappings:

    Target

    Type

    Selector

    orderNumber

    Embed field name

    Order

    itemSummary

    JSON path

    embeds[0].fields[1].value

    total

    Embed field name

    Price

    store

    Embed field name

    Site

    customerName

    Embed field name

    Profile

    imageUrl

    JSON path

    embeds[0].thumbnail.url

  5. Check the Extracted values. The spoiler bars around the order number and the bold markers around the product name are removed, and Target is recognised as the store.

  6. Save. Then go to Links → Webhooks, edit the Lumen bot and choose "your template name · custom" under Parser template. See Connect Discord monitor bots.

Tip: Embed field name selectors keep working if the bot changes the order of its fields. fields[1]-style JSON paths don't. Use JSON paths for values that aren't in fields, such as the title, footer, author or thumbnail.

Editing templates

Click the pencil icon on a template card, change it and click Save changes. Changes apply to new messages straight away. Editing doesn't change a template's place in the order: it's still ranked by when it was created. Settings the builder doesn't show, such as a fixed store set through the API, are kept.

Applying changes to existing orders

Every email and webhook payload Shippified receives is stored. After you create or change templates, click Re-run parsing on the Templates page to rebuild your existing orders from their original messages. Shippified reports the result, for example "Re-parsed 42 orders: 5 updated, 1 merged".

What re-parsing does:

  • Rebuilds each order from its stored messages, using your current templates, bot pins and inbox template lists.

  • Keeps values that don't come from messages: sale prices you entered, fields you edited by hand, delivery dates, addresses, and package weight and dimensions from carriers.

  • Merges orders that now share an order number.

  • Removes orders whose messages now all look like non-order mail, unless you've edited them or entered a sale price.

  • Skips orders with no stored messages, such as manual orders.

Related

Was this page helpful?