The "shopify" action
Anything that Shopify allows developers to do, Mechanic lets you automate. This means that you can create, update, or delete nearly anything in your Shopify account.
The "shopify" action has three styles of usage:
- Resourceful REST, which uses Shopify's REST admin API in a style reminiscent of ActiveResource
- Explicit REST, which uses Shopify's REST admin API with explicitly defined values for HTTP method, url, and body
- GraphQL, which uses Shopify's GraphQL admin API
Use resourceful REST if it's easy to do so – its job is to keep simple things simple. Use explicit REST if you need to get really specific about how your API request works. Use GraphQL when you need a feature not available in the REST API, or if it's otherwise more convenient/natural to do so.
Tip: if you're working with tags, always use GraphQL, to avoid accidentally overwriting tags added or removed by a simultaneously-running task (see How do I add or remove tags for Shopify resources?).
Resourceful REST
Accepts an array of options, containing these elements in order:
- Operation
Must be one of"create"
,"update"
, or"delete"
. - Resource specification
When creating, use a single string (e.g."customer"
).
When updating or deleting, use an array (e.g.["customer", 123]
). - An object of attributes
Only applies to creating and updating.
A task which tags a customer upon ordering might look like this:
{% action "shopify" %} [ "update", [ "customer", {{ order.customer.id | json }} ], { "tags": {{ order.customer.tags | add_tag: "ordered" | json }} } ] {% endaction %}
Explicit REST
Accepts an array of options, containing these elements in order:
- Operation
Must be one of"post"
,"put"
, or"delete"
- Request path
Literally, the path you want to request from Shopify – the entire path. For example,/admin/orders.json
. - An object of attributes
Same as the resourceful options style except that it must be wrapped in a parent object, with a single key named after the resource type. (This wrapping is required by Shopify regardless, but it's handled automatically during resourceful usage. Here, it's something you need to handle manually.)
A task which tags a customer upon ordering might look like this:
{% action "shopify" %} [ "put", "/admin/customers/{{ order.customer.id }}.json", { "customer": { "tags": {{ order.customer.tags | add_tag: "ordered" | json }} } } ] {% endaction %}
GraphQL
Accepts a valid GraphQL query.
A task which tags a customer upon ordering might look like this:
{% assign customer = shop.customers[order.customer.id] %} {% action "shopify" %} mutation { tagsAdd( id: {{ customer.admin_graphql_api_id | json }} tags: "ordered" ) { userErrors { field message } } } {% endaction %}
The "shopify" action may also be used with tag syntax:
{% capture query %}...{% endcapture %} {% action "shopify" query %}
Using GraphQL variables
Because GraphQL queries (excluding whitespace) are limited to 50,000 characters, you may encounter scenarios in which you need to fall back to GraphQL variables to provide larger inputs.
To provide these variables, supply the "shopify" action with a JSON object containing a "query"
key and a "variables"
key.
{% capture query %} mutation DeleteProduct($productId: ID!) { productDelete( input: { id: $productId } ) { userErrors { field message } } } {% endcapture %} {% action "shopify" %} { "query": {{ query | json }}, "variables": { "productId": "gid://shopify/Product/1234567890" } } {% endaction %}
Here's a more detailed example, showing how the query and variables may be built up separately, and provided to the action using concise tag syntax:
{% capture query %} mutation SetCustomerMetafield( $customerId: ID! $metafieldNamespace: String! $metafieldKey: String! $metafieldId: ID $metafieldValue: String! ) { customerUpdate( input: { id: $customerId metafields: [ { id: $metafieldId namespace: $metafieldNamespace key: $metafieldKey valueType: STRING value: $metafieldValue } ] } ) { userErrors { field message } customer { metafield( namespace: $metafieldNamespace key: $metafieldKey ){ id } } } } {% endcapture %} {% assign customer_id = 806736592949 %} {% assign customer = shop.customers[customer_id] %} {% assign existing_metafield = customer.metafields.test | where: "key", "test" | first %} {% assign variables = hash %} {% assign variables["customerId"] = customer.admin_graphql_api_id %} {% assign variables["metafieldNamespace"] = "test" %} {% assign variables["metafieldKey"] = "test" %} {% assign variables["metafieldId"] = existing_metafield.admin_graphql_api_id %} {% assign variables["metafieldValue"] = "now" | date: "%s" %} {% action "shopify" query: query, variables: variables %