Auto-tag out-of-stock products, with Mechanic.

Mechanic is a development and ecommerce automation platform for Shopify. :)

Auto-tag out-of-stock products

Use this task to tag products when they reach the out of stock inventory level you configure. Optionally, fill in the email alert recipient to send an alert when a product is initally tagged for being out of stock.

Runs Occurs whenever an inventory level is updated, Occurs when a user manually triggers the task, and Occurs when a bulk operation is completed. Configuration includes out of stock inventory level, product tag, and email alert recipient.

15-day free trial – unlimited tasks

Documentation

Use this task to tag products when they reach the out of stock inventory level you configure. Optionally, fill in the email alert recipient to send an alert when a product is initally tagged for being out of stock.

Run this task manually to scan and tag all active products in your store, according to their respective total inventory levels.

Developer details

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?)

Open source
View on GitHub to contribute to this task
Subscriptions
shopify/inventory_levels/update
mechanic/user/trigger
mechanic/shopify/bulk_operation
Tasks use subscriptions to sign up for specific kinds of events. Learn more
Options
out of stock inventory level (number, required), product tag (required), email alert recipient (email)
Code
{% assign out_of_stock_inventory_level = options.out_of_stock_inventory_level__number_required %}
{% assign product_tag = options.product_tag__required %}
{% assign email_alert_recipient = options.email_alert_recipient__email %}

{% assign products = array %}

{% if event.topic == "shopify/inventory_levels/update" %}
  {% comment %}
    -- get product data from the inventory level resource
  {% endcomment %}

  {% capture query %}
    query {
      inventoryLevel(id: {{ inventory_level.admin_graphql_api_id | json }}) {
        item {
          variant {
            product {
              id
              legacyResourceId
              status
              title
              totalInventory
              tags
            }
          }
        }
      }
    }
  {% endcapture %}

  {% assign result = query | shopify %}

  {% assign product = result.data.inventoryLevel.item.variant.product %}

  {% comment %}
    -- only process active products
  {% endcomment %}

  {% if product.status == "ACTIVE" or event.preview %}
    {% assign products[0] = product %}
  {% endif %}

{% elsif event.topic == "mechanic/user/trigger" %}
  {% comment %}
    -- get all active products in the shop
  {% endcomment %}

  {% capture bulk_operation_query %}
    query {
      products(
        query: "status:active"
      ) {
        edges {
          node {
            __typename
            id
            totalInventory
            tags
          }
        }
      }
    }
  {% endcapture %}

  {% action "shopify" %}
    mutation {
      bulkOperationRunQuery(
        query: {{ bulk_operation_query | json }}
      ) {
        bulkOperation {
          id
          status
        }
        userErrors {
          field
          message
        }
      }
    }
  {% endaction %}

  {% break %}

{% elsif event.topic == "mechanic/shopify/bulk_operation" %}
  {% assign products = bulkOperation.objects | where: "__typename", "Product" %}
{% endif %}

{% comment %}
  -- preview event to handle both inventory level updates and bulk product queries
{% endcomment %}

{% if event.preview %}
  {% capture products_json %}
    [
      {
        "id": "gid://shopify/Product/1234567890",
        "totalInventory": {{ out_of_stock_inventory_level | plus: 1 }},
        "tags": {{ product_tag | json }}
      },
      {
        "id": "gid://shopify/Product/2345678901",
        "title": "Widget",
        "totalInventory": {{ out_of_stock_inventory_level }}
      }
    ]
  {% endcapture %}

  {% assign products = products_json | parse_json %}
{% endif %}

{% comment %}
  - process all of the products from bulk query, or the single active product linked to the inventory level update event
{% endcomment %}

{% for product in products %}
  {% if product.totalInventory > out_of_stock_inventory_level %}
    {% if product.tags contains product_tag %}
      {% comment %}
        -- product is above the configured out of stock level and has the out of stock tag; remove it
      {% endcomment %}

      {% action "shopify" %}
        mutation {
          tagsRemove(
            id: {{ product.id | json }}
            tags: {{ product_tag | json }}
          ) {
            userErrors {
              field
              message
            }
          }
        }
      {% endaction %}
    {% endif %}

  {% else %}
    {% comment %}
      -- product is out of stock
    {% endcomment %}

    {% if product.tags contains product_tag %}
      {% comment %}
        -- product has already been tagged; skip it (including email notification if applicable)
      {% endcomment %}

      {% continue %}
    {% endif %}

    {% action "shopify" %}
      mutation {
        tagsAdd(
          id: {{ product.id | json }}
          tags: {{ product_tag | json }}
        ) {
          userErrors {
            field
            message
          }
        }
      }
    {% endaction %}

    {% comment %}
      -- send email if this is a single inventory level event and an alert recipient is configured
    {% endcomment %}

    {% if event.topic == "shopify/inventory_levels/update" and email_alert_recipient != blank %}
      {% capture email_body %}
        Hello,

        {{ product.title }} is now out of stock, with a total stock level of {{ product.totalInventory }} (across all variants and locations).

        <a href="{{ shop.admin_url }}/products/{{ product.legacyResourceId }}">Manage this product</a>

        Thanks,
        Mechanic (for {{ shop.name }})
      {% endcapture %}

      {% action "email" %}
        {
          "to": {{ email_alert_recipient | json }},
          "subject": {{ product.title | append: " is now out of stock (" | append: product.totalInventory | append: ")" | json }},
          "body": {{ email_body | unindent | strip | newline_to_br | json }},
          "reply_to": {{ shop.customer_email | json }},
          "from_display_name": {{ shop.name | json }}
        }
      {% endaction %}
    {% endif %}
  {% endif %}
{% endfor %}
Task code is written in Mechanic Liquid, an extension of open-source Liquid enhanced for automation. Learn more
Defaults
Out of stock inventory level
0
Product tag
out-of-stock