Auto-tag customers having a rolling minimum total spend, with Mechanic.

Mechanic is an automation development platform for Shopify. :)

Auto-tag customers having a rolling minimum total spend

by Isaac Bowen (team@usemechanic.com)

Use this task to tag customers who reach a certain spending threshold, by scanning a rolling period of order history. Useful for rewarding customers who keep a consistent spend total.

Runs when a user triggers the task, every day at midnight, when an order is created, when an order is updated, and when an order is deleted. Configuration includes minimum total spent, customer tag, and days of order history to consider.

15-day free trial – unlimited tasks

Documentation

Run this task manually to scan all of your customers. This may take some time!

This task will also scan all customers on a nightly basis, and will run for a single customer every time a customer's order is paid or cancelled.

Note: By default, Mechanic only scans the last 60 days of order history. To change this, follow this tutorial.

Developer details

Mechanic is designed to benefit everybody: merchants, customers, developers, agencies, Gurus, 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.

Events
when a user triggers the task (mechanic/user/trigger)
every day at midnight (mechanic/scheduler/daily)
when an order is created (shopify/orders/create)
when an order is updated (shopify/orders/updated)
when an order is deleted (shopify/orders/delete)
Options
minimum total spent (number, required), customer tag (required), days of order history to consider (number, required)
Script
{% comment %}
  express a preference for which option appears first
  {{ options.minimum_total_spent__number_required }}
  {{ options.customer_tag__required }}
  {{ options.days_of_order_history_to_consider__number_required }}
{% endcomment %}

{% assign acceptable_order_financial_statuses = "paid partially_paid partially_refunded" | split: " " %}
{% assign acceptable_transaction_kinds = "sale capture refund" | split: " " %}

{% assign days_in_seconds = options.days_of_order_history_to_consider__number_required | times: 24 | times: 60 | times: 60 %}
{% assign min_created_at = "now" | date: "%s" | times: 1 | minus: days_in_seconds %}

{% if event.preview %}
  {
    "action": {
      "type": "shopify",
      "options": [
        "update",
        [
          "customer",
          1234567890
        ],
        {
          "tags": {{ options.customer_tag__required | json }}
        }
      ]
    }
  }
{% else %}
  {% for customer in shop.customers %}
    {% if event.topic contains "shopify/orders" and event.topic != "shopify/orders/delete" and customer.id != order.customer.id %}
      {% continue %}
    {% endif %}

    {% assign customer_total = 0.0 %}
    {% assign customer_orders_count = 0 %}

    {% for customer_order in customer.orders.any %}
      {% assign customer_order_created_at_in_seconds = customer_order.created_at | date: "%s" | times: 1 %}
      {% if customer_order_created_at_in_seconds < min_created_at %}
        {% break %}
      {% endif %}

      {% unless acceptable_order_financial_statuses contains customer_order.financial_status %}
        {% continue %}
      {% endunless %}

      {% for transaction in customer_order.transactions %}
        {% if transaction.status != "success" %}
          {% continue %}
        {% endif %}

        {% unless acceptable_transaction_kinds contains transaction.kind %}
          {% continue %}
        {% endunless %}

        {% if transaction.kind == "refund" %}
          {% assign customer_total = customer_total | minus: transaction.amount %}
        {% else %}
          {% assign customer_total = customer_total | plus: transaction.amount %}
        {% endif %}
      {% endfor %}

      {% assign customer_orders_count = customer_orders_count | plus: 1 %}
    {% endfor %}

    {% assign tags_to_save = customer.tags | remove_tag: options.customer_tag__required %}
    {% assign log_line_prefix = customer.email | default: customer.id | append: " spent " | append: customer_total | append: " across " | append: customer_orders_count | append: " orders, " %}
    {% if customer_total >= options.minimum_total_spent__number_required %}
      {"log": {{ log_line_prefix | append: "qualifying them for the tag" | json }}}
      {% assign tags_to_save = customer.tags | add_tag: options.customer_tag__required %}
    {% else %}
      {"log": {{ log_line_prefix | append: "and did not qualify for the tag" | json }}}
    {% endif %}

    {% if tags_to_save != customer.tags %}
      {
        "action": {
          "type": "shopify",
          "options": [
            "update",
            [
              "customer",
              {{ customer.id | json }}
            ],
            {
              "tags": {{ tags_to_save | json }}
            }
          ]
        }
      }
    {% endif %}

    {% if event.topic contains "shopify/orders" and event.topic != "shopify/orders/delete" and customer.id == order.customer.id %}
      {% break %}
    {% endif %}
  {% endfor %}
{% endif %}
Mechanic tasks are written in Liquid, which makes them easy to write and easy to modify. Learn more about our platform.
Defaults
Days of order history to consider
30