@clawpify/skills 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +73 -0
- package/clawpify/SKILL.md +134 -0
- package/clawpify/references/blogs.md +385 -0
- package/clawpify/references/bulk-operations.md +386 -0
- package/clawpify/references/collections.md +71 -0
- package/clawpify/references/customers.md +141 -0
- package/clawpify/references/discounts.md +431 -0
- package/clawpify/references/draft-orders.md +495 -0
- package/clawpify/references/files.md +355 -0
- package/clawpify/references/fulfillments.md +437 -0
- package/clawpify/references/gift-cards.md +453 -0
- package/clawpify/references/inventory.md +107 -0
- package/clawpify/references/locations.md +349 -0
- package/clawpify/references/marketing.md +352 -0
- package/clawpify/references/markets.md +346 -0
- package/clawpify/references/menus.md +313 -0
- package/clawpify/references/metafields.md +461 -0
- package/clawpify/references/orders.md +164 -0
- package/clawpify/references/pages.md +308 -0
- package/clawpify/references/products.md +277 -0
- package/clawpify/references/refunds.md +401 -0
- package/clawpify/references/segments.md +319 -0
- package/clawpify/references/shipping.md +406 -0
- package/clawpify/references/shop.md +307 -0
- package/clawpify/references/subscriptions.md +429 -0
- package/clawpify/references/translations.md +270 -0
- package/clawpify/references/webhooks.md +400 -0
- package/dist/agent.d.ts +18 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +100 -0
- package/dist/auth.d.ts +34 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +58 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/mcp-server.d.ts +3 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +236 -0
- package/dist/shopify.d.ts +29 -0
- package/dist/shopify.d.ts.map +1 -0
- package/dist/shopify.js +41 -0
- package/dist/skills.d.ts +8 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +36 -0
- package/package.json +100 -0
- package/src/agent.ts +133 -0
- package/src/auth.ts +109 -0
- package/src/index.ts +55 -0
- package/src/mcp-server.ts +190 -0
- package/src/shopify.ts +63 -0
- package/src/skills.ts +42 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Clawpify
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Clawpify
|
|
2
|
+
|
|
3
|
+
Shopify Agent SDK. Query and manage Shopify stores with AI agents and MCP.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @clawpify/skills
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { ShopifyClient } from "@clawpify/skills";
|
|
15
|
+
|
|
16
|
+
const client = new ShopifyClient({
|
|
17
|
+
storeUrl: "my-store.myshopify.com",
|
|
18
|
+
accessToken: "shpat_xxxxx",
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const { data } = await client.graphql(`{
|
|
22
|
+
products(first: 5) {
|
|
23
|
+
nodes { id title }
|
|
24
|
+
}
|
|
25
|
+
}`);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## AI Agent
|
|
29
|
+
|
|
30
|
+
Requires `@anthropic-ai/sdk`:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { ShopifyClient } from "@clawpify/skills";
|
|
34
|
+
import { ShopifyAgent } from "@clawpify/skills/agent";
|
|
35
|
+
import { loadSkills } from "@clawpify/skills/skills";
|
|
36
|
+
|
|
37
|
+
const client = new ShopifyClient({ storeUrl, accessToken });
|
|
38
|
+
const agent = new ShopifyAgent({ shopify: client, skillContent: await loadSkills() });
|
|
39
|
+
|
|
40
|
+
const result = await agent.chat("List my products");
|
|
41
|
+
console.log(result.response);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## MCP Server
|
|
45
|
+
|
|
46
|
+
Add to `~/.claude/mcp.json`:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"mcpServers": {
|
|
51
|
+
"shopify": {
|
|
52
|
+
"command": "npx",
|
|
53
|
+
"args": ["@clawpify/skills"]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Create `~/.clawpify/.env`:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
SHOPIFY_STORE_URL=your-store.myshopify.com
|
|
63
|
+
SHOPIFY_CLIENT_ID=your-client-id
|
|
64
|
+
SHOPIFY_CLIENT_SECRET=shpss_xxxxx
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## What It Covers
|
|
68
|
+
|
|
69
|
+
Products, Orders, Customers, Inventory, Discounts, Collections, Gift Cards, Refunds, Draft Orders, Webhooks, and [more](./clawpify/references/).
|
|
70
|
+
|
|
71
|
+
## License
|
|
72
|
+
|
|
73
|
+
MIT
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: clawpify
|
|
3
|
+
description: Query and manage Shopify stores via GraphQL Admin API. Use for products, orders, customers, inventory, discounts, and all Shopify data operations.
|
|
4
|
+
dependencies:
|
|
5
|
+
- Tool: shopify_graphql (from MCP server or custom function)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Shopify GraphQL Admin API
|
|
9
|
+
|
|
10
|
+
A comprehensive skill for interacting with Shopify's GraphQL Admin API. This skill enables Claude to query and manage all aspects of Shopify store data.
|
|
11
|
+
|
|
12
|
+
## When to Use This Skill
|
|
13
|
+
|
|
14
|
+
Use this skill when the user asks about:
|
|
15
|
+
- Products (list, search, create, update, delete)
|
|
16
|
+
- Orders (view, cancel, fulfill)
|
|
17
|
+
- Customers (list, create, update)
|
|
18
|
+
- Inventory (check levels, adjust quantities)
|
|
19
|
+
- Discounts (create codes, manage promotions)
|
|
20
|
+
- Any other Shopify store operations
|
|
21
|
+
|
|
22
|
+
## Critical Operations Requiring Permission
|
|
23
|
+
|
|
24
|
+
IMPORTANT: Before executing any of the following operations, you MUST ask for explicit user permission:
|
|
25
|
+
|
|
26
|
+
- Refunds: Create refunds (permanent financial transactions)
|
|
27
|
+
- Order Cancellations: Cancel orders (may trigger refunds)
|
|
28
|
+
- Gift Card Deactivation: Permanently disable gift cards
|
|
29
|
+
- Inventory Adjustments: Modify stock levels
|
|
30
|
+
- Product Deletions: Permanently remove products
|
|
31
|
+
- Discount Activations: Change pricing for customers
|
|
32
|
+
|
|
33
|
+
Always show what will be changed and wait for user confirmation.
|
|
34
|
+
|
|
35
|
+
## How to Use
|
|
36
|
+
|
|
37
|
+
1. Use the `shopify_graphql` tool to execute queries
|
|
38
|
+
2. Check for `errors` (GraphQL issues) and `userErrors` (validation issues)
|
|
39
|
+
3. Use pagination with `first`/`after` for large result sets
|
|
40
|
+
4. Format all IDs as: `gid://shopify/Resource/123`
|
|
41
|
+
|
|
42
|
+
## Available References
|
|
43
|
+
|
|
44
|
+
For detailed patterns and examples, refer to the reference documents:
|
|
45
|
+
- products.md - Products and variants management
|
|
46
|
+
- orders.md - Order operations
|
|
47
|
+
- customers.md - Customer management
|
|
48
|
+
- inventory.md - Inventory and locations
|
|
49
|
+
- discounts.md - Discount codes and promotions
|
|
50
|
+
- collections.md - Product collections
|
|
51
|
+
- fulfillments.md - Order fulfillment and shipping
|
|
52
|
+
- refunds.md - Process refunds
|
|
53
|
+
- draft-orders.md - Draft order creation
|
|
54
|
+
- gift-cards.md - Gift card management
|
|
55
|
+
- webhooks.md - Event subscriptions
|
|
56
|
+
- locations.md - Store locations
|
|
57
|
+
- marketing.md - Marketing activities
|
|
58
|
+
- markets.md - Multi-market setup
|
|
59
|
+
- menus.md - Navigation menus
|
|
60
|
+
- metafields.md - Custom data fields
|
|
61
|
+
- pages.md - Store pages
|
|
62
|
+
- blogs.md - Blog management
|
|
63
|
+
- files.md - File uploads
|
|
64
|
+
- shipping.md - Shipping configuration
|
|
65
|
+
- shop.md - Store information
|
|
66
|
+
- subscriptions.md - Subscription management
|
|
67
|
+
- translations.md - Content translations
|
|
68
|
+
- segments.md - Customer segments
|
|
69
|
+
- bulk-operations.md - Bulk data operations
|
|
70
|
+
|
|
71
|
+
## Quick Examples
|
|
72
|
+
|
|
73
|
+
### List Recent Orders
|
|
74
|
+
```graphql
|
|
75
|
+
query {
|
|
76
|
+
orders(first: 10, sortKey: CREATED_AT, reverse: true) {
|
|
77
|
+
nodes {
|
|
78
|
+
id
|
|
79
|
+
name
|
|
80
|
+
totalPriceSet {
|
|
81
|
+
shopMoney { amount currencyCode }
|
|
82
|
+
}
|
|
83
|
+
customer { displayName }
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Search Products
|
|
90
|
+
```graphql
|
|
91
|
+
query {
|
|
92
|
+
products(first: 10, query: "title:*shirt* AND status:ACTIVE") {
|
|
93
|
+
nodes {
|
|
94
|
+
id
|
|
95
|
+
title
|
|
96
|
+
status
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Check Inventory
|
|
103
|
+
```graphql
|
|
104
|
+
query GetInventory($id: ID!) {
|
|
105
|
+
inventoryItem(id: $id) {
|
|
106
|
+
id
|
|
107
|
+
inventoryLevels(first: 5) {
|
|
108
|
+
nodes {
|
|
109
|
+
quantities(names: ["available"]) {
|
|
110
|
+
name
|
|
111
|
+
quantity
|
|
112
|
+
}
|
|
113
|
+
location { name }
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Error Handling
|
|
121
|
+
|
|
122
|
+
Always check responses:
|
|
123
|
+
- `errors` array = GraphQL syntax issues
|
|
124
|
+
- `userErrors` in mutations = validation problems
|
|
125
|
+
|
|
126
|
+
## Best Practices
|
|
127
|
+
|
|
128
|
+
1. Request only needed fields to optimize response size
|
|
129
|
+
2. Use pagination for lists that may grow
|
|
130
|
+
3. Check userErrors in all mutation responses
|
|
131
|
+
4. Ask permission before dangerous operations
|
|
132
|
+
5. Format results clearly for the user
|
|
133
|
+
6. Use bulk operations for large data exports/imports
|
|
134
|
+
7. Handle rate limits with exponential backoff
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
# Shopify Blogs & Articles
|
|
2
|
+
|
|
3
|
+
Manage blogs and blog articles via the GraphQL Admin API.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Blogs are containers for articles (blog posts). Each shop can have multiple blogs, and each blog contains multiple articles.
|
|
8
|
+
|
|
9
|
+
## List Blogs
|
|
10
|
+
|
|
11
|
+
```graphql
|
|
12
|
+
query ListBlogs($first: Int!) {
|
|
13
|
+
blogs(first: $first) {
|
|
14
|
+
nodes {
|
|
15
|
+
id
|
|
16
|
+
title
|
|
17
|
+
handle
|
|
18
|
+
articlesCount {
|
|
19
|
+
count
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
Variables: `{ "first": 10 }`
|
|
26
|
+
|
|
27
|
+
## Get Blog
|
|
28
|
+
|
|
29
|
+
```graphql
|
|
30
|
+
query GetBlog($id: ID!) {
|
|
31
|
+
blog(id: $id) {
|
|
32
|
+
id
|
|
33
|
+
title
|
|
34
|
+
handle
|
|
35
|
+
articlesCount {
|
|
36
|
+
count
|
|
37
|
+
}
|
|
38
|
+
articles(first: 10) {
|
|
39
|
+
nodes {
|
|
40
|
+
id
|
|
41
|
+
title
|
|
42
|
+
publishedAt
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
Variables: `{ "id": "gid://shopify/Blog/123" }`
|
|
49
|
+
|
|
50
|
+
## Create Blog
|
|
51
|
+
|
|
52
|
+
```graphql
|
|
53
|
+
mutation CreateBlog($blog: BlogCreateInput!) {
|
|
54
|
+
blogCreate(blog: $blog) {
|
|
55
|
+
blog {
|
|
56
|
+
id
|
|
57
|
+
title
|
|
58
|
+
handle
|
|
59
|
+
}
|
|
60
|
+
userErrors {
|
|
61
|
+
field
|
|
62
|
+
message
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
Variables:
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"blog": {
|
|
71
|
+
"title": "Company News",
|
|
72
|
+
"handle": "news"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Update Blog
|
|
78
|
+
|
|
79
|
+
```graphql
|
|
80
|
+
mutation UpdateBlog($id: ID!, $blog: BlogUpdateInput!) {
|
|
81
|
+
blogUpdate(id: $id, blog: $blog) {
|
|
82
|
+
blog {
|
|
83
|
+
id
|
|
84
|
+
title
|
|
85
|
+
handle
|
|
86
|
+
}
|
|
87
|
+
userErrors {
|
|
88
|
+
field
|
|
89
|
+
message
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
Variables:
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"id": "gid://shopify/Blog/123",
|
|
98
|
+
"blog": {
|
|
99
|
+
"title": "Latest News"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Delete Blog
|
|
105
|
+
|
|
106
|
+
```graphql
|
|
107
|
+
mutation DeleteBlog($id: ID!) {
|
|
108
|
+
blogDelete(id: $id) {
|
|
109
|
+
deletedBlogId
|
|
110
|
+
userErrors {
|
|
111
|
+
field
|
|
112
|
+
message
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## List Articles
|
|
119
|
+
|
|
120
|
+
```graphql
|
|
121
|
+
query ListArticles($first: Int!, $after: String, $query: String) {
|
|
122
|
+
articles(first: $first, after: $after, query: $query, sortKey: PUBLISHED_AT, reverse: true) {
|
|
123
|
+
pageInfo {
|
|
124
|
+
hasNextPage
|
|
125
|
+
endCursor
|
|
126
|
+
}
|
|
127
|
+
nodes {
|
|
128
|
+
id
|
|
129
|
+
title
|
|
130
|
+
handle
|
|
131
|
+
publishedAt
|
|
132
|
+
author {
|
|
133
|
+
name
|
|
134
|
+
}
|
|
135
|
+
blog {
|
|
136
|
+
title
|
|
137
|
+
}
|
|
138
|
+
tags
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
Variables: `{ "first": 10 }`
|
|
144
|
+
|
|
145
|
+
## Get Article
|
|
146
|
+
|
|
147
|
+
```graphql
|
|
148
|
+
query GetArticle($id: ID!) {
|
|
149
|
+
article(id: $id) {
|
|
150
|
+
id
|
|
151
|
+
title
|
|
152
|
+
handle
|
|
153
|
+
body
|
|
154
|
+
summary
|
|
155
|
+
publishedAt
|
|
156
|
+
author {
|
|
157
|
+
name
|
|
158
|
+
email
|
|
159
|
+
}
|
|
160
|
+
blog {
|
|
161
|
+
id
|
|
162
|
+
title
|
|
163
|
+
}
|
|
164
|
+
image {
|
|
165
|
+
url
|
|
166
|
+
altText
|
|
167
|
+
}
|
|
168
|
+
tags
|
|
169
|
+
templateSuffix
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
Variables: `{ "id": "gid://shopify/Article/123" }`
|
|
174
|
+
|
|
175
|
+
## Create Article
|
|
176
|
+
|
|
177
|
+
```graphql
|
|
178
|
+
mutation CreateArticle($article: ArticleCreateInput!, $blog: ArticleBlogInput) {
|
|
179
|
+
articleCreate(article: $article, blog: $blog) {
|
|
180
|
+
article {
|
|
181
|
+
id
|
|
182
|
+
title
|
|
183
|
+
handle
|
|
184
|
+
publishedAt
|
|
185
|
+
}
|
|
186
|
+
userErrors {
|
|
187
|
+
field
|
|
188
|
+
message
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
Variables:
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"article": {
|
|
197
|
+
"title": "Summer Collection Launch",
|
|
198
|
+
"handle": "summer-collection-launch",
|
|
199
|
+
"body": "<p>We're excited to announce our new summer collection...</p>",
|
|
200
|
+
"summary": "Introducing our latest summer styles",
|
|
201
|
+
"author": {
|
|
202
|
+
"name": "Marketing Team"
|
|
203
|
+
},
|
|
204
|
+
"tags": ["summer", "new-arrivals", "collection"],
|
|
205
|
+
"isPublished": true,
|
|
206
|
+
"publishedAt": "2025-06-01T09:00:00Z"
|
|
207
|
+
},
|
|
208
|
+
"blog": {
|
|
209
|
+
"id": "gid://shopify/Blog/123"
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Create Article with Image
|
|
215
|
+
|
|
216
|
+
```graphql
|
|
217
|
+
mutation CreateArticleWithImage($article: ArticleCreateInput!, $blog: ArticleBlogInput) {
|
|
218
|
+
articleCreate(article: $article, blog: $blog) {
|
|
219
|
+
article {
|
|
220
|
+
id
|
|
221
|
+
title
|
|
222
|
+
image {
|
|
223
|
+
url
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
userErrors {
|
|
227
|
+
field
|
|
228
|
+
message
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
Variables:
|
|
234
|
+
```json
|
|
235
|
+
{
|
|
236
|
+
"article": {
|
|
237
|
+
"title": "Product Spotlight",
|
|
238
|
+
"body": "<p>Check out our featured product...</p>",
|
|
239
|
+
"isPublished": true,
|
|
240
|
+
"image": {
|
|
241
|
+
"url": "https://example.com/images/featured.jpg",
|
|
242
|
+
"altText": "Featured product image"
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
"blog": {
|
|
246
|
+
"id": "gid://shopify/Blog/123"
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Update Article
|
|
252
|
+
|
|
253
|
+
```graphql
|
|
254
|
+
mutation UpdateArticle($id: ID!, $article: ArticleUpdateInput!) {
|
|
255
|
+
articleUpdate(id: $id, article: $article) {
|
|
256
|
+
article {
|
|
257
|
+
id
|
|
258
|
+
title
|
|
259
|
+
body
|
|
260
|
+
}
|
|
261
|
+
userErrors {
|
|
262
|
+
field
|
|
263
|
+
message
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
Variables:
|
|
269
|
+
```json
|
|
270
|
+
{
|
|
271
|
+
"id": "gid://shopify/Article/123",
|
|
272
|
+
"article": {
|
|
273
|
+
"body": "<p>Updated article content...</p>",
|
|
274
|
+
"tags": ["summer", "sale", "featured"]
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Move Article to Different Blog
|
|
280
|
+
|
|
281
|
+
```graphql
|
|
282
|
+
mutation MoveArticle($id: ID!, $article: ArticleUpdateInput!, $blog: ArticleBlogInput) {
|
|
283
|
+
articleUpdate(id: $id, article: $article, blog: $blog) {
|
|
284
|
+
article {
|
|
285
|
+
id
|
|
286
|
+
blog {
|
|
287
|
+
id
|
|
288
|
+
title
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
userErrors {
|
|
292
|
+
field
|
|
293
|
+
message
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
Variables:
|
|
299
|
+
```json
|
|
300
|
+
{
|
|
301
|
+
"id": "gid://shopify/Article/123",
|
|
302
|
+
"article": {},
|
|
303
|
+
"blog": {
|
|
304
|
+
"id": "gid://shopify/Blog/456"
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## Delete Article
|
|
310
|
+
|
|
311
|
+
```graphql
|
|
312
|
+
mutation DeleteArticle($id: ID!) {
|
|
313
|
+
articleDelete(id: $id) {
|
|
314
|
+
deletedArticleId
|
|
315
|
+
userErrors {
|
|
316
|
+
field
|
|
317
|
+
message
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## Get Article Tags
|
|
324
|
+
|
|
325
|
+
```graphql
|
|
326
|
+
query GetArticleTags($limit: Int!) {
|
|
327
|
+
articleTags(limit: $limit, sort: POPULAR) {
|
|
328
|
+
... on String {
|
|
329
|
+
__typename
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Get Article Authors
|
|
336
|
+
|
|
337
|
+
```graphql
|
|
338
|
+
query GetArticleAuthors($first: Int!) {
|
|
339
|
+
articleAuthors(first: $first) {
|
|
340
|
+
nodes {
|
|
341
|
+
name
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Search Articles by Tag
|
|
348
|
+
|
|
349
|
+
```graphql
|
|
350
|
+
query SearchArticlesByTag($tag: String!) {
|
|
351
|
+
articles(first: 10, query: $tag) {
|
|
352
|
+
nodes {
|
|
353
|
+
id
|
|
354
|
+
title
|
|
355
|
+
tags
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
Variables: `{ "tag": "tag:summer" }`
|
|
361
|
+
|
|
362
|
+
## Article Search Filters
|
|
363
|
+
|
|
364
|
+
| Filter | Example | Description |
|
|
365
|
+
|--------|---------|-------------|
|
|
366
|
+
| `title` | `title:summer` | Filter by title |
|
|
367
|
+
| `author` | `author:John` | Filter by author |
|
|
368
|
+
| `tag` | `tag:featured` | Filter by tag |
|
|
369
|
+
| `blog_title` | `blog_title:News` | Filter by blog |
|
|
370
|
+
| `created_at` | `created_at:>2024-01-01` | Filter by creation date |
|
|
371
|
+
| `published_at` | `published_at:>2024-01-01` | Filter by publish date |
|
|
372
|
+
|
|
373
|
+
## API Scopes Required
|
|
374
|
+
|
|
375
|
+
- `read_content` - Read blogs and articles
|
|
376
|
+
- `write_content` - Create, update, delete blogs and articles
|
|
377
|
+
|
|
378
|
+
## Notes
|
|
379
|
+
|
|
380
|
+
- Articles require a blog to belong to
|
|
381
|
+
- Tags are strings and case-insensitive
|
|
382
|
+
- Use `publishedAt` to schedule future publication
|
|
383
|
+
- Set `isPublished: false` to save as draft
|
|
384
|
+
- HTML in body is sanitized by Shopify
|
|
385
|
+
- Images should be uploaded first or provided via URL
|