All pages
Powered by GitBook
1 of 5

Code

A task's code is a Liquid template. In the same way that a Shopify storefront might use a Liquid template to receive requests and render HTML, a task uses its Liquid code to receive events, and render a series of JSON objects. These JSON objects define actions, logs, and errors.

In Mechanic, actions are performed after their originating task run concludes. Actions are not performed inline during the task's Liquid rendering.

To inspect and respond to the results of an HTTP action, add a task subscription to mechanic/actions/perform, allowing the action to re-invoke the task with the action result data.

Learn more: Responding to action results

Task code always has access to a set of environment variables, which can be used to make decisions about what JSON objects to render.

A task must purposefully consider its preview, so as to accurately communicate its intent to users and to the Mechanic platform.

To find many examples of task code, browse https://github.com/lightward/mechanic-tasks.

Environment variables

A task's Liquid code always has access to a set of environment variables, defined by Mechanic.

Environment variables may be reassigned as needed. (When preparing a task preview, this may be a necessary technique.) To learn more, see Stub data.

Variable

Contents

shop

An object containing Shopify's REST representation of the current Shopify store

event

An object containing information about the current event

cache

The current store's Mechanic cache object, supporting lookups for cached values

task

An object containing information about the current task

options

An object containing task options, configured by the user

The Shopify variables available to tasks always contain data drawn from the event itself. If a task has a offset event subscription, this data may be outdated by the time the task runs.

To reload the data in a Shopify variable, use something like this:

{% unless event.preview %}
  {% assign customer = customer.reload %}
{% endunless %}

Remember, Mechanic does not permit access to the Shopify API during event preview. Using this unless statement ensures that reloading only happens during a live event.

Event subject variables

When a task is actually invoked for an event, it may have access to an additional variable, determined by the specific event it is responding to. When this is the case, the additional variable will be named after the event subject, and its contents will be established by the event's data. The name of this variable is communicated by the Mechanic task editor, based on the task's current subscriptions.

For example, a subscription to shopify/customers/create will make available a variable called customer. A subscription to shopify/products/update will expose a variable called product, etc.

Shopify variables

All Shopify events support an additional variable named after the event topic. For example, when a task responds to a shopify/customers/create event, it will have access to an additional variable named customer, containing the customer data contained in the event.

Shopify events always contain data from Shopify's REST representation of each resource; therefore, automatic Shopify variables always contain data from the REST representation as well. The best resource for the data available for each variable type is Shopify's REST Admin API reference.

Shopify variables in Mechanic do not necessarily contain the same attributes as Liquid variables used in Shopify (in places like themes or email templates) – even if they share the same name.

In Mechanic, Shopify variables always contain data from Shopify events, which are delivered to Mechanic via webhook. This means that Shopify variables always have the same data structure as Shopify webhooks, corresponding to Shopify's REST representation for this data.

For example, while Shopify themes support customer.name, Mechanic does not (because Shopify's REST representation of the customer resource does not contain a "name" property). On the other hand, Mechanic supports customer.created_at, while Shopify themes do not.

Action objects

An action object defines work to be performed by an action, after the task is fully finished rendering. Action objects are most easily generated using the action tag.

An action object is a plain JSON object, having the following structure:

{
  "action": {
    "type": ACTION_TYPE,
    "options": ACTION_OPTIONS,
    "meta": ACTION_META
  }
}

Use the action tag to skip the boilerplate while writing actions. All tasks in the Mechanic task library use the action tag, rather than writing out the action object in raw JSON.

In Mechanic, actions are performed after their originating task run concludes. Actions are not performed inline during the task's Liquid rendering.

To inspect and respond to the results of an HTTP action, add a task subscription to mechanic/actions/perform, allowing the action to re-invoke the task with the action result data.

Learn more: Responding to action results

Defining an action

Type

The action type is always a string, having a value that corresponds to a supported action (e.g. "shopify", or "http").

Options

Action options vary by action type. Depending on the action type, its options may be another complete object, or an array, or a scalar value.

Meta

Actions may optionally include meta information, annotating the action with any JSON value.

This information could be purely for record-keeping, making it easy to determine why an action was rendered, or to add helpful context:

{
  "action": {
    "type": "shopify",
    "options": [
      "post",
      "/admin/customers/1234567890/send_invite.json",
      {}
    ],
    "meta": {
      "invite_reason": "alpha",
      "customer_email": "customer@example.com"
    }
  }
}

Or, this information could be used to facilitate complex task flows, in concert with a subscription to mechanic/actions/perform (see Responding to action results). An action's meta information can supply followup task runs with information about state, allowing the task to cycle between different phases of operation.

{% if event.topic contains "trigger" %}
  {% action %}
    {
      "type": "cache",
      "options": ["set", "foo", "bar"],
      "meta": {
        "mode": "first"
      }
    }
  {% endaction %}
{% elsif action.meta.mode == "first" %}
  {% action %}
    {
      "type": "cache",
      "options": ["set", "foo", "bar"],
      "meta": {
        "mode": "second"
      }
    }
  {% endaction %}
{% elsif action.meta.mode == "second" %}
  {% action "echo", "done" %}
{% endif %}

Error objects

When a task renders an error object, the task run will be marked as failed, and no rendered action runs will be performed. This is a good way to communicate an intentional failure to the user, when your Liquid code detects a certain condition.

A task that renders an error object during preview will interrupt the preview, and visibly communicate the error to the user. This makes error objects a useful way to validate task options.

Unlike a "raised" exception in other programming languages, a rendered error object is simply added to the list of the task run's JSON objects. At the completion of task code rendering, all objects are evaluated; at that point, if an error object is among them, the error is then raised and shown to the user.

An error object does not halt rendering of the task's Liquid code, but it does prevent any other rendered objects from having an effect. Specifically, this means that the presence of an error object means that any action objects will be ignored.

This also means that rendering an error object will not prevent the task from reaching any syntax errors (or other problematic code) later on in the task's Liquid code.

An error object is a plain JSON object, having the following structure:

{
  "error": ERROR_DETAILS
}

The error details can be any JSON value. This value will be represented to the user as the reason for the task failing.

Error objects are most easily generated using the error tag.

Log objects

Log objects are useful for recording information for later reference. They have no side-effects. Carefully chosen log objects can massively simplify post-hoc debugging, especially (as we've found) when investigating merchant bug reports.

A log object is a plain JSON object, having the following structure:

{
  "log": LOG_DETAILS
}

The log details can be any JSON value.

Log objects are most easily generated using the log tag.

Log objects appear wherever task run results are visible, including the task preview and when viewing an event.

A log object visible in a task preview
A log object visible in a task run's result