lightward / mechanic-tasks Goto Github PK
View Code? Open in Web Editor NEWPublic task repository for Mechanic (https://mechanic.dev)
Home Page: https://tasks.mechanic.dev/
License: MIT License
Public task repository for Mechanic (https://mechanic.dev)
Home Page: https://tasks.mechanic.dev/
License: MIT License
https://tasks.mechanic.dev/cancel-and-close-unpaid-orders-after-two-days
Right now, this task queries for financial_status:pending
. I think this additional should be optional (open to discussion on that one), but I'd like it to include support for financial_status:expired
as well. (The "expired" state feels like a substate of "pending", to me.)
Currently, this task looks at totalInventory to determine if a product is sold out. However, if a product variant's inventory policy is set to Continue, the front-end of Shopify doesn't show this item as sold out. The result is a mix of sold-out and technically not sold-out products at the end of the sorted collection.
From Shopify's docs: "inventory_policy - Whether customers are allowed to place an order for the product variant when it's out of stock."
In order to support looking at this field, we'd need to look at the product variants for totalInventory = 0 products. This may not be possible without moving to bulk operations which is a significant change to the logic of this task.
Mechanic has a task using the fulfillmentService attribute on line items, which has been deprecated (oddly with no notice in the developer change log that I can find).
It looks like this field should now be accessed from the variant (per the Map here).
Task that needs to be patched: https://tasks.mechanic.dev/auto-tag-orders-that-are-ready-to-ship
Slack: https://usemechanic.slack.com/archives/C039BQGF8LV/p1650557893948089
Runtime Error using the oldest supported Shopify Admin API version.
The field Publication.name is deprecated. Use Catalog.title instead.
https://tasks.mechanic.dev/auto-fulfill-items-that-dont-require-shipping
(notes below all describe what's available in 2023-04)
We need that requiresShipping
field, and it turns out that it's available one level up on FulfillmentOrderLineItem.requiresShipping
.
FulfillmentOrderLineItem
doesn't have any references to the original product or variant (which - sigh - I understand but don't love), so I think this task will necessarily have to drop the "Ignore products with this tag" option.
This customer is being marked as opted-in because the task checks the marketingOptInLevel, but I think that just represents what the opt-in level was when they signed up, not that they opted in, I think the marketingState switches from pending on the double confirm
Update to this task: https://tasks.mechanic.dev/abandoned-checkout-emails
The default shopify template for abandoned checkouts can be found in notification settings
Modernize task to use bulk operations.
https://tasks.mechanic.dev/sync-inventory-for-shared-skus
The inventoryBulkAdjustQuantityAtLocation
mutation has a 100-item limit. Update this task to group updates into sets of at most 100, generating as many mutations as needed.
Typical error:
GraphQL operation returned userErrors: { "inventoryBulkAdjustQuantityAtLocation": { "userErrors": [ { "field": null, "message": "Quantity can't be adjusted for more than 100 items." } ] } }
https://tasks.mechanic.dev/hide-out-of-stock-products
Shopify's QueryRoot.products
connection supports filtering by inventory_total
(docs)! Was this always the case and I just didn't know it? 🤪
The change is tiny but significant for query efficiency, I'm just pressed for time at the moment so it's easier to record this for later:
For copy/paste purposes:
query: "inventory_total:<={{ options.out_of_stock_inventory_quantity__number_required }}"
*make sure "set default values" appears in the docs
On the Slack workspace, a developer raised an issue where the Send a PDF invoice when an order is created task was returning incorrect prices. As noted in the discussion, the issue is caused by Shopify's API presenting currency values in their dollars and cents format, rather than cents only as the Shopify theming system does. This creates a conflict in how currencies are calculated, resulting in any currencies formatted with money filters being 100x too small.
The simple solution for most currencies is to multiple the currency value by 100 before using a money filter, like so: {{ price | times: 100 | money_with_currency }}
. However, there are several currencies supported by Shopify which are not divisible by 100, which makes this solution not entirely reliable. I've attempted to make a complete list of supported currencies where this would be an issue, and this is what I came up with. It may not be exhaustive:
Before creating a pull request to fix this particular task, a more robust solution is required. I am currently at a loss as to the proper way to fix this.
References
List of Global Currencies: https://en.wikipedia.org/wiki/List_of_circulating_currencies
Shopify Supported Currencies: https://help.shopify.com/en/manual/payments/shopify-payments/multi-currency#supported-currencies
This task also hides gift card products. (There's a isGiftCard field on the product object btw)
Perhaps also check for the value "continue selling when out of stock" is checked? (ProductVariantInventoryPolicy)
https://mechanic.canny.io/task-requests/p/copy-tag-to-metafield
Metafields are becoming critical with OS 2.0 - https://help.shopify.com/en/manual/online-store/themes/customizing-themes/storefront-filters#custom-filters
The goal here is to provide a way for users to move from tags to metafields, if needed.
Also inspired by: https://tasks.mechanic.dev/copy-product-metafields-to-each-products-tags.
https://tasks.mechanic.dev/auto-tag-products-when-another-tag-is-added
Add a manually triggered mode that looks at all existing products
Concerning Publication.title, Shopify says:
Name of the publication. Use Catalog.title instead.
The task library uses publications in many places. (As an example, this issue came up re: Auto-tag customers by sales channel.)
The Task in mechanic Auto-tag orders that contain subscription products has an issue with the Permission Scoping
This is the Task I am mentioning here: https://github.com/lightward/mechanic-tasks/blob/main/tasks/auto-tag-orders-that-contain-subscription-products.json
I'll post the quickfix I did here but may need investigation as the Dev who wrote it does have the action within global scope and should be picked up by mechanic for granting the additional scope but it doesn't unless I'm missing something.
Task code (Not granting write_orders Permission)
{% if event.topic == "shopify/orders/create" %}
{% capture query %}
query {
order(id: {{ order.admin_graphql_api_id | json }}) {
id
name
tags
lineItems(first: 100) {
edges {
node {
id
sellingPlan {
name
}
}
}
}
}
}
{% endcapture %}
{% assign result = query | shopify %}
{% assign orders[0] = result.data.order %}
{% elsif event.topic == "mechanic/user/trigger" %}
{% assign cursor = nil %}
{% for n in (1..2500) %}
{% capture query %}
query {
orders(
first: 4
after: {{ cursor | json }}
reverse: true
) {
pageInfo {
hasNextPage
}
edges {
cursor
node {
id
name
tags
lineItems(first: 100) {
edges {
node {
id
sellingPlan {
name
}
}
}
}
}
}
}
}
{% endcapture %}
{% assign result = query | shopify %}
{% assign orders_batch = result.data.orders.edges | map: "node" %}
{% assign orders = orders | concat: orders_batch %}
{% if result.data.orders.pageInfo.hasNextPage %}
{% assign cursor = result.data.orders.edges.last.cursor %}
{% else %}
{% break %}
{% endif %}
{% endfor %}
{% endif %}
{% if event.preview %}
{% capture orders_json %}
[
{
"id": "gid://shopify/Order/1234567890",
"name": "#TEST",
"lineItems": {
"edges": [
{
"node": {
"sellingPlan": [
{
"name": "Subscription, Delivery every month"
}
]
}
},
{
"node": {
"sellingPlan": [
{
"name": "Subscription, Delivery every month"
}
]
}
}
]
}
}
]
{% endcapture %}
{% assign orders = orders_json | parse_json %}
{% endif %}
{% for order in orders %}
{% assign order_qualifies = false %}
{% assign line_items = order.lineItems.edges | map: "node" %}
{% for line_item in line_items %}
{% if line_item.sellingPlan.name != blank %}
{% assign order_qualifies = true %}
{% log line_item.sellingPlan.name %}
{% break %}
{% endif %}
{% endfor %}
{% if order_qualifies %}
{% action "shopify" %}
mutation {
tagsAdd(
id: {{ order.id | json }}
tags: {{ options.tag_to_apply__required | json }}
) {
node {
... on Order {
id
name
tags
}
}
userErrors {
field
message
}
}
}
{% endaction %}
{% endif %}
{% endfor %}
At the end of the Task I added:
{% if options.tag_to_apply__required != blank %}
{% action "shopify" %}
mutation {
tagsAdd(
id: "gid://shopify/Order/1234567890"
tags: {{ options.tag_to_apply__required | json }}
) {
userErrors {
field
message
}
}
}
{% endaction %}
{% endif %}
{% endif %}
Not sure but I'm thinking it's either b/c Mechanic is looking for a string for the "id" perhaps? Or the Dev used the node in the GraphQL.
I may be missing something completely if so I apologize :P But figured worth bringing up at least!
https://tasks.mechanic.dev/find-duplicate-skus
Typically this kind of refactor is warranted for memory reasons, but this time it's for runtime duration reasons. :) Also, by going with bulk operations, we can scan all variants instead of just the first n.
Auto-fulfill items that don't require shipping
Add an option to include products with a specific tag -
https://tasks.mechanic.dev/auto-fulfill-items-that-dont-require-shipping
Typo in code - the word fulfillment is spelled fulfillment in a few spots in the code.
https://tasks.mechanic.dev/auto-fulfill-orders-when-tagged
When there are multiple shipping types on an order, for example, one fulfillment order doesn't require shipping, and others do, fulfillmentCreateV2 throws an error:
I think we need to update this task to group the fulfillment mutations by delivery method type. :
SHIPPING
The order is shipped.
PICK_UP
The order is picked up by the customer.
NONE
No delivery is needed.
RETAIL
The order is delivered to a retail store.
LOCAL
The order is delivered using a local delivery service.
https://shopify.dev/api/admin-graphql/2022-04/enums/DeliveryMethodType
https://tasks.mechanic.dev/auto-capture-payments-when-an-order-is-created
With the introduction of Shop Cash - https://help.shop.app/hc/en-us/articles/5052986190612-Shop-Cash it looks like split payments will become more common.
We had a user write in and say that the user used some shop cash and a cc, and only one of those methods was auto-captured.
This report appears to include gift card products with infinitive inventory. It would be more accurate to exclude these types of products as it can never go out of stock.
Similar to this task: https://tasks.mechanic.dev/auto-associate-products-with-a-delivery-profile-by-product-tag
But, for variants. And, because variants don't have tags, we'll need to use some other attribute(s) to assign the the shipping profile.
Sku? metafield?
Convert product template task to use bulk operations
https://tasks.mechanic.dev/set-product-templates-based-on-product-tags
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
This repository currently has no open or pending branches.
.github/workflows/cla.yml
contributor-assistant/github-action v2.3.2
.github/workflows/test.yml
actions/checkout v4
actions/setup-node v4
package.json
@shopify/prettier-config 1.1.2
ajv 8.12.0
dir-compare 4.2.0
glob 10.3.12
husky ^9.0.7
lint-staged 15.2.2
prettier 3.2.5
sort-json 2.0.1
node >=20 <21
npm >=10 <11
The recent prettier additions to this repo has an inconsistency somewhere in the build and commit steps.
After every PR submission, I see more and more JSON task files which format arrays in different ways.
diff --git a/tasks/error-reporter.json b/tasks/error-reporter.json
index 74c23b5..a17b815 100644
--- a/tasks/error-reporter.json
+++ b/tasks/error-reporter.json
@@ -53,5 +53,8 @@
"mechanic/errors/action"
],
"subscriptions_template": "mechanic/errors/event\nmechanic/errors/task\nmechanic/errors/action",
- "tags": ["Alert", "Error"]
+ "tags": [
+ "Alert",
+ "Error"
+ ]
}
Task: https://tasks.mechanic.dev/maintain-collections-by-product-metafield-values
I think we'll need to break this up into multiple mutations if there are too many products to add or remove
https://tasks.mechanic.dev/auto-tag-orders-that-are-ready-to-ship
{% if options.ignore_line_items_not_fulfilled_manually__boolean %} fulfillmentService { id } {% endif %}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.