From shopify-admin-skills
Audits Shopify customers' email and SMS marketing consent status (subscribed/unsubscribed/pending) via GraphQL for compliance audits, GDPR/CAN-SPAM reviews, and audience segmentation.
npx claudepluginhub 40rty-ai/shopify-admin-skills --plugin shopify-admin-skillsThis skill uses the workspace's default tool permissions.
Scans all customer records and reports the breakdown of email and SMS marketing consent status (subscribed, unsubscribed, pending, never asked). Used for compliance audits, GDPR/CAN-SPAM reviews, and understanding the addressable marketing audience. Read-only — no mutations.
Scans Shopify customer database for malformed emails, role accounts, disposable domains, and bounce-suspect patterns. Generates suppression list to protect email sender reputation.
Manages Shopify customers via GraphQL Admin API mutations/queries for create/update/delete/tags/metafields, Customer Account API, Multipass SSO, segmentation, B2B accounts.
Queries Wix Contacts API for contact lists, filters by email/activity/date, retrieves individuals; enables purchase history analysis, customer segmentation, RFM analysis via REST calls.
Share bugs, ideas, or general feedback.
Scans all customer records and reports the breakdown of email and SMS marketing consent status (subscribed, unsubscribed, pending, never asked). Used for compliance audits, GDPR/CAN-SPAM reviews, and understanding the addressable marketing audience. Read-only — no mutations.
shopify store auth --store <domain> --scopes read_customersread_customers| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| store | string | yes | — | Store domain (e.g., mystore.myshopify.com) |
| channel | string | no | both | Consent channel to audit: email, sms, or both |
| format | string | no | human | Output format: human or json |
ℹ️ Read-only skill — no mutations are executed. Safe to run at any time.
OPERATION: customers — query
Inputs: first: 250, select emailMarketingConsent { marketingState, consentUpdatedAt }, smsMarketingConsent { marketingState, consentUpdatedAt }, pagination cursor
Expected output: All customers with consent states; paginate until hasNextPage: false
Count customers by consent state for each channel
Calculate: addressable audience (subscribed), at-risk (pending), unreachable (unsubscribed/not asked)
# customers:query — validated against api_version 2025-01
query MarketingConsentAudit($after: String) {
customers(first: 250, after: $after) {
edges {
node {
id
displayName
defaultEmailAddress {
emailAddress
}
emailMarketingConsent {
marketingState
consentUpdatedAt
marketingOptInLevel
}
smsMarketingConsent {
marketingState
consentUpdatedAt
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
Claude MUST emit the following output at each stage. This is mandatory.
On start, emit:
╔══════════════════════════════════════════════╗
║ SKILL: Marketing Consent Report ║
║ Store: <store domain> ║
║ Started: <YYYY-MM-DD HH:MM UTC> ║
╚══════════════════════════════════════════════╝
After each step, emit:
[N/TOTAL] <QUERY|MUTATION> <OperationName>
→ Params: <brief summary of key inputs>
→ Result: <count or outcome>
On completion, emit:
For format: human (default):
══════════════════════════════════════════════
MARKETING CONSENT REPORT
Total customers: <n>
Email Marketing:
Subscribed: <n> (<pct>%) ← addressable
Unsubscribed: <n> (<pct>%)
Pending: <n> (<pct>%)
Not asked: <n> (<pct>%)
SMS Marketing:
Subscribed: <n> (<pct>%)
Unsubscribed: <n> (<pct>%)
Not asked: <n> (<pct>%)
Output: consent_audit_<date>.csv
══════════════════════════════════════════════
For format: json, emit:
{
"skill": "marketing-consent-report",
"store": "<domain>",
"total_customers": 0,
"email": { "subscribed": 0, "unsubscribed": 0, "pending": 0, "not_asked": 0 },
"sms": { "subscribed": 0, "unsubscribed": 0, "not_asked": 0 },
"output_file": "consent_audit_<date>.csv"
}
CSV file consent_audit_<YYYY-MM-DD>.csv with columns:
customer_id, email, email_marketing_state, email_consent_updated_at, sms_marketing_state, sms_consent_updated_at
| Error | Cause | Recovery |
|---|---|---|
THROTTLED | API rate limit exceeded | Wait 2 seconds, retry up to 3 times |
| No customers | Empty store | Exit with 0 results |
marketingOptInLevel: SINGLE_OPT_IN may require a re-consent campaign depending on your legal basis for processing.