Auto-tag customers based on discount codes used, with Mechanic.

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

Auto-tag customers based on discount codes used

Use this task to easily identify customers who used certain discount codes. This task runs automatically on incoming orders, and can be run manually to tag customers based on historical orders. Optionally, choose to remove tags, instead of adding them.

Runs Occurs whenever an order is created, Occurs when a user manually triggers the task, and Occurs when a bulk operation is completed. Configuration includes discount codes and tags, untag customers instead of tagging them, and allow partial matches when checking for discount codes.

15-day free trial – unlimited tasks

Documentation

Use this task to easily identify customers who used certain discount codes. This task runs automatically on incoming orders, and can be run manually to tag customers based on historical orders. Optionally, choose to remove tags, instead of adding them.

This task runs automatically on incoming orders. Run this task manually to scan your store's order history, tagging customers based on historical orders.

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
mechanic/shopify/bulk_operation
Tasks use subscriptions to sign up for specific kinds of events. Learn more
Options
discount codes and tags (keyval, required), untag customers instead of tagging them (boolean), allow partial matches when checking for discount codes (boolean)
Code
{% assign discount_codes_and_tags = options.discount_codes_and_tags__keyval_required %}
{% assign untag_customers_instead_of_tagging_them = options.untag_customers_instead_of_tagging_them__boolean %}
{% assign allow_partial = options.allow_partial_matches_when_checking_for_discount_codes__boolean %}

{% if event.topic == "shopify/orders/create" %}
  {% comment %}
    -- for new orders, only check discounts on that order, not all of a customer's orders
  {% endcomment %}

  {% capture query %}
    query {
      order(id: {{ order.admin_graphql_api_id | json }}) {
        discountCodes
        customer {
          id
          tags
        }
      }
    }
  {% endcapture %}

  {% assign result = query | shopify %}

  {% if event.preview %}
    {% capture result_json %}
      {
        "data": {
          "order": {
            "discountCodes": {{ discount_codes_and_tags | keys | json }},
            "customer": {
              "id": "gid://shopify/Customer/1234567890"
            }
          }
        }
      }
    {% endcapture %}

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

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

  {% if order.discountCodes == blank %}
    {% log "No discount codes for this order; nothing to do." %}
    {% break %}
  {% endif %}

  {% assign order_discount_codes_downcase
    = order.discountCodes
    | json
    | downcase
    | parse_json
  %}

  {% assign customer_tags_downcase
    = customer.tags
    | json
    | downcase
    | parse_json
  %}

  {% assign tags_to_add = array %}
  {% assign tags_to_remove = array %}

  {% comment %}
    -- use downcased strings for code and tag comparisons; however, add/remove tags using the configured values
  {% endcomment %}

  {% for keyval in discount_codes_and_tags %}
    {% assign discount_code_downcase = keyval[0] | downcase %}
    {% assign tag_downcase = keyval[1] | downcase %}

    {% if allow_partial %}
      {% for order_discount_code_downcase in order_discount_codes_downcase %}
        {% if order_discount_code_downcase contains discount_code_downcase %}
          {% if untag_customers_instead_of_tagging_them %}
            {% if customer_tags_downcase contains tag_downcase %}
              {% assign tags_to_remove = tags_to_remove | push: keyval[1] %}
            {% endif %}

          {% else %}
            {% unless customer_tags_downcase contains tag_downcase %}
              {% assign tags_to_add = tags_to_add | push: keyval[1] %}
            {% endunless %}
          {% endif %}

          {% break %}
        {% endif %}
      {% endfor %}

    {% elsif order_discount_codes_downcase contains discount_code_downcase %}
      {% if untag_customers_instead_of_tagging_them %}
        {% if customer_tags_downcase contains tag_downcase %}
          {% assign tags_to_remove = tags_to_remove | push: keyval[1] %}
        {% endif %}

      {% else %}
        {% unless customer_tags_downcase contains tag_downcase %}
          {% assign tags_to_add = tags_to_add | push: keyval[1] %}
        {% endunless %}
      {% endif %}
    {% endif %}
  {% endfor %}

  {% if tags_to_add != blank %}
    {% action "shopify" %}
      mutation {
        tagsAdd(
          id: {{ customer.id | json }}
          tags: {{ tags_to_add | json }}
        ) {
          userErrors {
            field
            message
          }
        }
      }
    {% endaction %}
  {% endif %}

  {% if tags_to_remove != blank %}
    {% action "shopify" %}
      mutation {
        tagsRemove(
          id: {{ customer.id | json }}
          tags: {{ tags_to_remove | json }}
        ) {
          userErrors {
            field
            message
          }
        }
      }
    {% endaction %}
  {% endif %}

{% elsif event.topic == "mechanic/user/trigger" %}
  {% comment %}
    -- get all customers who have placed an order, and each of their orders where one or more discount codes were used
  {% endcomment %}

  {% capture bulk_operation_query %}
    query {
      customers(query: "orders_count:>0") {
        edges {
          node {
            __typename
            id
            tags
            orders(query: "discount_code:*") {
              edges {
                node {
                  __typename
                  discountCodes
                }
              }
            }
          }
        }
      }
    }
  {% 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 %}
    {% capture jsonl_string %}
      {"__typename": "Customer","id": "gid://shopify/Customer/1234567890"}
      {"__typename": "Order","discountCodes":{{ discount_codes_and_tags | keys | json }},"__parentId":"gid://shopify/Customer/1234567890"}
      {"__typename": "Customer","id": "gid://shopify/Customer/2345678901","tags":{{ discount_codes_and_tags | values | json }}}
      {"__typename": "Order","discountCodes":{{ discount_codes_and_tags | keys | json }},"__parentId":"gid://shopify/Customer/2345678901"}
    {% endcapture %}

    {% assign bulkOperation = hash %}
    {% assign bulkOperation["objects"] = jsonl_string | parse_jsonl %}
  {% endif %}

  {% assign customers = bulkOperation.objects | where: "__typename", "Customer" %}
  {% assign orders = bulkOperation.objects | where: "__typename", "Order" %}

  {% comment %}
    -- loop through customers to see which qualify for tag updates
  {% endcomment %}

  {% for customer in customers %}
    {% assign customer_orders = orders | where: "__parentId", customer.id %}

    {% if customer_orders == blank %}
      {% continue %}
    {% endif %}

    {% assign customer_discount_codes_downcase = array %}

    {% for customer_order in customer_orders %}
      {% assign customer_discount_codes_downcase
        = customer_order.discountCodes
        | json
        | downcase
        | parse_json
        | concat: customer_discount_codes_downcase
        | uniq
      %}
    {% endfor %}

    {% assign customer_tags_downcase
      = customer.tags
      | json
      | downcase
      | parse_json
    %}

    {% assign tags_to_add = array %}
    {% assign tags_to_remove = array %}

    {% comment %}
      -- use downcased strings for code and tag comparisons; however, add/remove tags using the configured values
    {% endcomment %}

    {% for keyval in discount_codes_and_tags %}
      {% assign discount_code_downcase = keyval[0] | downcase %}
      {% assign tag_downcase = keyval[1] | downcase %}

      {% if allow_partial %}
        {% for customer_discount_code_downcase in customer_discount_codes_downcase %}
          {% if customer_discount_code_downcase contains discount_code_downcase %}
            {% if untag_customers_instead_of_tagging_them %}
              {% if customer_tags_downcase contains tag_downcase %}
                {% assign tags_to_remove = tags_to_remove | push: keyval[1] %}
              {% endif %}

            {% else %}
              {% unless customer_tags_downcase contains tag_downcase %}
                {% assign tags_to_add = tags_to_add | push: keyval[1] %}
              {% endunless %}
            {% endif %}

            {% break %}
          {% endif %}
        {% endfor %}

      {% elsif customer_discount_codes_downcase contains discount_code_downcase %}
        {% if untag_customers_instead_of_tagging_them %}
          {% if customer_tags_downcase contains tag_downcase %}
            {% assign tags_to_remove = tags_to_remove | push: keyval[1] %}
          {% endif %}

        {% else %}
          {% unless customer_tags_downcase contains tag_downcase %}
            {% assign tags_to_add = tags_to_add | push: keyval[1] %}
          {% endunless %}
        {% endif %}
      {% endif %}
    {% endfor %}

    {% if tags_to_add != blank %}
      {% action "shopify" %}
        mutation {
          tagsAdd(
            id: {{ customer.id | json }}
            tags: {{ tags_to_add | uniq | json }}
          ) {
            userErrors {
              field
              message
            }
          }
        }
      {% endaction %}
    {% endif %}

    {% if tags_to_remove != blank %}
      {% action "shopify" %}
        mutation {
          tagsRemove(
            id: {{ customer.id | json }}
            tags: {{ tags_to_remove | uniq | json }}
          ) {
            userErrors {
              field
              message
            }
          }
        }
      {% endaction %}
    {% endif %}
  {% endfor %}
{% endif %}
Task code is written in Mechanic Liquid, an extension of open-source Liquid enhanced for automation. Learn more