Mechanic is a development and ecommerce automation platform for Shopify. :)
Out of the box, this task scans the last week's worth of paid orders, and auto-tags products that meet the sales threshold of your choice, removing the tag from products that no longer qualify. This scan can be run on demand (with the "Run task" button), and will otherwise run nightly.
Runs Occurs when a user manually triggers the task, Occurs every day at midnight (in local time), and Occurs when a bulk operation is completed. Configuration includes tally by line item quantity, tally by line item subtotals, tally by number of orders, minimum tally threshold per product, product tag to apply, and order query.
Out of the box, this task scans the last week's worth of paid orders, and auto-tags products that meet the sales threshold of your choice, removing the tag from products that no longer qualify. This scan can be run on demand (with the "Run task" button), and will otherwise run nightly.
You can choose between a threshold defined by line item quantity (for the total number of units sold), by line item subtotals (for the total amount of money each product earned), or by number of orders (for the total number of times a customer placed an order including that product).
Configure the "Order query" option to get specific about which orders you want to consider. When altering the "processed_at" query parameter, you may use the following values:
This task can take some time to run, depending on the number of orders that need to be scanned. :)
For the interested, see the very end of the "Task result" portion of each task run's event, for a logged dump of product IDs mapped to the tallies Mechanic has arrived at for each one. You can use this to make sure you understand why Mechanic is making the tagging decisions it's making.
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?)
mechanic/user/trigger mechanic/scheduler/daily mechanic/shopify/bulk_operation
{% comment %} Preferred option order: {{ options.tally_by_line_item_quantity__boolean }} {{ options.tally_by_line_item_subtotals__boolean }} {{ options.tally_by_number_of_orders__boolean }} {{ options.minimum_tally_threshold_per_product__required_number }} {{ options.product_tag_to_apply__required }} {{ options.order_query__required }} {% endcomment %} {% assign mode_selections = 0 %} {% if options.tally_by_line_item_quantity__boolean %} {% assign mode = "line_item_quantity" %} {% assign mode_selections = mode_selections | plus: 1 %} {% endif %} {% if options.tally_by_line_item_subtotals__boolean %} {% assign mode = "line_item_subtotal" %} {% assign mode_selections = mode_selections | plus: 1 %} {% endif %} {% if options.tally_by_number_of_orders__boolean %} {% assign mode = "order_count" %} {% assign mode_selections = mode_selections | plus: 1 %} {% endif %} {% if mode_selections == 0 %} {"error": "Choose one tally mode."} {% elsif mode_selections > 1 %} {"error": "Choose exactly one tally mode - more than one is not supported."} {% endif %} {% if event.topic == "mechanic/user/trigger" or event.topic contains "mechanic/scheduler/" %} {% capture bulk_operation_query %} query { products( query: {{ options.product_tag_to_apply__required | json | prepend: "tag:" | json }} ) { edges { node { __typename id } } } orders( query: {{ options.order_query__required | json }} ) { edges { node { __typename id createdAt lineItems { edges { node { __typename id quantity originalTotalSet { shopMoney { amount } } product { id } } } } } } } } {% endcapture %} {% action "shopify" %} mutation { bulkOperationRunQuery( query: {{ bulk_operation_query | json }} ) { bulkOperation { id status } userErrors { field message } } } {% endaction %} {% elsif event.topic == "mechanic/shopify/bulk_operation" %} {% assign products_already_tagged = bulkOperation.objects | where: "__typename", "Product" | map: "id" %} {% assign line_items = bulkOperation.objects | where: "__typename", "LineItem" %} {% assign product_tallies = hash %} {% assign products_deserving_tag = array %} {% case mode %} {% when "line_item_quantity" %} {% for line_item in line_items %} {% if line_item.product %} {% assign product_tallies[line_item.product.id] = product_tallies[line_item.product.id] | default: 0 | plus: line_item.quantity %} {% endif %} {% endfor %} {% when "line_item_subtotal" %} {% for line_item in line_items %} {% if line_item.product %} {% assign product_tallies[line_item.product.id] = product_tallies[line_item.product.id] | default: 0 | plus: line_item.originalTotalSet.shopMoney.amount %} {% endif %} {% endfor %} {% when "order_count" %} {% assign product_ids = line_items | map: "product" | map: "id" | compact %} {% for product_id in product_ids %} {% assign product_tallies[product_id] = product_tallies[product_id] | default: 0 | plus: 1 %} {% endfor %} {% endcase %} {% if event.preview %} {% assign product_tallies["gid://shopify/Product/1234567890"] = options.minimum_tally_threshold_per_product__required_number %} {% endif %} {% for keyval in product_tallies %} {% assign product_id = keyval[0] %} {% assign tally = keyval[1] %} {% if tally >= options.minimum_tally_threshold_per_product__required_number %} {% assign products_deserving_tag[products_deserving_tag.size] = product_id %} {% unless products_already_tagged contains product_id %} {% action "shopify" %} mutation { tagsAdd( id: {{ product_id | json }} tags: {{ options.product_tag_to_apply__required | json }} ) { userErrors { field message } } } {% endaction %} {% endunless %} {% endif %} {% endfor %} {% for product_id in products_already_tagged %} {% unless products_deserving_tag contains product_id %} {% action "shopify" %} mutation { tagsRemove( id: {{ product_id | json }} tags: {{ options.product_tag_to_apply__required | json }} ) { userErrors { field message } } } {% endaction %} {% endunless %} {% endfor %} {"log": {{ product_tallies | json }}} {% endif %}
true
financial_status:paid processed_at:past_week