Auto-tag customers with product tags from their order, with Mechanic.

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

Auto-tag customers with product tags from their order

When orders come in, this task will copy tags from the order's products to the customer. Useful for automatically segmenting your customers based on attributes of their purchases. To keep things tidy, configure this task to only copy certain product tags.

Runs Occurs whenever an order is created and Occurs when a user manually triggers the task. Configuration includes limit to customers matching this query for manual runs and only copy these tags.

15-day free trial – unlimited tasks

Documentation

When orders come in, this task will copy tags from the order's products to the customer. Useful for automatically segmenting your customers based on attributes of their purchases. To keep things tidy, configure this task to only copy certain product tags.

This task may be run manually, to scan and tag customers based on the configured criteria. You may also configure a customer segment query, limiting the set of customers that are processed on manual runs. For example, to only include customers that have placed at least one order, use this query: number_of_orders > 0

Important: The customer segment query must use the exact casing and syntax as a query that is run from the customer segments admin screen. More information on the the syntax for these can be found here.

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
mechanic/user/trigger
Tasks use subscriptions to sign up for specific kinds of events. Learn more
Options
limit to customers matching this query for manual runs, only copy these tags (array)
Code
{% assign customer_segment_query = options.limit_to_customers_matching_this_query_for_manual_runs %}
{% assign only_copy_these_tags = options.only_copy_these_tags__array %}

{% assign customer_ids = array %}

{% if event.topic == "shopify/orders/create" %}
  {% assign customer_ids[0] = order.customer.admin_graphql_api_id %}

{% elsif event.topic == "mechanic/user/trigger" %}
  {% comment %}
    -- get IDs of all customers who match the segment query
    -- Note: a segment query cannot be null, so if one has not been configured in the task then send an empty string
  {% endcomment %}

  {% assign cursor = nil %}
  {% assign customer_segment_member_ids = array %}

  {% for n in (1..100) %}
    {% capture query %}
      query {
        customerSegmentMembers(
          first: 1000
          after: {{ cursor | json }}
          query: {{ customer_segment_query | default: "" | json }}
        ) {
          pageInfo {
            hasNextPage
            endCursor
          }
          edges {
            node {
              id
            }
          }
        }
      }
    {% endcapture %}

    {% assign result = query | shopify %}

    {% assign customer_segment_members = result.data.customerSegmentMembers.edges | map: "node" %}

    {% comment %}
      -- remove the "SegmentMember" portion from IDs so they can be processed with same code block for the orders/create event
    {% endcomment %}

    {% for customer_segment_member in customer_segment_members %}
      {% assign customer_ids[customer_ids.size] = customer_segment_member.id | remove: "SegmentMember" %}
    {% endfor %}

    {% if result.data.customerSegmentMembers.pageInfo.hasNextPage %}
      {% assign cursor = result.data.customerSegmentMembers.pageInfo.endCursor %}
    {% else %}
      {% break %}
    {% endif %}
  {% endfor %}

  {% unless event.preview %}
    {% log count_of_customers_matching_query: customer_ids.size %}
  {% endunless %}
{% endif %}

{% if event.preview %}
  {% assign customer_ids[0] = "gid://shopify/Customer/1234567890" %}
{% endif %}

{% for customer_id in customer_ids %}
  {% comment %}
    -- get all relevant order data for this customer
  {% endcomment %}

  {% assign cursor = nil %}
  {% assign tags_to_copy = array %}

  {% for n in (1..10) %}
    {% capture query %}
      query {
        customer(id: {{ customer_id | json }}) {
          id
          tags
          orders(
            first: 250
            after: {{ cursor | json }}
          ) {
            pageInfo {
              hasNextPage
              endCursor
            }
            nodes {
              id
              lineItems(first: 250) {
                nodes {
                  product {
                    tags
                  }
                }
              }
            }
          }
        }
      }
    {% endcapture %}

    {% assign result = query | shopify %}

    {% if event.preview %}
      {% capture result_json %}
        {
          "data": {
            "customer": {
              "id": "gid://shopify/Customer/1234567890",
              "orders": {
                "nodes": [
                  {
                    "id": "gid://shopify/Order/1234567890",
                    "lineItems": {
                      "nodes": [
                        {
                          "product": null
                        },
                        {
                          "product": {
                            "tags": [
                              "preview",
                              {{ only_copy_these_tags.first | json }}
                            ]
                          }
                        }
                      ]
                    }

                  }
                ]
              }
            }
          }
        }
      {% endcapture %}

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

    {% assign customer = result.data.customer %}

    {% for order in customer.orders.nodes %}
      {% for line_item in order.lineItems.nodes %}
        {% for tag in line_item.product.tags %}
          {% if tags_to_copy contains tag or customer.tags contains tag %}
            {% continue %}
          {% endif %}

          {% if only_copy_these_tags != blank %}
            {% unless only_copy_these_tags contains tag %}
              {% continue %}
            {% endunless %}
          {% endif %}

          {% assign tags_to_copy = tags_to_copy | push: tag %}
        {% endfor %}
      {% endfor %}
    {% endfor %}

    {% if result.data.customer.orders.pageInfo.hasNextPage %}
      {% assign cursor = result.data.customer.orders.pageInfo.endCursor %}
    {% else %}
      {% break %}
    {% endif %}
  {% endfor %}

  {% if tags_to_copy != blank %}
    {% action "shopify" %}
      mutation {
        tagsAdd(
          id: {{ customer.id | json }}
          tags: {{ tags_to_copy | json }}
        ) {
          userErrors {
            field
            message
          }
        }
      }
    {% endaction %}
  {% endif %}
{% endfor %}
Task code is written in Mechanic Liquid, an extension of open-source Liquid enhanced for automation. Learn more
Defaults
Limit to customers matching this query for manual runs
number_of_orders > 0