Mechanic is a development and ecommerce automation platform for Shopify. :)
This task will keep your sale tags in sync, without any manual work. Configure the task with a tag to apply (and optionally a tag for products that aren't on sale), and Mechanic will take care of applying and removing tags as appropriate.
Runs Occurs whenever a product is created, Occurs whenever a product is updated, ordered, or variants are added, removed or updated, and Occurs when a user manually triggers the task. Configuration includes tag for sale products, tag for all other products, and sale products must have a price lower than the compare at price.
This task will keep your sale tags in sync, without any manual work. Configure the task with a tag to apply (and optionally a tag for products that aren't on sale), and Mechanic will take care of applying and removing tags as appropriate.
Run this task manually to update your entire product catalog at once.
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/products/create shopify/products/update mechanic/user/trigger
{% assign tag_for_sale_products = options.tag_for_sale_products__required %} {% assign tag_for_all_other_products = options.tag_for_all_other_products %} {% assign must_have_price_lower_than_the_compare_at_price = options.sale_products_must_have_a_price_lower_than_the_compare_at_price__boolean %} {% comment %} -- for product create/update, filter the products query with the product ID that caused the event {% endcomment %} {% if event.topic contains "shopify/products/" %} {% assign search_query = product.id | prepend: "id:" %} {% endif %} {% comment %} -- query product(s) in the shop; variants will be queried separately as needed to support up to 2K variants {% endcomment %} {% assign cursor = nil %} {% assign products = array %} {% for n in (1..100) %} {% capture query %} query { products( first: 250 after: {{ cursor | json }} query: {{ search_query | json }} ) { pageInfo { hasNextPage endCursor } nodes { id tags } } } {% endcapture %} {% assign result = query | shopify %} {% if event.preview %} {% capture result_json %} { "data": { "products": { "nodes": [ { "id": "gid://shopify/Product/1234567890" } ] } } } {% endcapture %} {% assign result = result_json | parse_json %} {% endif %} {% assign products = products | concat: result.data.products.nodes %} {% if result.data.products.pageInfo.hasNextPage %} {% assign cursor = result.data.products.pageInfo.endCursor %} {% else %} {% break %} {% endif %} {% endfor %} {% comment %} -- process each product by querying as many variants as needed to determine which tag applies {% endcomment %} {% for product in products %} {% assign product_qualifies_as_sale = nil %} {% assign cursor = nil %} {% for n in (1..8) %} {% capture query %} query { product(id: {{ product.id | json }}) { variants( first: 250 after: {{ cursor | json }} ) { pageInfo { hasNextPage endCursor } nodes { price compareAtPrice } } } } {% endcapture %} {% assign result = query | shopify %} {% if event.preview %} {% capture result_json %} { "data": { "product": { "variants": { "nodes": [ { "price": "19.99", "compareAtPrice": "24.99" } ] } } } } {% endcapture %} {% assign result = result_json | parse_json %} {% endif %} {% assign variants = result.data.product.variants.nodes %} {% comment %} -- check batch of variants to see if a compare at price exists, and optionally if it is greater than the price {% endcomment %} {% for variant in variants %} {% if variant.compareAtPrice == blank %} {% continue %} {% endif %} {% if must_have_price_lower_than_the_compare_at_price %} {% assign price = variant.price | times: 1 %} {% assign compare_at_price = variant.compareAtPrice | times: 1 %} {% if price < compare_at_price %} {% assign product_qualifies_as_sale = true %} {% break %} {% endif %} {% else %} {% assign product_qualifies_as_sale = true %} {% break %} {% endif %} {% endfor %} {% comment %} -- only query for more variants if the product has not yet qualified as "on sale" AND if there are more variants {% endcomment %} {% if product_qualifies_as_sale %} {% break %} {% elsif result.data.product.variants.pageInfo.hasNextPage %} {% assign cursor = result.data.product.variants.pageInfo.endCursor %} {% else %} {% break %} {% endif %} {% endfor %} {% comment %} -- adjust tags on product as needed {% endcomment %} {% assign tag_to_add = nil %} {% assign tag_to_remove = nil %} {% if product_qualifies_as_sale %} {% if tag_for_sale_products != blank %} {% unless product.tags contains tag_for_sale_products %} {% assign tag_to_add = tag_for_sale_products %} {% endunless %} {% endif %} {% if tag_for_all_other_products != blank %} {% if product.tags contains tag_for_all_other_products %} {% assign tag_to_remove = tag_for_all_other_products %} {% endif %} {% endif %} {% else %} {% if tag_for_sale_products != blank %} {% if product.tags contains tag_for_sale_products %} {% assign tag_to_remove = tag_for_sale_products %} {% endif %} {% endif %} {% if tag_for_all_other_products != blank %} {% unless product.tags contains tag_for_all_other_products %} {% assign tag_to_add = tag_for_all_other_products %} {% endunless %} {% endif %} {% endif %} {% if tag_to_add or tag_to_remove %} {% action "shopify" %} mutation { {% if tag_to_add %} tagsAdd( id: {{ product.id | json }} tags: {{ tag_to_add | json }} ) { userErrors { field message } } {% endif %} {% if tag_to_remove %} tagsRemove( id: {{ product.id | json }} tags: {{ tag_to_remove | json }} ) { userErrors { field message } } {% endif %} } {% endaction %} {% endif %} {% endfor %}
on-sale
not-on-sale
true