Appearance
Messaging
Boxture sends e-mails, text messages and other notifications through its messaging module. Nothing is sent by default: a message only goes out when someone has set up a template for an event, for example "send the customer an e-mail when the shipment is shipped". Templates use Liquid, a simple template language, to fill in order numbers, addresses, tracking numbers and other details.
You find messaging under Admin › Messaging. It has six screens:
| Screen | What it is for |
|---|---|
| Messages | Every message that was sent (or attempted), with its status. |
| Templates | The rules that decide which message is sent for which event. |
| Layouts | Shared HTML wrappers for e-mails, such as a header with your logo and a footer. |
| Locales | Translations that templates can use, so one template can produce messages in several languages. |
| Campaigns | One-off messages sent to everyone on a list. |
| Lists | Lists of subscribers for campaigns. |
Only users with the Admin role can open these screens.
How a message is sent
- Something happens in Boxture: an order is allocated, a shipment is shipped, a user asks for a password reset. This is an event on a type of record (the Klass).
- Boxture looks for enabled templates with that Klass and Event that belong to the account of the record or to one of its parent accounts.
- For each template found, Boxture renders the To field. If it is empty, no message is created.
- Otherwise it renders the other fields, attaches any files and hands the message to the transport (mail, SMS, voice or Slack).
- The message appears under Messages with its state.
TIP
Because templates of parent accounts are included, a template created on a parent account applies to all its child accounts. Create a template on the account itself when it should only apply there. See Accounts for the account hierarchy.
Every template belongs to the account that was selected when it was created; the lists only show records of the current account. Switch account to see or change the templates of another account.
Templates
Go to Admin › Messaging › Templates and click New template. The form has these fields:
| Field | Description |
|---|---|
| Enabled | Only enabled templates are used. Disable a template to stop it without deleting it. |
| Description | A name for the template, shown in the list and in the message overview. Required. |
| Klass | The type of record the template is for, for example Order, Shipment or User. |
| Event | The event that triggers the template. The list shows the events available for the chosen Klass. |
| Transport | mail, sms, voice or slack. The fields below change with the transport. |
| From | The sender. Leave empty to use the default sender. |
| To | The recipient(s), usually a Liquid expression such as an e-mail address of a contact. Separate several recipients with commas. |
| Metadata | YAML with extra data; the account the template belongs to is stored here. |
For mail you also get:
- Subject, which can contain Liquid.
- Layout, an optional layout from Layouts.
- Html, the body. You can write Markdown or HTML, with Liquid.
- Link tracking and Open tracking. When switched on, clicks on links and the opening of the e-mail are recorded on the message.
For sms and voice you write a Text. For slack you write a Text and optionally a Payload in YAML (Slack Block Kit).
Click Save to store the template, or Continue to save and stay on the form. Once messages have been sent with a template, a Messages tab on the template shows them.
Example: shipment confirmation
| Field | Value |
|---|---|
| Description | Shipment shipped |
| Klass | Shipment |
| Event | ship |
| Transport |
To:
liquid
{{ shipment.destination.email }}Subject:
liquid
Your order {{ shipment.customer_reference_number }} is on its wayHtml:
liquid
Dear {{ shipment.destination.first_name }},
Your order {{ shipment.customer_reference_number }} was shipped with {{ shipment.carrier.name }}.
{% if shipment.tracking_number != blank %}
Your tracking number is **{{ shipment.tracking_number }}**.
{% endif %}
{% for parcel in shipment.parcels %}
- Parcel {{ parcel.position }}: {{ parcel.human_weight }}, tracking {{ parcel.tracking_number }}
{% endfor %}Attachments
A template can attach a file with the attach tag, for example a file from a URL:
liquid
{% attach 'https://www.example.com/terms.pdf' %}Some events attach files automatically, see the list of events below.
Which events can send messages
The Event list shows every event of the chosen Klass. The ones you will use most:
Order and order lines
Templates with Klass Order can use every status change of an order: confirm, pending, allocate, unallocate, backorder, picking, pick, unpick, pack, unpack, ship, expect, receive, build, complete, cancel, hold and release. The event fires when the order makes that transition, for example ship when the order is shipped. The hold event also fires when an order is put on hold manually. See Order lifecycle and Holds.
In addition every order fires create and update (and save for both) when it is created or changed, and destroy when it is deleted.
OrderLine has the same kind of events for lines: confirm, pending, allocate, unallocate, picking, pick, pack, ship, expect, receive, build, complete, cancel and retire, plus create, update, save and destroy.
Shipments and parcels
| Event | When |
|---|---|
pending, hold, release, label, labelled, ship, shipped, deliver, cancel | When the shipment makes that transition. See Shipments. |
paperwork_generated | After the carrier label (waybill) has been created for a shipment, and after the paperwork for a return shipment has been created. |
hold_un_number | When a pending shipment is put on hold and it contains items with a UN number (dangerous goods). |
create, update, save, destroy | When a shipment is created, changed or deleted. |
Parcel has the create, update, save and destroy events.
Inventory
| Klass | Event | When |
|---|---|---|
| InventoryItem | low_stock | When an inventory item is retired and the remaining available inventory of that product, status and location drops below the product's reorder level. See Product settings › Reorder level. |
| InventorySnapshot | create | When an inventory snapshot is made. The snapshot is attached as an Excel file automatically. See Snapshots. |
Users
User templates can use:
reset_password_instructions: fires when a user asks for a password reset. Use thetokenvariable to build the reset link.
WARNING
Password reset e-mails are sent only through messaging templates. Without an enabled User template for reset_password_instructions, users who forgot their password receive no e-mail.
activateanddisable: when a user is activated or disabled.create,update,saveanddestroy.
importo_import_completed and importo_import_failed appear in the list as well, but the current version doesn't send them. The in-app notification of an import has the results file, see Imports.
Daily reports
Every night at midnight (Amsterdam time) Boxture fires the daily event for each reporting view, such as Reporting::InventoryOnHand, Reporting::OpenSalesOrder or Reporting::ShippedProduct. A template with that Klass and event daily sends the report; the report is attached as an Excel file automatically. See Reporting.
Integrations
| Klass | Event | When |
|---|---|---|
| Integration | netsuite_fulfillment_failure | When NetSuite rejects a fulfillment. Variables: exception_message, shipment, account, user. |
| Integration | webhook_failure | When a Shopify webhook can't be processed. |
| Vorto::Message | process, complete, exception, retry | When an integration message changes state. See Vorto. |
| Exceptio::Exception, Exceptio::Instance | create | When an application error is recorded. See Exceptions. |
Liquid variables
The record that triggered the event is available under its name in lowercase: order, shipment, parcel, order_line, inventory_item, user, and so on. The user who triggered the event is available as user too (when it isn't the record itself), and the current language as locale.
You output a variable between double curly braces and write logic (conditions, loops) between curly braces with percent signs:
liquid
{{ order.name }}
{{ order.delivery_contact.company_name }}
{% for line in order.order_lines %}
{{ line.quantity }} x {{ line.product.number }} {{ line.product.name }}
{% endfor %}Order
liquid
{{ order.name }} order number
{{ order.state }}
{{ order.short_type }} the order type
{{ order.customer_reference_number }}
{{ order.purchase_order_number }}
{{ order.other_reference_number }}
{{ order.business_model }} b2c, b2b, b2g or bopis
{{ order.delivery_terms }}
{{ order.gift_message }}
{{ order.packing_instructions }}
{{ order.customer_name }}
{{ order.metadata }}
{{ order.created_at }} {{ order.updated_at }}
{{ order.account }} see Account
{{ order.customer }} id, name, state, metadata
{{ order.delivery_contact }} see Contact
{{ order.billing_contact }}
{{ order.pickup_contact }}
{{ order.destination_location }} see Location
{{ order.related_order }}
{{ order.order_lines }} list of order lines
{{ order.order_line_items }}
{{ order.shipments }} list of shipments
{{ order.last_shipment }}
{{ order.papers }}Order status checks, which return true or false, include everything_shipped?, everything_packed?, everything_picked?, everything_allocated?, anything_backordered?, anything_pending?, everything_cancelled? and export_shipments?.
Order line
liquid
{{ order_line.position }}
{{ order_line.quantity }}
{{ order_line.product }} see Product
{{ order_line.description }}
{{ order_line.serial_number }}
{{ order_line.status }} new or defective
{{ order_line.state }}
{{ order_line.price }} {{ order_line.discount }} {{ order_line.customs_value }}
{{ order_line.allocated_quantity }} {{ order_line.backordered_quantity }}
{{ order_line.picked_quantity }} {{ order_line.packed_quantity }} {{ order_line.shipped_quantity }}
{{ order_line.received_quantity }} {{ order_line.expected_quantity }}
{{ order_line.origin_location }}
{{ order_line.order }}Shipment
liquid
{{ shipment.name }}
{{ shipment.state }}
{{ shipment.tracking_number }}
{{ shipment.return_tracking_number }}
{{ shipment.carrier.name }} {{ shipment.carrier.code }} {{ shipment.carrier.url }}
{{ shipment.service_type.name }}
{{ shipment.ship_at }}
{{ shipment.delivery_terms }}
{{ shipment.customer_reference_number }}
{{ shipment.purchase_order_number }}
{{ shipment.origin }} sender, see Contact
{{ shipment.destination }} receiver, see Contact (also shipment.consignee)
{{ shipment.billing }}
{{ shipment.importer }} {{ shipment.exporter }}
{{ shipment.order }} first order of the shipment
{{ shipment.orders }}
{{ shipment.parcels }}
{{ shipment.parcel_items }}
{{ shipment.account }}
{{ shipment.export? }}Parcel and parcel item
liquid
{{ parcel.position }}
{{ parcel.tracking_number }}
{{ parcel.sscc }}
{{ parcel.physical_packaging }}
{{ parcel.weight }} {{ parcel.weight_unit }} or {{ parcel.human_weight }}
{{ parcel.length }} {{ parcel.width }} {{ parcel.height }} {{ parcel.dimensions_unit }} or {{ parcel.human_dimensions }}
{{ parcel.container }}
{{ parcel.parcel_items }}
{{ parcel_item.product_number }} {{ parcel_item.product_name }}
{{ parcel_item.serial_number }}
{{ parcel_item.price }} {{ parcel_item.customs_value }}
{{ parcel_item.hs_code }} {{ parcel_item.origin_country_code }} {{ parcel_item.un_number }}Contact
liquid
{{ contact.company_name }}
{{ contact.first_name }} {{ contact.last_name }}
{{ contact.address_lines }}
{{ contact.postal_code }} {{ contact.city }}
{{ contact.state_or_province_code }} {{ contact.country_code }}
{{ contact.formatted_address }}
{{ contact.email }} {{ contact.phone_number }}
{{ contact.vatin }} {{ contact.eori_number }} {{ contact.chamber_of_commerce_number }}Product
liquid
{{ product.number }} {{ product.name }} {{ product.description }}
{{ product.ean_or_upc }}
{{ product.product_category }}
{{ product.price }}
{{ product.weight }} {{ product.weight_unit }}
{{ product.hs_code }} {{ product.origin_country_code }} {{ product.un_number }}
{{ product.customs_value }} {{ product.customs_description }}
{{ product.packing_instructions }}
{{ product.account }}Account, location, user
liquid
{{ account.name }} {{ account.code }} {{ account.url }} {{ account.gln }}
{{ account.logo }}
{{ account.parent }}
{{ account.contacts }}
{{ location.name }} {{ location.contact }} {{ location.notes }}
{{ user.name }} {{ user.email }} {{ user.root_url }}Inventory item
liquid
{{ inventory_item.product }}
{{ inventory_item.location }}
{{ inventory_item.bin_location.name }}
{{ inventory_item.status }}
{{ inventory_item.serial_number }} {{ inventory_item.lot }} {{ inventory_item.expires_on }}Useful filters
liquid
{{ shipment.ship_at | localize: 'nl', '%d-%m-%Y' }}
{{ 'greeting' | t }}
{{ order.created_at | date: '%d-%m-%Y' }}The t filter translates a text using Locales (see below).
Layouts
A layout is an HTML wrapper shared by several mail templates. Go to Admin › Messaging › Layouts › New layout, give it a Name and write the HTML in Data. Put this where the body of the template should appear:
liquid
{{ content }}After saving, a Media tab lets you upload images (such as your logo) to use in the layout, and a Templates tab shows the templates that use it. Select the layout in the Layout field of a mail template.
Locales
Locales hold translations so that one template can send messages in several languages. Go to Admin › Messaging › Locales › New locale, enter a Key to identify it and write the translations in Data as YAML, with the language code at the top:
yaml
en:
greeting: Dear customer
shipped: Your order has been shipped
nl:
greeting: Beste klant
shipped: Je bestelling is verzondenIn a template you use them with the t filter:
liquid
{{ 'greeting' | t }}
{{ 'greeting' | t: locale: 'nl' }}Without a locale option the language of the session in which the event happened is used.
Messages
Admin › Messaging › Messages lists the messages that were sent. Click a message to see:
- Preview: To, From, Subject, attachments and the rendered e-mail (or the text for SMS and Slack).
- Details: State, Transport, Provider, the provider's message ID, when it was last sent and created, and click and open counts if tracking was on.
- Tracking: the individual opens and clicks.
Use Resend to send the same message again.
Messages are also shown on the records they belong to: the order page lists the messages of the order, its lines, shipments and parcels, and the shipment page lists the messages of the shipment.
Message states
| State | Meaning |
|---|---|
| pending | Created, not yet handed to the provider. |
| sent | Handed to the provider. |
| delivered | The provider reports delivery. |
| undelivered, rejected, bounced, blocked, complaint | The provider could not deliver it, or the recipient complained. |
| no_recipient | There was no valid recipient. |
Not every transport reports every state.
Messages are meant to be deleted after a number of months, see Purging › Nuntius messages. Automatic purging is currently switched off, so for now nothing is removed. The number of failed messages per template in the last 24 hours drives the traffic light of messaging, see Traffic lights.
Campaigns and lists
Campaigns send one message to everyone on a list, for example an announcement of changed opening hours.
Lists
Go to Admin › Messaging › Lists › New list:
- Name and Slug (a short code for the list).
- unsubscribe allowed: whether subscribers may unsubscribe themselves.
- Description: tell subscribers what the list is for and how often they will get messages.
Add subscribers one by one with New subscriber (First name, Last name, Phone number, Email and Metadata), or with Import subscribers: upload a CSV file whose first row has the column headers. Supported columns are first_name, last_name, email and phone_number; any other column is stored in the subscriber's metadata.
Campaigns
Go to Admin › Messaging › Campaigns › New campaign:
- Enter a Name and choose the Transport, a Layout and the List. You can reuse a list of an earlier campaign; unsubscribes are registered on the list.
- Leave From empty to use the default sender.
- For mail, enter the Subject and the Body, and choose whether to use link and open tracking.
- Save the campaign. It stays in draft and can be changed until it is published.
- Publish the campaign and confirm "Are you sure you want to send out this campaign?". Boxture sends a message to every subscribed member of the list.
After publishing, the campaign shows statistics (messages sent, not sent, opened and clicked) and a list of its messages.