Unpublish products when tagged, with Mechanic.

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

Unpublish products when tagged

This task watches for certain product tags, and removes the product from the selected sales channel(s) when those tags are found.

Runs Occurs whenever a product is updated, ordered, or variants are added, removed or updated. Configuration includes product tags to watch for, require product to have all given tags before unpublishing, and sales channel names.

15-day free trial – unlimited tasks

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/products/update
Tasks use subscriptions to sign up for specific kinds of events. Learn more
Options
product tags to watch for (required, array) , require product to have all given tags before unpublishing (boolean) , sales channel names (required, array)
Code
{% assign product_tags_to_watch_for = options.product_tags_to_watch_for__required_array %}
{% assign require_all_tags = options.require_product_to_have_all_given_tags_before_unpublishing__boolean %}
{% assign sales_channel_names = options.sales_channel_names__required_array %}

{% comment %}
  -- get all of the sales channel names (i.e. publications aka app catalogs) in the shop
{% endcomment %}

{% capture query %}
  query {
    publications(
      first: 250
      catalogType:APP
    ) {
      nodes {
        id
        catalog {
          ... on AppCatalog {
            apps(first: 1) {
              nodes {
                title
              }
            }
          }
        }
      }
    }
  }
{% endcapture %}

{% assign result = query | shopify %}

{% if event.preview %}
  {% capture result_json %}
    {
      "data": {
        "publications": {
          "nodes": [
            {
              "id": "gid://shopify/Publication/1234567890",
              "catalog": {
                "apps": {
                  "nodes": [
                    {
                      "title": {{ sales_channel_names.first | json }}
                    }
                  ]
                }
              }
            }
          ]
        }
      }
    }
  {% endcapture %}

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

{% comment %}
  -- save the publication IDs for all of the configured sales channel names
{% endcomment %}

{% assign publication_ids = array %}
{% assign available_sales_channel_names = array %}

{% for publication in result.data.publications.nodes %}
  {% assign publication_name = publication.catalog.apps.nodes.first.title %}

  {% assign available_sales_channel_names = available_sales_channel_names | push: publication_name %}

  {% if sales_channel_names contains publication_name %}
    {% assign publication_ids = publication_ids | push: publication.id %}
  {% endif %}
{% endfor %}

{% if publication_ids == blank  %}
  {% error
    message: "None of the sales channels configured in this task exist in the shop. Check the list of available channels and verify each configured channel exists.",
    configured_sales_channel_names: sales_channel_names,
    available_sales_channel_names: available_sales_channel_names
  %}

  {% break %}

{% elsif publication_ids.size != sales_channel_names.size %}
  {% unless event.preview %}
    {% comment %}
      -- using action error here so the task will continue with any other configured and matched sales channels
    {% endcomment %}

    {% action "echo"
      __error: "One or more configured sales channel names do not match any of the publication names available in this shop.",
      configured_sales_channel_names: sales_channel_names,
      available_sales_channel_names: available_sales_channel_names
    %}
  {% endunless %}
{% endif %}

{% comment %}
  -- get product data and current publication status(es)
{% endcomment %}

{% capture query %}
  query {
    product(id: {{ product.admin_graphql_api_id | json }}) {
      id
      tags
      {% for publication_id in publication_ids %}
        publishedOnPublication{{ forloop.index }}: publishedOnPublication(
          publicationId: {{ publication_id | json }}
        )
      {% endfor %}
    }
  }
{% endcapture %}

{% assign result = query | shopify %}

{% if event.preview %}
  {% capture result_json %}
    {
      "data": {
        "product": {
          "id": "gid://shopify/Product/1234567890",
          "tags": {{ product_tags_to_watch_for | json }},
          "publishedOnPublication1": true
        }
      }
    }
  {% endcapture %}

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

{% assign product = result.data.product %}

{% comment %}
  -- check if product has at least one or all of the configured tags as warranted
{% endcomment %}

{% assign product_qualifies = false %}

{% if require_all_tags %}
  {% for tag in product_tags_to_watch_for %}
    {% if product.tags contains tag %}
      {% if forloop.last %}
        {% assign product_qualifies = true %}
      {% endif %}

    {% else %}
      {% break %}
    {% endif %}
  {% endfor %}

{% else %}
  {% for tag in product_tags_to_watch_for %}
    {% if product.tags contains tag %}
      {% assign product_qualifies = true %}
      {% break %}
    {% endif %}
  {% endfor %}
{% endif %}

{% unless product_qualifies %}
  {% break %}
{% endunless %}

{% assign publication_ids_for_unpublishing = array %}

{% for publication_id in publication_ids %}
  {% assign key = "publishedOnPublication" | append: forloop.index %}
  {% assign published = product[key] %}

  {% if product[key] %}
    {% assign publication_ids_for_unpublishing = publication_ids_for_unpublishing | push: publication_id %}
  {% endif %}
{% endfor %}

{% if publication_ids_for_unpublishing == blank %}
  {% log "Product was already unpublished on all configured sales channel(s). :)" %}
  {% break %}
{% endif %}

{% action "shopify" %}
  mutation {
    {% for publication_id in publication_ids_for_unpublishing %}
      publishableUnpublish{{ forloop.index }}: publishableUnpublish(
        id: {{ product.id | json }}
        input: {
          publicationId: {{ publication_id | json }}
        }
      ) {
        userErrors {
          field
          message
        }
      }
    {% endfor %}
  }
{% endaction %}
Task code is written in Mechanic Liquid, an extension of open-source Liquid enhanced for automation. Learn more
Defaults
Sales channel names
["Online Store"]