Auto-tag orders that contain a matching product, with Mechanic.

Mechanic is a development and ecommerce automation platform for Shopify. :)

Auto-tag orders that contain a matching product

This task watches for incoming orders, and tags them if they contain a product that matches by title or by product tags. Additionally, edited orders will have tags added or removed in line with product additions or removals. Run this task manually to scan your store's order history, tagging older orders that qualify, and untagging those that have been edited and no longer do.

Runs Occurs whenever an order is created, Occurs whenever an order is edited, Occurs when a user manually triggers the task, and Occurs when a bulk operation is completed. Configuration includes required product title, required product tags, and order tags to apply.

15-day free trial – unlimited tasks

Documentation

This task watches for incoming orders, and tags them if they contain a product that matches by title or by product tags. Additionally, edited orders will have tags added or removed in line with product additions or removals. Run this task manually to scan your store's order history, tagging older orders that qualify, and untagging those that have been edited and no longer do.

Note: If more than one required product tag is specified, this task will look for products that individually contain all of the tags provided.

Developer details

Mechanic is designed to benefit everybody: merchants, customers, developers, agencies, Shopifolks, everybody.

That’s why we make it easy to configure automation without code, why we make it easy to tweak the underlying code once tasks are installed, and why we publish it all here for everyone to learn from.

(By the way, have you seen our documentation? Have you joined the Slack community?)

Open source
View on GitHub to contribute to this task
Subscriptions
shopify/orders/create
shopify/orders/edited
mechanic/user/trigger
mechanic/shopify/bulk_operation
Tasks use subscriptions to sign up for specific kinds of events. Learn more
Options
required product title, required product tags (array), order tags to apply (required, array)
Code
{% comment %}
  Ordering the task options:

  {{ options.required_product_title }}
  {{ options.required_product_tags__array }}
  {{ options.order_tags_to_apply__required_array }}
{% endcomment %}

{% if options.required_product_title == blank and options.required_product_tags__array == blank %}
  {"error": "Fill in at least one of 'Required product title' and 'Required product tags'. :)"}
{% endif %}

{% if event.topic contains "shopify/orders/" %}
  {% capture query %}
    query {
      order(id: {{ order_edit.order.admin_graphql_api_id | default: order.admin_graphql_api_id | json }}) {
        id
        tags
        lineItems(first: 250) {
          edges {
            node {
              currentQuantity
              product {
                id
                title
                tags
              }
            }
          }
        }
      }
    }
  {% endcapture %}

  {% assign result = query | shopify %}

  {% if event.preview %}
    {% capture result_json %}
      {
        "data": {
          "order": {
            "id": "gid://shopify/Order/1234567890",
            "tags": [],
            "lineItems": {
              "edges": [
                {
                  "node": {
                    "currentQuantity": 1,
                    "product": {
                      "id": "gid://shopify/Product/1234567890",
                      "title": {{ options.required_product_title | json }},
                      "tags": {{ options.required_product_tags__array | json }}
                    }
                  }
                }
              ]
            }
          }
        }
      }
    {% endcapture %}

    {% assign result = result_json | parse_json %}
  {% endif %}

  {% assign order = result.data.order %}
  {% assign line_items = order.lineItems.edges | map: "node" %}

  {% assign order_qualifies = false %}
  {% assign order_qualifies_by_tag = nil %}
  {% assign order_qualifies_by_title = nil %}

  {% assign current_line_items = array %}

  {% for line_item in line_items %}
    {% if line_item.currentQuantity > 0 %}
      {% assign current_line_items[current_line_items.size] = line_item %}
    {% endif %}
  {% endfor %}

  {% assign order_products = current_line_items | map: "product" %}

  {% if options.required_product_title != blank %}
    {% assign order_qualifies_by_title = false %}

    {% assign order_product_titles = order_products | map: "title" %}

    {% if order_product_titles contains options.required_product_title %}
      {% assign order_qualifies_by_title = true %}
    {% endif %}
  {% endif %}

  {% if options.required_product_tags__array != blank %}
    {% assign order_qualifies_by_tag = false %}

    {% for order_product in order_products %}
      {% assign order_product_qualifies_by_tag = true %}

      {% for required_tag in options.required_product_tags__array %}
        {% unless order_product.tags contains required_tag %}
          {% assign order_product_qualifies_by_tag = false %}
          {% break %}
        {% endunless %}
      {% endfor %}

      {% if order_product_qualifies_by_tag %}
        {% assign order_qualifies_by_tag = true %}
        {% break %}
      {% endif %}
    {% endfor %}
  {% endif %}

  {% comment %}
    Make sure *at least one* of the two qualifications were evaluated,
    and make sure neither of them outright failed.
  {% endcomment %}
  {% if order_qualifies_by_tag != nil or order_qualifies_by_title != nil %}
    {% if order_qualifies_by_tag != false and order_qualifies_by_title != false %}
      {% assign order_qualifies = true %}
    {% endif %}
  {% endif %}

  {% if order_qualifies %}
    {% action "shopify" %}
      mutation {
        tagsAdd(
          id: {{ order.id | json }}
          tags: {{ options.order_tags_to_apply__required_array | json }}
        ) {
          userErrors {
            field
            message
          }
        }
      }
    {% endaction %}
  {% else %}
    {% for order_tag_to_apply in options.order_tags_to_apply__required_array %}
      {% if order.tags contains order_tag_to_apply %}
        {% action "shopify" %}
          mutation {
            tagsRemove(
              id: {{ order.id | json }}
              tags: {{ options.order_tags_to_apply__required_array | json }}
            ) {
              userErrors {
                field
                message
              }
            }
          }
        {% endaction %}
        {% break %}
      {% endif%}
    {% endfor %}
  {% endif %}

{% elsif event.topic == "mechanic/user/trigger" %}
  {% capture bulk_operation_query %}
    query {
      orders {
        edges {
          node {
            __typename
            id
            tags
            lineItems {
              edges {
                node {
                  __typename
                  id
                  currentQuantity
                  product {
                    id
                    title
                    tags
                  }
                }
              }
            }
          }
        }
      }
    }
  {% endcapture %}

  {% action "shopify" %}
    mutation {
      bulkOperationRunQuery(
        query: {{ bulk_operation_query | json }}
      ) {
        bulkOperation {
          id
          status
        }
        userErrors {
          field
          message
        }
      }
    }
  {% endaction %}

{% elsif event.topic == "mechanic/shopify/bulk_operation" %}
  {% if event.preview %}
    {% assign bulkOperation = hash %}
    {% assign bulkOperation["objects"] = array %}

    {% assign order = hash %}
    {% assign order["__typename"] = "Order" %}
    {% assign order["id"] = "gid://shopify/Order/1234567890" %}
    {% assign order["tags"] = array %}

    {% assign product = hash %}
    {% assign product["title"] = options.required_product_title %}
    {% assign product["tags"] = options.required_product_tags__array %}

    {% assign lineItem = hash %}
    {% assign lineItem["__typename"] = "LineItem" %}
    {% assign lineItem["__parent"] = order %}
    {% assign lineItem["currentQuantity"] = 1 %}
    {% assign lineItem["product"] = product %}

    {% assign bulkOperation["objects"][0] = order %}
    {% assign bulkOperation["objects"][1] = lineItem %}
  {% endif %}

  {% assign qualifying_order_ids = array %}
  {% assign order_ids_that_already_have_tags = array %}

  {% for object in bulkOperation.objects %}
    {% case object.__typename %}
    {% when "Order" %}
      {% assign order_already_has_tags = true %}
      {% for tag in options.order_tags_to_apply__required_array %}
        {% unless object.tags contains tag %}
          {% assign order_already_has_tags = false %}
        {% endunless %}
      {% endfor %}

      {% if order_already_has_tags %}
        {% assign order_ids_that_already_have_tags[order_ids_that_already_have_tags.size] = object.id %}
      {% endif %}
    {% when "LineItem" %}
      {% assign product = object.product %}

      {% assign product_qualifies = false %}
      {% assign product_qualifies_by_tag = nil %}
      {% assign product_qualifies_by_title = nil %}

      {% if options.required_product_title != blank %}
        {% assign product_qualifies_by_title = false %}

        {% if product.title == options.required_product_title %}
          {% assign product_qualifies_by_title = true %}
        {% endif %}
      {% endif %}

      {% if options.required_product_tags__array != blank %}
        {% assign product_qualifies_by_tag = true %}
        {% for required_tag in options.required_product_tags__array %}
          {% unless product.tags contains required_tag %}
            {% assign product_qualifies_by_tag = false %}
            {% break %}
          {% endunless %}
        {% endfor %}
      {% endif %}

      {% comment %}
        Make sure *at least one* of the two qualifications were evaluated,
        and make sure neither of them outright failed.
      {% endcomment %}
      {% if product_qualifies_by_tag != nil or product_qualifies_by_title != nil %}
        {% if product_qualifies_by_tag != false and product_qualifies_by_title != false %}
          {% assign product_qualifies = true %}
        {% endif %}
      {% endif %}

      {% if product_qualifies and object.currentQuantity > 0 %}
        {% assign qualifying_order_ids[qualifying_order_ids.size] = object.__parent.id %}
      {% endif %}
    {% endcase %}
  {% endfor %}

  {% assign qualifying_order_ids = qualifying_order_ids | uniq %}
  {% assign order_ids_that_already_have_tags = order_ids_that_already_have_tags | uniq %}

  {% for order_id in qualifying_order_ids %}
    {% unless order_ids_that_already_have_tags contains order_id %}
      {% action "shopify" %}
        mutation {
          tagsAdd(
            id: {{ order_id | json }}
            tags: {{ options.order_tags_to_apply__required_array | json }}
          ) {
            userErrors {
              field
              message
            }
          }
        }
      {% endaction %}
    {% endunless %}
  {% endfor %}

  {% for order_id in order_ids_that_already_have_tags %}
    {% unless qualifying_order_ids contains order_id %}
      {% action "shopify" %}
        mutation {
          tagsRemove(
            id: {{ order_id | json }}
            tags: {{ options.order_tags_to_apply__required_array | json }}
          ) {
            userErrors {
              field
              message
            }
          }
        }
      {% endaction %}
    {% endunless %}
  {% endfor %}
{% endif %}
Task code is written in Mechanic Liquid, an extension of open-source Liquid enhanced for automation. Learn more