Skip to content

Commit

Permalink
community task requests
Browse files Browse the repository at this point in the history
  • Loading branch information
tekhaus committed Feb 4, 2025
1 parent 869ba15 commit 46f998c
Show file tree
Hide file tree
Showing 11 changed files with 1,043 additions and 0 deletions.
16 changes: 16 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ This directory is built automatically. Each task's documentation is generated fr
* [Auto-tag products when another tag is added](./auto-tag-products-when-another-tag-is-added)
* [Auto-tag products when their variants change](./auto-tag-products-when-their-skus-change)
* [Auto-tag products with incoming inventory](./auto-tag-products-with-incoming-inventory)
* [Auto-tag products with their category](./auto-tag-products-with-their-category)
* [Auto-tag products with their vendors](./auto-tag-products-with-their-vendors)
* [Auto-tag products without descriptions](./auto-tag-products-without-descriptions)
* [Auto-untag customers when a certain product is refunded](./auto-untag-customers-when-a-certain-product-is-refunded)
Expand Down Expand Up @@ -313,6 +314,7 @@ This directory is built automatically. Each task's documentation is generated fr
* [Sync an inverse customer tag](./sync-an-inverse-customer-tag)
* [Sync an inverse order tag](./sync-an-inverse-order-tag)
* [Sync an inverse product tag](./sync-an-inverse-product-tag)
* [Sync in stock locations to a variant metafield](./sync-in-stock-locations-to-a-variant-metafield)
* [Sync inventory across a product type](./sync-inventory-across-a-product-type)
* [Sync inventory across product variants](./sync-inventory-across-product-variants)
* [Sync inventory for shared SKUs](./sync-inventory-for-shared-skus)
Expand All @@ -332,6 +334,7 @@ This directory is built automatically. Each task's documentation is generated fr
* [Tag orders that have at least x of a certain product](./tag-orders-that-have-at-least-x-of-a-certain-product)
* [Tag products as in- or out-of-stock, by location ID](./tag-products-as-in-or-out-of-stock-by-location-id)
* [Tag products as in- or out-of-stock](./tag-products-as-in-or-out-of-stock)
* [Tag products by metaobject reference field values](./tag-products-ny-metaobject-reference-field-values)
* [Tag products by their price ranges](./tag-products-by-their-price-ranges)
* [Tag products with no images](./tag-products-with-no-images)
* [Temporarily add an order note](./temporarily-add-an-order-note)
Expand Down Expand Up @@ -498,6 +501,7 @@ This directory is built automatically. Each task's documentation is generated fr
* [Auto-tag products when another tag is added](./auto-tag-products-when-another-tag-is-added)
* [Auto-tag products when their variants change](./auto-tag-products-when-their-skus-change)
* [Auto-tag products with incoming inventory](./auto-tag-products-with-incoming-inventory)
* [Auto-tag products with their category](./auto-tag-products-with-their-category)
* [Auto-tag products with their vendors](./auto-tag-products-with-their-vendors)
* [Auto-tag products without descriptions](./auto-tag-products-without-descriptions)
* [Copy order and/or product tags to customers](./copy-order-tags-to-customers)
Expand Down Expand Up @@ -596,6 +600,10 @@ This directory is built automatically. Each task's documentation is generated fr

* [Generate a simple product catalog PDF](./generate-a-simple-product-catalog-pdf)

### Category

* [Auto-tag products with their category](./auto-tag-products-with-their-category)

### Collections

* [Auto create collections by metafield values](./auto-create-collections-by-metafield-values)
Expand Down Expand Up @@ -1094,6 +1102,10 @@ This directory is built automatically. Each task's documentation is generated fr
* [Tag customers who reach a certain threshold of refunded orders](./tag-customers-who-reach-a-certain-threshold-of-refunded-orders)
* [Track incoming donations in a store metafield](./track-incoming-donations-in-a-store-metafield)

### Metaobjects

* [Tag products by metaobject reference field values](./tag-products-ny-metaobject-reference-field-values)

### Multi-Location

* [Auto-connect new products to all locations](./auto-connect-new-products-to-all-locations)
Expand Down Expand Up @@ -1343,6 +1355,7 @@ This directory is built automatically. Each task's documentation is generated fr
* [Auto-tag products when another tag is added](./auto-tag-products-when-another-tag-is-added)
* [Auto-tag products when their variants change](./auto-tag-products-when-their-skus-change)
* [Auto-tag products with incoming inventory](./auto-tag-products-with-incoming-inventory)
* [Auto-tag products with their category](./auto-tag-products-with-their-category)
* [Auto-tag products with their vendors](./auto-tag-products-with-their-vendors)
* [Auto-tag products without descriptions](./auto-tag-products-without-descriptions)
* [Auto-update inventory policy based on a "preorder" tag](./auto-update-inventory-policy-based-on-a-preorder-tag)
Expand Down Expand Up @@ -1395,6 +1408,7 @@ This directory is built automatically. Each task's documentation is generated fr
* [Sync inventory levels to variant metafields](./sync-inventory-levels-to-variant-metafields)
* [Sync variant inventory within a product by pack size](./sync-variant-inventory-within-a-product-by-pack-size)
* [Tag products as in- or out-of-stock](./tag-products-as-in-or-out-of-stock)
* [Tag products by metaobject reference field values](./tag-products-ny-metaobject-reference-field-values)
* [Tag products by their price ranges](./tag-products-by-their-price-ranges)
* [Tag products with no images](./tag-products-with-no-images)
* [Track incoming donations in a store metafield](./track-incoming-donations-in-a-store-metafield)
Expand Down Expand Up @@ -1666,6 +1680,7 @@ This directory is built automatically. Each task's documentation is generated fr
* [Tag customers on the anniversary of their first order](./tag-customers-on-the-anniversary-of-their-first-order)
* [Tag customers who reach a certain threshold of refunded orders](./tag-customers-who-reach-a-certain-threshold-of-refunded-orders)
* [Tag new orders of customers with prior unpaid orders](./tag-new-orders-of-customers-with-prior-unpaid-orders)
* [Tag products by metaobject reference field values](./tag-products-ny-metaobject-reference-field-values)
* [Tag products with no images](./tag-products-with-no-images)
* [Temporarily enable tax-exempt status when a customer is tagged](./temporarily-enable-tax-exempt-status-when-a-customer-is-tagged)
* [Trigger order emails with a tag](./trigger-order-emails-with-a-tag)
Expand Down Expand Up @@ -1712,6 +1727,7 @@ This directory is built automatically. Each task's documentation is generated fr
### Uncategorized

* [Mechanic tour task](./mechanic-tour-task)
* [Sync in stock locations to a variant metafield](./sync-in-stock-locations-to-a-variant-metafield)

### Unpaid

Expand Down
49 changes: 49 additions & 0 deletions docs/auto-tag-products-with-their-category/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Auto-tag products with their category

Tags: Auto-Tag, Category, Products

Use this task to tag products with their category from [Shopify's standard product taxonomy](https://shopify.github.io/product-taxonomy/releases/latest/). Run this task manually to scan every active product in your store. Optionally, set it to run daily to scan active products updated in the last day.

* View in the task library: [tasks.mechanic.dev/auto-tag-products-with-their-category](https://tasks.mechanic.dev/auto-tag-products-with-their-category)
* Task JSON, for direct import: [task.json](../../tasks/auto-tag-products-with-their-category.json)
* Preview task code: [script.liquid](./script.liquid)

## Default options

```json
{
"apply_this_prefix_to_tags__required": "category: ",
"run_task_daily__boolean": false
}
```

[Learn about task options in Mechanic](https://learn.mechanic.dev/core/tasks/options)

## Subscriptions

```liquid
{% if options.run_task_daily__boolean %}
mechanic/scheduler/daily
{% endif %}
mechanic/user/trigger
```

[Learn about event subscriptions in Mechanic](https://learn.mechanic.dev/core/tasks/subscriptions)

## Documentation

Use this task to tag products with their category from [Shopify's standard product taxonomy](https://shopify.github.io/product-taxonomy/releases/latest/). Run this task manually to scan every active product in your store. Optionally, set it to run daily to scan active products updated in the last day.

Note: A tag prefix must be configured so the task will know which category tag(s) to remove from a product if applicable.

## Installing this task

Find this task [in the library at tasks.mechanic.dev](https://tasks.mechanic.dev/auto-tag-products-with-their-category), and use the "Try this task" button. Or, import [this task's JSON export](../../tasks/auto-tag-products-with-their-category.json) – see [Importing and exporting tasks](https://learn.mechanic.dev/core/tasks/import-and-export) to learn how imports work.

## Contributions

Found a bug? Got an improvement to add? Start here: [../../CONTRIBUTING.md](../../CONTRIBUTING.md).

## Task requests

Submit your [task requests](https://mechanic.canny.io/task-requests) for consideration by the Mechanic community, and they may be chosen for development and inclusion in the [task library](https://tasks.mechanic.dev/)!
148 changes: 148 additions & 0 deletions docs/auto-tag-products-with-their-category/script.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
{% assign tag_prefix = options.apply_this_prefix_to_tags__required %}

{% if event.topic == "mechanic/user/trigger" or event.topic == "mechanic/scheduler/daily" %}
{% assign search_query = "status:active" %}

{% comment %}
-- if this is a daily scheduled run, then create a search query filter to only get active products updated since previous day
{% endcomment %}

{% if event.topic contains "mechanic/scheduler/daily" %}
{% assign search_query
= event.data
| date: "%FT%TZ", tz: "UTC", advance: "-1 day"
| json
| prepend: "status:active updated_at:>="
%}
{% endif %}

{% unless event.preview %}
{% log search_query: search_query %}
{% endunless %}

{% comment %}
-- get all or recently updated active products in the shop, depending upon event topic
{% endcomment %}

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

{% for n in (1..200) %}
{% capture query %}
query {
products(
first: 250
after: {{ cursor | json }}
query: {{ search_query | json }}
) {
pageInfo {
hasNextPage
endCursor
}
nodes {
id
title
category {
name
isArchived
}
tags
}
}
}
{% endcapture %}

{% assign result = query | shopify %}

{% if event.preview %}
{% capture result_json %}
{
"data": {
"products": {
"nodes": [
{
"id": "gid://shopify/Product/1234567890",
"category": {
"name": "Shoes",
"isArchived": false
}
}
]
}
}
}
{% endcapture %}

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

{% assign products = products | concat: result.data.products.nodes %}

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

{% comment %}
-- process products to see which category tag to add, and which to remove
{% endcomment %}

{% for product in products %}
{% assign tag_should_have = nil %}
{% assign tag_to_add = nil %}
{% assign tags_to_remove = array %}

{% unless product.category == blank or product.category.isArchived %}
{% assign tag_should_have = product.category.name | prepend: tag_prefix %}
{% endunless %}

{% unless product.tags contains tag_should_have %}
{% assign tag_to_add = tag_should_have %}
{% endunless %}

{% for tag in product.tags %}
{% if tag == tag_should_have %}
{% continue %}
{% endif %}

{% if tag contains tag_prefix %}
{% assign tag_prefix_check = tag | slice: 0, tag_prefix.size %}

{% if tag_prefix_check == tag_prefix and tag.size > tag_prefix.size %}
{% assign tags_to_remove = tags_to_remove | push: tag %}
{% endif %}
{% endif %}
{% endfor %}

{% if tag_to_add != blank or tags_to_remove != blank %}
{% action "shopify" %}
mutation {
{% if tag_to_add != blank %}
tagsAdd(
id: {{ product.id | json }}
tags: {{ tag_to_add | json }}
) {
userErrors {
field
message
}
}
{% endif %}
{% if tags_to_remove != blank %}
tagsRemove(
id: {{ product.id | json }}
tags: {{ tags_to_remove | json }}
) {
userErrors {
field
message
}
}
{% endif %}
}
{% endaction %}
{% endif %}
{% endfor %}
{% endif %}
61 changes: 61 additions & 0 deletions docs/sync-in-stock-locations-to-a-variant-metafield/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Sync in stock locations to a variant metafield

Tags: (not tagged!)

This task will maintain a variant list metafield of in stock location names. Running on a schedule, it will check recently updated variants to see which are in stock at each location. Variants with positive "available" inventory at a location, or are configured for overselling, are considered to be in stock, as are variants that are sold from a location but not tracked.

* View in the task library: [tasks.mechanic.dev/sync-in-stock-locations-to-a-variant-metafield](https://tasks.mechanic.dev/sync-in-stock-locations-to-a-variant-metafield)
* Task JSON, for direct import: [task.json](../../tasks/sync-in-stock-locations-to-a-variant-metafield.json)
* Preview task code: [script.liquid](./script.liquid)

## Default options

```json
{
"variant_metafield__required": "custom.in_stock_locations",
"include_location_names__array": null,
"exclude_location_names__array": null,
"run_every_10_minutes__boolean": false,
"run_hourly__boolean": true,
"run_daily__boolean": false
}
```

[Learn about task options in Mechanic](https://learn.mechanic.dev/core/tasks/options)

## Subscriptions

```liquid
{% if options.run_every_10_minutes__boolean %}
mechanic/scheduler/10min
{% elsif options.run_hourly__boolean %}
mechanic/scheduler/hourly
{% elsif options.run_daily__boolean %}
mechanic/scheduler/daily
{% endif %}
mechanic/user/trigger
```

[Learn about event subscriptions in Mechanic](https://learn.mechanic.dev/core/tasks/subscriptions)

## Documentation

This task will maintain a variant list metafield of in stock location names. Running on a schedule, it will check recently updated variants to see which are in stock at each location. Variants with positive "available" inventory at a location, or are configured for overselling, are considered to be in stock, as are variants that are sold from a location but not tracked.

Optionally, you may choose to have this task only check specific locations using the "Include location names" option, or to ignore specific locations using the "Exclude location names" option. Exclusions will only apply if the inclusions field is empty.

Run the task manually to scan all variants (up to 25K) in the shop for initial setup.

**Important:** if you wish the configured variant metafield to be used as a search filter on your website using [Shopify Search & Discovery](https://help.shopify.com/en/manual/online-store/search-and-discovery), then you must set up a [custom metafield definition](https://help.shopify.com/en/manual/custom-data/metafields/metafield-definitions/creating-custom-metafield-definitions) for it *before* running this task. Otherwise, you will not be able to create the metafield definition with a "list.single_line_text_field" type.

## Installing this task

Find this task [in the library at tasks.mechanic.dev](https://tasks.mechanic.dev/sync-in-stock-locations-to-a-variant-metafield), and use the "Try this task" button. Or, import [this task's JSON export](../../tasks/sync-in-stock-locations-to-a-variant-metafield.json) – see [Importing and exporting tasks](https://learn.mechanic.dev/core/tasks/import-and-export) to learn how imports work.

## Contributions

Found a bug? Got an improvement to add? Start here: [../../CONTRIBUTING.md](../../CONTRIBUTING.md).

## Task requests

Submit your [task requests](https://mechanic.canny.io/task-requests) for consideration by the Mechanic community, and they may be chosen for development and inclusion in the [task library](https://tasks.mechanic.dev/)!
Loading

0 comments on commit 46f998c

Please sign in to comment.