Publish back-in-stock products, with Mechanic.

Mechanic is a development platform for Shopify. :)

Publish back-in-stock products

by Isaac Bowen (team@usemechanic.com)

Whenever inventory for a product is updated, this task compares its available inventory against your "back in stock" threshold. If the product is to be considered back in stock, this task will make sure it's published to the sales channels of your choice. Optionally, it'll send you an email when it publishes your product.

Runs when an inventory level is updated. Configuration includes sales channel names and email notification recipient.

15-day free trial – unlimited tasks

Developer details

Mechanic is designed to benefit everybody: merchants, customers, developers, agencies, Gurus, 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.

Events
when an inventory level is updated (shopify/inventory_levels/update)
Options
sales channel names (required, array), email notification recipient (email)
Script
{% if event.preview %}
  {% assign inventory_level = hash %}
  {% assign inventory_level["admin_graphql_api_id"] = "gid://shopify/InventoryLevel/14071693373?inventory_item_id=32830988484669" %}
{% endif %}

{% capture query %}
  query {
    publications(first: 250) {
      edges {
        node {
          id
          name
        }
      }
    }
  }
{% endcapture %}

{% assign result = query | shopify %}

{% assign publication_ids = array %}

{% for publication_edge in result.data.publications.edges %}
  {% if options.sales_channel_names__required_array contains publication_edge.node.name %}
    {% assign publication_ids[publication_ids.size] = publication_edge.node.id %}
  {% endif %}
{% endfor %}

{% unless event.preview %}
  {% assign available_channels = result.data.publications.edges | map: "node" | map: "name" %}
  {% if publication_ids.size != options.sales_channel_names__required_array.size %}
    {% error message: "Didn't find all configured sales channels. Please check the list of available channels, and compare it with the list of configured channels.", available_channels: available_channels, configured_channels: options.sales_channel_names__required_array %}
  {% endif %}
{% endunless %}

{% if event.preview %}
  {% assign publication_ids = array %}
  {% assign publication_ids[0] = "gid://shopify/Publication/1234567890" %}
{% endif %}

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

            {% for publication_id in publication_ids %}
              published{{ forloop.index }}: publishedOnPublication(publicationId: {{ publication_id | json }})
            {% endfor %}
          }
        }
      }
    }
  }
{% endcapture %}

{% assign result = query | shopify %}

{% if event.preview %}
  {% capture result_json %}
    {
      "data": {
        "inventoryLevel": {
          "item": {
            "variant": {
              "product": {
                "id": "gid://shopify/Product/1234567890",
                "legacyResourceId": "1234567890",
                "title": "Short sleeve t-shirt",
                "totalInventory": 1,
                "published1": false
              }
            }
          }
        }
      }
    }
  {% endcapture %}

  {% assign result = result_json | parse_json %}
{% endif %}

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

{% assign mutations = array %}

{% if product.totalInventory > 0 %}
  {% for publication_id in publication_ids %}
    {% assign published_key = "published" | append: forloop.index %}
    {% if product[published_key] == false %}
      {% capture mutation %}
        publishablePublish{{ forloop.index}}: publishablePublish(
          id: {{ product.id | json }}
          input: {
            publicationId: {{ publication_id | json }}
          }
        ) {
          userErrors {
            field
            message
          }
        }
      {% endcapture %}

      {% assign mutations[mutations.size] = mutation %}
    {% endif %}
  {% endfor %}
{% endif %}

{% if mutations != empty %}
  {% action "shopify" %}
    mutation {
      {{ mutations | join: newline }}
    }
  {% endaction %}

  {% if options.email_notification_recipient__email != blank %}
    {% capture email_subject %}
      Back in stock: {{ product.title }}
    {% endcapture %}

    {% capture email_body %}
      Visit https://{{ shop.domain }}/admin/products/{{ product.legacyResourceId }} to manage this product.

      Thanks,
      - Mechanic, for {{ shop.name }}
    {% endcapture %}

    {% action "email" %}
      {
        "to": {{ options.email_notification_recipient__email | json }},
        "subject": {{ email_subject | unindent | strip | json }},
        "body": {{ email_body | unindent | strip | newline_to_br | json }}
      }
    {% endaction %}
  {% endif %}
{% endif %}
Mechanic tasks are written in Liquid, which makes them easy to write and easy to modify. Learn more about our platform.