Email a CSV export of orders, with Mechanic.

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

Email a CSV export of orders

Use this task to generate and email a CSV of orders, including one row per line item. Filter with a search query or by tags, and auto-tag orders as they're exported. Run the export on demand, and/or nightly. This task is also useful as a template for further development.

Runs Occurs when a user manually triggers the task. Configuration includes search query for orders, ignore orders with this tag, add this tag after export, export email recipient, export email subject, export email body, export csv filename, and run export nightly.

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
mechanic/user/trigger
{% if options.run_export_nightly__boolean %}mechanic/scheduler/daily{% endif %}
Tasks use subscriptions to sign up for specific kinds of events. Learn more
Options
search query for orders, ignore orders with this tag, add this tag after export, export email recipient (email, required), export email subject (required), export email body (required, multiline), export csv filename (required), run export nightly (boolean)
Code
{% assign search_query_for_orders = options.search_query_for_orders %}
{% assign ignore_orders_with_this_tag = options.ignore_orders_with_this_tag %}
{% assign add_this_tag_after_export = options.add_this_tag_after_export %}
{% assign export_email_recipient = options.export_email_recipient__email_required %}
{% assign export_email_subject = options.export_email_subject__required %}
{% assign export_email_body = options.export_email_body__required_multiline %}
{% assign export_csv_filename = options.export_csv_filename__required %}

{% assign cursor = nil %}
{% assign order_ids = array %}

{% for n in (1..100) %}
  {% capture query %}
    query {
      orders(
        first: 250
        query: {{ search_query_for_orders | default: "" | json }}
        after: {{ cursor | json }}
      ) {
        pageInfo {
          hasNextPage
          endCursor
        }
        nodes {
          id
          tags
        }
      }
    }
  {% endcapture %}

  {% assign result = query | shopify %}

  {% for order in result.data.orders.nodes %}
    {% if ignore_orders_with_this_tag != blank and order.tags contains ignore_orders_with_this_tag %}
      {% continue %}
    {% endif %}

    {% assign order_ids = order_ids | push: order.id  %}
  {% endfor %}

  {% if result.data.orders.pageInfo.hasNextPage %}
    {% assign cursor = result.data.orders.pageInfo.endCursor %}
  {% else %}
    {% break %}
  {% endif %}
{% endfor %}

{% assign csv = array %}
{% assign csv[0] = "Customer ID,First Order Date,Customer E-mail,Shipping First Name,Shipping Last Name,Shipping Address 1,Shipping Address 2,Shipping City,Shipping Province,Shipping Country,Shipping Zip,Shipping Phone,Billing First Name,Billing Last Name,Billing Address 1,Billing Address 2,Billing City,Billing Province,Billing Country,Billing Zip,Billing Phone,Current Purchase Date,Product ID,Product Title,Variant ID,Variant Title,Tags,Quantity,Price,SKU,Shipping Code,Shipping Name" | split: "," %}

{% if event.preview %}
  {% assign order_ids[0] = "gid://shopify/Order/1234567890" %}
{% endif %}

{% for order_id in order_ids %}
  {% capture query %}
    query {
      order(id: {{ order_id | json }}) {
        id
        tags
        name
        processedAt
        shippingAddress {
          firstName
          lastName
          address1
          address2
          city
          province
          country
          zip
          phone
        }
        billingAddress {
          firstName
          lastName
          address1
          address2
          city
          province
          country
          zip
          phone
        }
        customer {
          legacyResourceId
          defaultEmailAddress {
            emailAddress
          }
          orders(
            first: 1
            sortKey: PROCESSED_AT
          ) {
            nodes {
              processedAt
            }
          }
        }
        lineItems(first: 250) {
          nodes {
            product {
              legacyResourceId
              title
              tags
            }
            variant {
              legacyResourceId
              title
            }
            customAttributes {
              key
              value
            }
            quantity
            discountedTotalSet {
              shopMoney {
                amount
                currencyCode
              }
            }
            sku
          }
        }
        shippingLine {
          title
          shippingRateHandle
        }
      }
    }
  {% endcapture %}

  {% assign result = query | shopify %}

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

  {% for line_item in order.lineItems.nodes %}
    {% assign row = array %}

    {% comment %}Customer ID{% endcomment %}
    {% assign row[row.size] = order.customer.legacyResourceId %}

    {% comment %}First Order Date{% endcomment %}
    {% assign row[row.size] = order.customer.orders.nodes.first.processedAt %}

    {% comment %}Customer E-mail{% endcomment %}
    {% assign row[row.size] = order.customer.defaultEmailAddress.emailAddress %}

    {% comment %}Shipping First Name{% endcomment %}
    {% assign row[row.size] = order.shippingAddress.firstName %}

    {% comment %}Shipping Last Name{% endcomment %}
    {% assign row[row.size] = order.shippingAddress.lastName %}

    {% comment %}Shipping Address 1{% endcomment %}
    {% assign row[row.size] = order.shippingAddress.address1 %}

    {% comment %}Shipping Address 2{% endcomment %}
    {% assign row[row.size] = order.shippingAddress.address2 %}

    {% comment %}Shipping City{% endcomment %}
    {% assign row[row.size] = order.shippingAddress.city %}

    {% comment %}Shipping Province{% endcomment %}
    {% assign row[row.size] = order.shippingAddress.province %}

    {% comment %}Shipping Country{% endcomment %}
    {% assign row[row.size] = order.shippingAddress.country %}

    {% comment %}Shipping Zip{% endcomment %}
    {% assign row[row.size] = order.shippingAddress.zip %}

    {% comment %}Shipping Phone{% endcomment %}
    {% assign row[row.size] = order.shippingAddress.phone %}

    {% comment %}Billing First Name{% endcomment %}
    {% assign row[row.size] = order.billingAddress.firstName %}

    {% comment %}Billing Last Name{% endcomment %}
    {% assign row[row.size] = order.billingAddress.lastName %}

    {% comment %}Billing Address 1{% endcomment %}
    {% assign row[row.size] = order.billingAddress.address1 %}

    {% comment %}Billing Address 2{% endcomment %}
    {% assign row[row.size] = order.billingAddress.address2 %}

    {% comment %}Billing City{% endcomment %}
    {% assign row[row.size] = order.billingAddress.city %}

    {% comment %}Billing Province{% endcomment %}
    {% assign row[row.size] = order.billingAddress.province %}

    {% comment %}Billing Country{% endcomment %}
    {% assign row[row.size] = order.billingAddress.country %}

    {% comment %}Billing Zip{% endcomment %}
    {% assign row[row.size] = order.billingAddress.zip %}

    {% comment %}Billing Phone{% endcomment %}
    {% assign row[row.size] = order.billingAddress.phone %}

    {% comment %}Current Purchase Date{% endcomment %}
    {% assign row[row.size] = order.processedAt %}

    {% comment %}Product ID{% endcomment %}
    {% assign row[row.size] = line_item.product.legacyResourceId %}

    {% comment %}Product Title{% endcomment %}
    {% assign row[row.size] = line_item.product.title %}

    {% comment %}Variant ID{% endcomment %}
    {% assign row[row.size] = line_item.variant.legacyResourceId %}

    {% comment %}Variant Title{% endcomment %}
    {% assign row[row.size] = line_item.variant.title %}

    {% comment %}Tags{% endcomment %}
    {% assign row[row.size] = line_item.product.tags | join: ", " %}

    {% comment %}Quantity{% endcomment %}
    {% assign row[row.size] = line_item.quantity %}

    {% comment %}Price{% endcomment %}
    {% assign row[row.size] = line_item.discountedTotalSet.shopMoney.amount %}

    {% comment %}SKU{% endcomment %}
    {% assign row[row.size] = line_item.sku %}

    {% comment %}Shipping Code{% endcomment %}
    {% assign row[row.size] = order.shippingLine.shippingRateHandle %}

    {% comment %}Shipping Name{% endcomment %}
    {% assign row[row.size] = order.shippingLine.title %}

    {% assign csv[csv.size] = row %}
  {% endfor %}
{% endfor %}

{% if add_this_tag_after_export != blank %}
  {% for order_id in order_ids %}
    {% action "shopify" %}
      mutation {
        tagsAdd(
          id: {{ order_id | json }}
          tags: {{ add_this_tag_after_export | json }}
        ) {
          userErrors {
            field
            message
          }
        }
      }
    {% endaction %}
  {% endfor %}
{% endif %}

{% if event.preview or csv.size > 1 %}
  {% action "email" %}
    {
      "from_display_name": {{ shop.name | json }},
      "to": {{ export_email_recipient | json }},
      "subject": {{ export_email_subject | json }},
      "body": {{ export_email_body | strip | newline_to_br | json }},
      "attachments": {
        {{ export_csv_filename | append: ".csv" | json }}: {{ csv | csv | json }}
      }
    }
  {% endaction %}
{% endif %}
Task code is written in Mechanic Liquid, an extension of open-source Liquid enhanced for automation. Learn more
Defaults
Search query for orders
fulfillment_status:unshipped
Ignore orders with this tag
exported
Add this tag after export
exported
Export email subject
Unfulfilled orders for {{ "now" | date: "%Y-%m-%d" }}
Export email body
Hello,

Please see the attachment for currently unfulfilled orders.

Thanks,
Mechanic, for {{ shop.name }}
Export CSV filename
unfulfilled-orders-{{ "now" | date: "%Y-%m-%d" }}