Mechanic is a development and ecommerce automation platform for Shopify. :)
Configure this task with search terms that describe certain products, and this task will apply the tags of your choice to every customer who purchases a matching product or product variant. Run this task manually to tag all customers who have a qualifying order already on file.
Runs Occurs whenever an order is paid, Occurs when a user manually triggers the task, and Occurs when a bulk operation is completed. Configuration includes search query, search for products, search for product variants, customer tags to apply, and test mode.
Configure this task with search terms that describe certain products, and this task will apply the tags of your choice to every customer who purchases a matching product or product variant. Run this task manually to tag all customers who have a qualifying order already on file.
This task auto-tags customers who have paid orders on file for products or product variants that match the search query you add.
Sample searches:
sku:ABC123
tag:holiday
product_type:"Gift Card"
title:"Short sleeve t-shirt"
To ensure expected results, use this task with test mode enabled, before disabling test mode.
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/paid mechanic/user/trigger mechanic/shopify/bulk_operation
{% comment %} Ordering the task options: {{ options.search_query__required }} {{ options.search_for_products__boolean }} {{ options.search_for_product_variants__boolean }} {{ options.customer_tags_to_apply__required_array }} {{ options.test_mode__boolean }} {% endcomment %} {% if options.search_for_products__boolean and options.search_for_product_variants__boolean %} {% error "Choose only one of 'Search for products' and 'Search for product variants'. :)" %} {% elsif options.search_for_products__boolean == false and options.search_for_product_variants__boolean == false %} {% error "Choose either 'Search for products' and 'Search for product variants'." %} {% endif %} {% assign cursor = nil %} {% assign qualifier_resource_ids = array %} {% assign qualifier_resource_summaries = array %} {% assign jobs = array %} {% for n in (0..100) %} {% capture query %} query { {% if options.search_for_products__boolean %} resources: products( {% else %} resources: productVariants( {% endif %} first: 250 after: {{ cursor | json }} query: {{ options.search_query__required | json }} ) { edges { node { id legacyResourceId {% if options.search_for_products__boolean %} displayName: title {% else %} displayName {% endif %} } } } } {% endcapture %} {% assign result = query | shopify %} {% if event.preview %} {% capture result_json %} { "data": { "resources": { "edges": [ { "node": { "id": "gid://shopify/Product/1234567890", "displayName": "Bundle", "legacyResourceId": "1234567890" } } ] } } } {% endcapture %} {% assign result = result_json | parse_json %} {% endif %} {% log %} { "qualifier_resources": {{ result.data.resources.edges | map: "node" | json }} } {% endlog %} {% assign qualifier_resource_ids = result.data.resources.edges | map: "node" | map: "legacyResourceId" | concat: qualifier_resource_ids %} {% if result.data.resources.pageInfo.hasNextPage %} {% assign cursor = result.data.resources.edges.last.cursor %} {% else %} {% break %} {% endif %} {% endfor %} {% if event.topic contains "shopify/orders/" %} {% if event.preview %} {% capture order_json %} { "financial_status": "paid", "name": "#1234", "customer": { "email": "customer@example.com", "tags": "", "admin_graphql_api_id": "gid://shopify/Customer/1234567890" }, "line_items": [ { "product_id": 1234567890, "variant_id": 1234567890, "title": "IPod Nano - 8GB" } ] } {% endcapture %} {% assign order = order_json | parse_json %} {% endif %} {% assign order_qualifies = false %} {% assign order_qualifying_resource = nil %} {% if order.financial_status == "paid" and order.customer %} {% for line_item in order.line_items %} {% if options.search_for_products__boolean %} {% assign id = line_item.product_id | append: "" %} {% else %} {% assign id = line_item.variant_id | append: "" %} {% endif %} {% if qualifier_resource_ids contains id %} {% assign order_qualifies = true %} {% assign order_qualifying_resource = line_item.title %} {% break %} {% endif %} {% endfor %} {% endif %} {% if order_qualifies %} {% assign job = hash %} {% assign job["customer_id"] = order.customer.admin_graphql_api_id %} {% assign job["customer_email"] = order.customer.email %} {% assign job["customer_existing_tags"] = order.customer.tags | split: ", " %} {% assign job["reason"] = order_qualifying_resource | append: ", in order " | append: order.name %} {% assign jobs[jobs.size] = job %} {% endif %} {% elsif event.topic == "mechanic/user/trigger" %} {% capture bulk_operation_query %} query { customers { edges { node { __typename id email tags orders( query: "financial_status:paid" ) { edges { node { __typename id name lineItems { edges { node { __typename id {% if options.search_for_products__boolean %} resource: product { legacyResourceId displayName: title } {% else %} resource: variant { legacyResourceId displayName } {% endif %} } } } } } } } } } } {% 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 bulkOperation_json %} { "objects": [ { "__typename": "LineItem", "resource": { "legacyResourceId": "1234567890", "displayName": "IPod Nano - 8GB" }, "__parent": { "name": "#1234", "__parent": { "id": "gid://shopify/Customer/1234567890", "email": "customer@example.com", "tags": [] } } } ] } {% endcapture %} {% assign bulkOperation = bulkOperation_json | parse_json %} {% endif %} {% assign lineItems = bulkOperation.objects | where: "__typename", "LineItem" | where: "resource" %} {% for lineItem in lineItems %} {% assign resource = lineItem.resource %} {% assign order = lineItem.__parent %} {% assign customer = order.__parent %} {% if qualifier_resource_ids contains resource.legacyResourceId %} {% assign job = hash %} {% assign job["customer_id"] = customer.id %} {% assign job["customer_email"] = customer.email %} {% assign job["customer_existing_tags"] = customer.tags %} {% assign job["reason"] = resource.displayName | append: ", in order " | append: order.name %} {% assign jobs[jobs.size] = job %} {% endif %} {% endfor %} {% endif %} {% assign customer_ids_with_jobs = jobs | map: "customer_id" | uniq %} {% for customer_id in customer_ids_with_jobs %} {% assign customer_jobs = jobs | where: "customer_id", customer_id %} {% assign customer_existing_tags = customer_jobs[0].customer_existing_tags %} {% assign customer_email = customer_jobs[0].customer_email %} {% assign reasons = customer_jobs | map: "reason" %} {% assign tags_to_add = array %} {% for tag in options.customer_tags_to_apply__required_array %} {% unless customer_existing_tags contains tag %} {% assign tags_to_add[tags_to_add.size] = tag %} {% endunless %} {% endfor %} {% if options.test_mode__boolean %} {% action "echo" %} { "customer_id": {{ customer_id | json }}, "customer_email": {{ customer_email | json }}, "customer_purchases": {{ reasons | json }}, "customer_existing_tags": {{ customer_existing_tags | json }}, "customer_tags_to_add": {{ tags_to_add | json }} } {% endaction %} {% elsif tags_to_add == empty %} {% capture log_message %}Customer {{ customer.id }} already has all applicable tags ({{ tags_applicable | join: ", " }}); nothing to do.{% endcapture %} {% log log_message %} {% else %} {% action "shopify" %} mutation { tagsAdd( id: {{ customer_id | json }} tags: {{ tags_to_add | json }} ) { userErrors { field message } } } {% endaction %} {% endif %} {% endfor %}
sku:ABC123
true
true