Actions

Here’s a quick demonstration showing how actions work and how easy it is to change data structures to fit your needs.

How it works

You might send an identify call or a track event from a source to Customer.io, but we have to reshape that data to fit the kinds of requests and data your destination expects.

That’s what an action does: it determines when we send data to your destination and how we map data to your destination.

The when is what we call a trigger. You’ll see the trigger on the Actions page for any destination. It’s the formula that tells us what kinds of source events result in a destination event.

The how are the Actions that we use. Because your destination expects data in a specific shape, we map source data to the shape your destination to the calls and payload-shapes your destination expects.

 In most cases, our default actions are all you’ll need

We’ve set up actions to support the majority of use cases and expected data structures. You’ll only want to change these if you aren’t using the out-of-the-box functionality with your destination.

flowchart LR a(source event)-->b{Does it match a
destination trigger} b-->|yes|c(Map data to
destination) b-.->|no|d(Event is not
forwarded to destination)
The default actions for the Customer.io source
The default actions for the Customer.io source

How many actions should I have?

The Type determines the kinds of things your source data can do in your destination. In general, you won’t have more actions than you have types!

By default, when you set up a new destination, you’ll see an action for every available Type.

Action types

An action Type is the thing that you want to do in your destination.

the action types available for the Customer.io destination
the action types available for the Customer.io destination

For example, you’ll notice that the top type in our Customer.io destination is the Create or Update Person action. This is a fundamental action in Customer.io Journeys and maps nicely to an Identify call.

You can add/update and delete devices to, but these don’t map neatly to a source method, so we look for events called Application Installed and Uninstalled!

Because different destinations serve different purposes, action types differ by destination.

Triggers and Filters

A Trigger determines when we send an action of the specified Type. It’s governed by conditions in the Filter field when you edit an action.

There are two typical filter fields:

  • type represents the kinds of methods sent from our source libraries: identify, track, page, screen, group, and alias.
  • event represents the name field from track calls. Unlike other calls, track calls simply represent custom events, and the event name tells us what kind of event a person performed.

You can also filter based on other fields, but we’d recommend that you not get too granular with filters or you could inadvertently prevent data from reaching your destination!

Triggers on the Actions TabFilters within an Action
the trigger field on the actions tab shows the things that result in calls to your destination
the trigger field on the actions tab shows the things that result in calls to your destination
the filter field within an action lets you choose the trigger(s) for an action
the filter field within an action lets you choose the trigger(s) for an action

Data Structure

The Data Structure for each action determines the source data that we set for the fields that your destination expects. Data structures use JSON notation for variables—but you don’t necessarily need to know JSON notation to change values. When you opt to change a mapping on the left, we’ll give you a drop-down of available Variables that you can select from incoming source payloads.

In most cases, if you want to manipulate values, you’ll want to do it at your source—in your code. But we offer a couple of functions that can make things a little easier on you. Read more about the case and coalesce functions below.

 Pick variables that match your source filter

The list of available variables covers all possible source events. It isn’t limited to the type or event in your source filter. If the action is based on an incoming identify event, and you try to map a field to $.event, that field will always be null, because identify calls don’t include an event!

map properties in the source event to your destination
map properties in the source event to your destination

Mapping to traits and event properties

While we know that incoming identify calls contain traits and incoming track calls likely contain properties, we don’t know what those properties are or might be. If you want to map to a specific trait or event property, you’ll need to provide it yourself—under traits.<trait-name> or properties.<property-name> respectively.

Make sure that your requests reliably provide the trait or event property in your source events or the property will be empty when we send data to your destination!

The case function

The case function is simple: it converts a value’s case to lower or upper. You might use this function to enforce uniform cases in a destination. For example, you might want to store your users’ names in lowercase for uniformity.

The case function uses the format case(sourcekey, "lower/upper").

case(traits.first_name, "lower")

The coalesce function

The coalesce function picks the first non-null value in a list of possible values. That’s a fancy way of saying that it uses the first non-empty value that it finds in the incoming source payload.

The coalesce function uses the format coalesce(firstkey, secondkey). Only two arguments are supported at the moment.

For example, Customer.io lets you identify people by id or email address. So, when you use Customer.io as a destination, we set the Person ID to coalesce($.userId, $.traits.email). This simply means that if the request has a userId, we’ll map that to the person’s ID. If it doesn’t, we’ll map the email trait to the person’s ID.

If you use coalesce, and none of the keys are populated, the trait and the corresponding mapping will be null (empty).

flowchart LR a("coalesce(userId, traits.email)")-->b{Does the call
have a userId} b-->|yes|c(Person ID = userId) b-.->|no|d{"Does the call have
an email trait?"} d-->|yes|e(Person ID = traits.email) d-.->|no|f(Person ID = null)

Hash function

The hash function lets you hash a value using the SHA-256 algorithm. This is useful if you want to hash an email address or other personally identifiable information (PII) before sending it to a destination.

hash(traits.email)

Slugify function

The slugify function converts a value to a slug—a value that consists only of letters, numbers, and hyphens. Slugifying a value removes all special characters, converts spaces to hyphens, and removes multiple hyphens. For example, slugify("Hello, World!") returns hello-world.

This might be useful when you want to convert a value to a URL-friendly identifier. For example, if you want to convert an email address to a slug that you use to identify a person in destination.

slugify(traits.email)

Empty source and destination values

You can map values to destinations, but that doesn’t guarantee that those values are populated in your source events.

Most source calls only require an ID of some sort or an event name, so you won’t necessarily receive errors if you send source data that doesn’t fully populate all the data you want to capture at your destination. You’ll need to make sure sure that your sources send the right data—traits, event properties, etc—that you want to map to your destinations.

Copied to clipboard!
  Contents
Is this page helpful?