Skip to main content

Automation - data messages

Automatically push data messages based on triggers throughout Stager

Updated this week

Automation allows you to send data to external platforms without having to lift a finger. For example, send customer data to an external Customer Data Platform to build 360 degree customer profiles or send transaction data to financial platform to track spending habits.


Create a data message automation

To create a data message automation, first go to Marketing - Automation. Then click + New workflow in the upper right corner. This will bring you to the Automation builder, where you will see different 4 blocks. These are explained below.

Workflow

The first block is the Workflow block. This is where you enter general information about the automation workflow as a whole. The first field, Send, is the most important, as it determines what the automation will send. Select the Data message option here. Next, you can fill in the rest of the fields as necessary for the automation you are trying to make.

Trigger

Next you will see the Trigger block which you can use to determine what exactly will cause your automation workflow to execute. When creating an data message automation, you have the choice between Order and Contact

Order

If you select Order, you only have one option:

  • Updated on: You set the trigger based on when an order has been updated. This means that you get a message any time the order or any ticket within it is modified. Creating an order also falls under modification in this scenario, just as tickets being refunded or swapped. This is made distinct by a specific property that is sent together with the message.

Contact

If you select Contact, you only have one option:

  • Updated on: You set the trigger based on when an Contact has been updated. This means that you get a message any time the contact or anything related to it has been updated, be it their contact details, their interests or their opt-ins. Creating and deleting a contact also falls under modification in this scenario. This is made distinct by a specific property that is sent together with the message.

When a trigger has been selected, the Execute action field will appear. For data message automation workflows, there will always be only one option - At the same time as. This is because you generally will want the updated data as soon as possible.

Rules

No rules are currently available for any data message automation workflows. These will be added in the future. For now, each change is handled like a trigger when an automation is active.

Action

Finally, we have the Action block. This is where you will configure where data messages triggered by this workflow should be sent.

This block consists of two fields. The first of these is the data message type. This is the specific message that will be sent. For now, each trigger supports a single message type, which is why this field will always be automatically selected. For Order-based triggers, this will always be Transaction data, while for Contact-based trigger it will be Contact data. More on this can be found in the, linked below.

The second field is the Webhook URL field which tells Stager where the triggered data messages should be sent. This is either and endpoint to your own server (for example https://www.organizer.com/stager-data-message) or an external tool you want the data to be pushed to.


Technical Implementation

The automated data messages are implemented using a webhook which users can specify. Triggered workflows push to that webhook, providing you with up-to-date data. You first need to create an endpoint that we can push all information to.

To help you, the data messages comes with their own documentation:

In the documentation you can see a single webhook as well as 2 different possible JSON schemas. These schemas are the different datasets that we can push to your endpoints. The specific dataset depends on what has been specified in the automation. A contact-based automation will always contain the ContactData dataset and so forth.

The schemas are always enveloped together with some useful data such as simple organization data, simple automation data, the time the push was triggered and the specific change that triggered this push (in case of contact: was the contact created, or was an existing contact updated?)

To make the handling of messages easier (especially during busier moments) we always recommend implementing a queue mechanism. This way you can easily capture the requests sent by Stager, put them in the queue and process them outside the request cycle, not holding up subsequent requests and possibly causing time-outs.

Verification

As data provided by the automated data messages will most likely be used to populate both internal as well as external platforms with sensitive data, we recommend you set up your application to verify that incoming data is sent by Stager and not a different party. This makes sure that no 'fake' data gets through to your website, preventing in from being defaced.

To help you with this, Stager will sign all outgoing requests to your application with an X-Signature HTTP header. This signature is created using the full body of the request sent to your endpoint. It uses the HMAC-SHA256 hashing algorithm and the authentication token of your workflow as the secret key. You can find this token in the Workflow block of a previously saved data message automation workflow.

You can easily verify the signature using the request body, the authentication token of your workflow, the signature itself (the value of the X-Signature header) and any cryptography library available within your chosen tech stack that has support for the HMAC-SHA256 algorithm.

Verification code samples

We have a limited list of code samples to guide you through verifying requests received at your Stager webhook endpoint.

Node.js / Express

import express from "express";
import bodyParser from "body-parser";
import crypto from "crypto";

const HMAC_ALGORITHM = "sha256";
const HMAC_ENCODING = "hex";

// The authentication token, found on the selected channel page.
// Assumed that it is set as an enviroment variable,
// which is recommended, as the token is considered a secret.
const HMAC_SECRET = process.env.SECRET_TOKEN;

// Webhook endpoint - receives push feed requests from Stager
app.post("/stager-data-messages", (req, res) => {
// Prepare required data
const body = req.body;
const bodyString = JSON.stringify(body);
const stagerSignature = req.header("X-Signature");

// Create Hmac object, generate control signature
hmacObject = crypto.createHmac(HMAC_ALGORITHM, HMAC_SECRET);
hmacObject.update(bodyString);
const controlSignature = hmacObject.digest(HMAC_ENCODING);

// Verify signature provided by Stager
if (stagerSignature === controlSignature) {
// Signature valid, message is safe to process

// ...

// Close connection with a 200 response
res.status(200).send("Request received and message processed!");
} else {
// Signature invalid, message ignored
// Close connection with a 403 response
res.status(403).send("Request validation failed!");
}
});

Kotlin / Play

import javax.crypto.Mac  
import javax.crypto.spec.SecretKeySpec
import org.apache.commons.codec.binary.Hex
import play.mvc.Controller
import play.mvc.NoAuthenticityToken
import play.mvc.results.Forbidden
import play.mvc.results.Ok
import play.mvc.results.Result

// The authentication token, found in the Stager Backstage
// Assumed that it is set as an environment variable "authenticationToken"
// which is recommended, as the token is considered a secret
const val AUTHENTICATION_TOKEN_NAME = "authenticationToken"

const val HMAC_ALGORITHM = "HmacSHA256"
const val SIGNATURE_HEADER = "X-Signature"

class StagerDataMessageRequestHandler : Controller() {
@NoAuthenticityToken
fun handle(): Result {
val body = request.body
val bodyBytes = body.readAllBytes()

val headers = request.headers
val stagerSignature = headers[SIGNATURE_HEADER]?.value()

// Verify signature provided by Stager
return if (validateSignature(bodyBytes, stagerSignature)) {
// Signature valid, message is safe to process

// ...

Ok() // Close connection with a 200 response
} else {
// Signature invalid, message ignored
// Close connection with a 403 response
Forbidden("Request validation failed!")
}
}

private fun validateSignature(body: ByteArray, signature: String?): Boolean {
// Check whether signature is present
return signature?.let { // Signature present, continue with verification
// Construct SecretKeySpec object from the authentication token
val secretKeyEnvVar = System.getenv(AUTHENTICATION_TOKEN_NAME)
val secretKeyBytes = Hex.decodeHex(secretKeyEnvVar.toCharArray())
val secretKey = SecretKeySpec(secretKeyBytes, HMAC_ALGORITHM)

// Create and initiate the Mac instance
val hmacInstance = Mac.getInstance(HMAC_ALGORITHM)
hmacInstance.init(secretKey)

// Generate control signature and the Stager signature against it
val controlSignature = hmacInstance.doFinal(body)
return controlSignature.contentEquals(secretKeyBytes)
} ?: run {
false // Signature missing, default to invalid
}
}
}

Response

The data messages expect a 2XX response back within 5 seconds. If no response is received within this time, the connection is terminated and considered failed due to timeout. This is logged as an error both within Stager (to be handled internally) as well as the backstage in the automation logs.

Other responses are also allowed (for example, specific error messages such as 403 in case verification fails) to help aid debugging. These will be handled as errors though.

Logging

Stager logs any sent request together with the response received and exposes the last 7 days worth of these for your convenience. They can be accessed by clicking the Times triggered block of an active automation workflow.

In the logs page, you will see a list of all requests sent to your endpoint. Clicking on an entry will open it, showing even more data, such as the generated signature, message type and even the whole data message sent to your endpoint. Use this to debug data inconsistencies or other unexpected behavior.

Did this answer your question?