Mechanic is a development and ecommerce automation platform for Shopify. :)
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.
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.
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?)
shopify/orders/create mechanic/user/trigger mechanic/shopify/bulk_operation
{% 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 %}