Responding to action results

Sometimes, you'll want to do more than a single round of generating actions – you may want to check the results of an action, see if they appear the way you expect, and then perform additional actions based on the results.

To achieve this flow, subscribe to the "mechanic/actions/perform" topic. When a task includes this subscription, Mechanic will generate an event with that topic for every action that the task completes. Task runs responding to this event topic receive the action variable, containing everything available in event.data.

Data for an action consists of the following attributes:

  • type – a lowercase string, defining the action type
  • options – the options with which the action was configured
  • run – an object containing the following attributes, describing the run that was generated by the action's performance
    • id – a string containing the UUID for this action
    • ok – a boolean, true for a successful action run, and false for a failure
    • error – either null, or a string containing the error message returned for a failed action
    • result – the data returned from the action; format varies by action type
    • result_meta – an object containing useful performance-related data
    • attempts – an integer, indicating the number of times the action was attempted before final success or failure
    • enqueued_at – the time at which this action was sent to our queue for execution
    • started_at – the time at which the action started
    • stopped_at – the time at which the action stopped
    • elapsed_time_ms – the number of milliseconds this action required, from start to stop

Usage warning

It's important to specifically account for the "mechanic/actions/perform" topic when writing your task script, minding the fact that improper composition could result in an infinite loop. (Having said that, Mechanic will step in and forcibly fail subsequent task runs that contain results identical to their predecessors.)

Remember, you can use "log" tags to return data without requiring an action.

Example task

This example prompts the Mechanic user to enter a chunk of JSON, which will be used to create a customer record via a "shopify" action. If Shopify reports back that the customer creation was successful, the task will generate an "echo" action, reporting the success. If not, another "echo" will be generated, reporting the specific error message from Shopify.

Subscriptions

mechanic/user/text
mechanic/actions/perform

Script

Note: This script is written to specifically support preview actions, generating stub data during event preview to ensure that appropriate preview actions are generated.

{% if event.topic == "mechanic/user/text" %}
  {% if event.preview %}
    {% assign event = hash %}
    {% assign event["topic"] = "mechanic/user/text" %}
    {% assign event["data"] = '{"email":"customer@example.com"}' %}
  {% endif %}

  {% assign data = event.data | default: "{}" | parse_json %}
  {% action "shopify", "create", "customer", data %}
{% elsif event.topic == "mechanic/actions/perform" %}
  {% if event.preview %}
    {% assign action = hash %}
    {% assign action["type"] = "shopify" %}
    {% assign action["run"] = hash %}
    {% assign action["run"]["ok"] = true %}
  {% endif %}

  {% if action.type == "shopify" %}
    {% if action.run.ok %}
      {% action "echo" "Success!" %}
    {% else %}
      {% action "echo" "Invalid data!", action.run.error %}
    {% endif %}
  {% else %}
    {% comment %}
      This branch is where the task ultimately terminates. At
      this point, we're still processing performed actions, but
      we know that the action type here must be something other
      than our initial "shopify" action. And clearly, it's
      "echo", and we don't need to do anything with it. This
      final task run will therefore perform no actions, which
      means that the run sequence will finally conclude.
    {% endcomment %}
  {% endif %}
{% endif %}
Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.