Mechanic is a development and ecommerce automation platform for Shopify. :)
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.
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?)
mechanic/user/trigger {% if options.run_export_nightly__boolean %}mechanic/scheduler/daily{% endif %}
{% 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 %}
fulfillment_status:unshipped
exported
exported
Unfulfilled orders for {{ "now" | date: "%Y-%m-%d" }}
Hello, Please see the attachment for currently unfulfilled orders. Thanks, Mechanic, for {{ shop.name }}
unfulfilled-orders-{{ "now" | date: "%Y-%m-%d" }}