Email customers when tagged, with Mechanic.

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

Email customers when tagged

Automatically send out an email to your customers when a tag is added to their account. Useful for sending approval emails, welcome emails if the customer was created with a certain tag, or any other emails related to an update to the customer's status. The most common use of this task is to send out emails to customers when their accounts are approved, but you can use this task to email customers any kind of alert you like, triggered by a simple tag. For example, some themes include an email subscription form that creates a customer record, pre-tagged with "email subscribe", or something to that effect.

Runs Occurs whenever a customer is created, Occurs whenever a customer is updated, and Occurs when a user manually triggers the task. Configuration includes tag to watch for, ignore tag case, autotag customers after emailing, email subject, and email body.

15-day free trial – unlimited tasks

Documentation

Automatically send out an email to your customers when a tag is added to their account. Useful for sending approval emails, welcome emails if the customer was created with a certain tag, or any other emails related to an update to the customer's status. The most common use of this task is to send out emails to customers when their accounts are approved, but you can use this task to email customers any kind of alert you like, triggered by a simple tag. For example, some themes include an email subscription form that creates a customer record, pre-tagged with "email subscribe", or something to that effect.

Important note: After saving this task for the first time (and every time you change the tag to watch for), click the "Run task" button. Mechanic will then scan your customers to find those who already have the desired tag, and will make a note of them, so as to not email them in the future. (We require this to avoid suddenly sending a flood of emails to customers that were tagged before the Mechanic task was created.)

Enable the "Autotag customers after emailing" option to have Mechanic add "YOURTAGHERE-email-sent" to the customer's tags, when their email is sent out.

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/customers/create
shopify/customers/update
mechanic/user/trigger
Tasks use subscriptions to sign up for specific kinds of events. Learn more
Options
tag to watch for (required), ignore tag case (boolean), autotag customers after emailing (boolean), email subject (required), email body (required, multiline)
Code
{% assign approval_tag = options.tag_to_watch_for__required %}

{% if options.ignore_tag_case__boolean %}
  {% assign approval_tag = options.tag_to_watch_for__required | downcase %}
{% endif %}

{% capture email_sent_tag %}{{ approval_tag }}-email-sent{% endcapture %}
{% assign tag_processed_metafield_key = task.created_at | date: "%s" | append: approval_tag | append: "tag-processed" | sha256 | slice: 0, 5 | prepend: "-" | prepend: approval_tag %}
{% assign customers_scanned_metafield_key = task.created_at | date: "%s" | append: approval_tag | append: "customers-scanned" | sha256 | slice: 0, 5 | prepend: "-" | prepend: approval_tag %}

{% if event.topic contains "shopify/customers/" %}
  {% assign customer_tags = customer.tags | split: ", " %}

  {% if options.ignore_tag_case__boolean %}
    {% assign customer_tags = customer.tags | downcase | split: ", " %}
  {% endif %}

  {% assign customer_qualifies = true %}
  {% unless customer_tags contains approval_tag %}
    {% assign customer_qualifies = false %}
    {% log "The customer does not have the required tag." %}
  {% endunless %}

  {% if options.autotag_customers_after_emailing__boolean %}
    {% if customer_tags contains email_sent_tag %}
      {% assign customer_qualifies = false %}
      {% log "According to the customer's tags, this customer has already received this email." %}
    {% endif %}
  {% endif %}

  {% if customer_qualifies %}
    {% capture query %}
      query {
        customer(id: {{ customer.admin_graphql_api_id | json }}) {
          metafield(namespace: "mechanic", key: {{ tag_processed_metafield_key | json }}) {
            value
          }
        }
      }
    {% endcapture %}
    {% assign result = query | shopify %}

    {% if event.preview %}
      {% capture result_json %}
        {
          "data": {
            "customer": {
              "metafield": {
                "value": "1"
              }
            }
          }
        }
      {% endcapture %}
      {% assign result = result_json | parse_json %}
    {% endif %}

    {% if result.data.customer.metafield %}
      {% assign customer_qualifies = false %}
      {% log "According to a stored metafield, this customer has already received this email, or was already tagged when this task was initially set up." %}
    {% endif %}
  {% endif %}

  {% if customer_qualifies %}
    {% capture query %}
      query {
        shop {
          metafield(namespace: "mechanic", key: {{ customers_scanned_metafield_key | json }}) {
            value
          }
        }
      }
    {% endcapture %}
    {% assign result = query | shopify %}

    {% if event.preview %}
      {% capture result_json %}
        {
          "data": {
            "shop": {
              "metafield": {
                "value": "1"
              }
            }
          }
        }
      {% endcapture %}
      {% assign result = result_json | parse_json %}
    {% endif %}

    {% if result.data.shop.metafield == nil %}
      {% error "Please use this task's 'Run task' button to manually scan your existing customers. Mechanic will take note of everyone who's already tagged, so as to *not* send them an email in the future." %}
    {% endif %}
  {% endif %}

  {% if event.preview or customer_qualifies %}
    {% action "email" %}
      {
        "to": {{ customer.email | json }},
        "subject": {{ options.email_subject__required | json }},
        "body": {{ options.email_body__required_multiline | strip | newline_to_br | json }},
        "reply_to": {{ shop.customer_email | json }},
        "from_display_name": {{ shop.name | json }}
      }
    {% endaction %}

    {% action "shopify" %}
      mutation {
        {% if options.autotag_customers_after_emailing__boolean %}
          tagsAdd(
            id: {{ customer.admin_graphql_api_id | json }}
            tags: {{ email_sent_tag | json }}
          ) {
            userErrors {
              field
              message
            }
          }
        {% endif %}

        customerUpdate(input: {
          id: {{ customer.admin_graphql_api_id | json }}
          metafields: [
            {
              namespace: "mechanic"
              key: {{ tag_processed_metafield_key | json }}
              type: "number_integer"
              value: "1"
            }
          ]
        }) {
          userErrors {
            field
            message
          }
        }
      }
    {% endaction %}
  {% endif %}
{% elsif event.topic == "mechanic/user/trigger" %}
  {% assign customer_ids_to_mark = array %}
  {% assign cursor = nil %}

  {% for n in (0..100) %}
    {% capture query %}
      query {
        customers(
          first: 250
          query: {{ approval_tag | json | prepend: "tag:" | json }}
          after: {{ cursor | json }}
        ) {
          pageInfo {
            hasNextPage
          }
          edges {
            cursor
            node {
              id
              metafield(
                namespace: "mechanic"
                key: {{ tag_processed_metafield_key | json }}
              ) {
                value
              }
            }
          }
        }
      }
    {% endcapture %}

    {% assign result = query | shopify %}

    {% if event.preview %}
      {% capture result_json %}
        {
          "data": {
            "customers": {
              "pageInfo": {
                "hasNextPage": false
              },
              "edges": [
                {
                  "node": {
                    "id": "gid://shopify/Customer/1234567890",
                    "metafield": null
                  }
                }
              ]
            }
          }
        }
      {% endcapture %}

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

    {% for edge in result.data.customers.edges %}
      {% if edge.node.metafield %}
        {% continue %}
      {% endif %}

      {% assign customer_ids_to_mark[customer_ids_to_mark.size] = edge.node.id %}
    {% endfor %}

    {% if result.data.customers.pageInfo.hasNextPage %}
      {% assign cursor = result.data.customers.edges.last.cursor %}
    {% else %}
      {% break %}
    {% endif %}
  {% endfor %}

  {% assign metafields = array %}

  {% for customer_id in customer_ids_to_mark %}
    {% capture metafield %}
      {
        ownerId: {{ customer_id | json }}
        namespace: "mechanic"
        key: {{ tag_processed_metafield_key | json }}
        type: "number_integer"
        value: "1"
      }
    {% endcapture %}

    {% assign metafields = metafields | push: metafield %}
  {% endfor %}

  {% assign groups_of_metafields = metafields | in_groups_of: 25, fill_with: false %}

  {% for group_of_metafields in groups_of_metafields %}
    {% action "shopify" %}
      mutation {
        metafieldsSet(
          metafields: [
            {{ group_of_metafields | join: newline }}
          ]
        ) {
          metafields {
            id
            namespace
            key
            type
            value
            owner {
              ... on Customer {
                id
              }
            }
          }
          userErrors {
            code
            field
            message
          }
        }
      }
    {% endaction %}
  {% endfor %}

  {% action "shopify" %}
    mutation {
      metafieldsSet(
        metafields: [
          {
            ownerId: {{ "gid://shopify/Shop/" | append: shop.id | json }}
            namespace: "mechanic"
            key: {{ customers_scanned_metafield_key | json }}
            type: "number_integer"
            value: "1"
          }
        ]
      ) {
        metafields {
          id
          namespace
          key
          type
          value
          owner {
            ... on Shop {
              id
            }
          }
        }
        userErrors {
          code
          field
          message
        }
      }
    }
  {% endaction %}
{% endif %}
Task code is written in Mechanic Liquid, an extension of open-source Liquid enhanced for automation. Learn more
Defaults
Tag to watch for
approved
Ignore tag case
true
Email subject
Your account has been approved!
Email body
Hi {{ customer.first_name | default: "there" }},

Your account for {{ shop.name }} has been approved! Thanks for registering, and we'll see you soon.

Thanks,
The team at {{ shop.name }}