Token导航 LogoToken导航TokenDH.com
研究检索需要联网github未标认证来源可访问许可证需确认审计通过

shopify-webhooksShopify webhooks 搜索

Agent Skill

shopify-webhooks 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

470

周安装

19

GitHub Stars

19

下载量

147
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:shopify-webhooks(Shopify webhooks 搜索)
来源仓库:https://github.com/finsilabs/awesome-ecommerce-skills
仓库路径:skills/shopify-webhooks
安装命令:
npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill shopify-webhooks
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill shopify-webhooks

简介

用于查找和筛选 Shopify Webhook 事件类型与 payload 结构的相关信息。

  • 适用于后端服务监听订单、库存或客户变更事件的标准实现参考。
  • 通过 npx 命令从社区仓库安装,支持主流 AI 代码宿主平台调用。
  • 使用前应确认 webhook URL 的安全性,避免暴露敏感端点。
  • shopify-webhooks 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

Shopify Webhooks

Overview

Shopify webhooks deliver real-time event notifications to your app's HTTP endpoints when store events occur — orders placed, products updated, customers created, apps uninstalled. Every webhook payload includes an HMAC-SHA256 signature in the X-Shopify-Hmac-SHA256 header that must be verified before processing. Shopify guarantees at-least-once delivery, so handlers must be idempotent.

When to Use This Skill

  • When triggering fulfillment workflows the moment an order is paid
  • When syncing product or inventory changes to an external system in near real time
  • When sending customer data to a marketing automation platform upon registration
  • When cleaning up app data after a merchant uninstalls the app (app/uninstalled)
  • When implementing required GDPR webhooks for App Store compliance
  • When replacing polling loops that constantly query the Admin API for changes

Core Instructions

  1. Register webhooks via the Admin API Prefer registering webhooks programmatically in the afterAuth hook of your Shopify app. This ensures re-registration after reinstall: ` // Webhook registration helper export async function registerWebhooks(adminClient: GraphqlClient, appUrl: string) {const webhooksToRegister = [{topic: "ORDERS_CREATE", callbackUrl: ${appUrl}/webhooks/orders-create}, {topic: "ORDERS_UPDATED", callbackUrl: ${appUrl}/webhooks/orders-updated}, {topic: "PRODUCTS_UPDATE", callbackUrl: ${appUrl}/webhooks/products-update}, {topic: "APP_UNINSTALLED", callbackUrl: ${appUrl}/webhooks/app-uninstalled}, // Mandatory GDPR webhooks {topic: "CUSTOMERS_DATA_REQUEST", callbackUrl: ${appUrl}/webhooks/gdpr/customers-data-request}, {topic: "CUSTOMERS_REDACT", callbackUrl: ${appUrl}/webhooks/gdpr/customers-redact}, {topic: "SHOP_REDACT", callbackUrl: ${appUrl}/webhooks/gdpr/shop-redact},]; for (const {topic, callbackUrl} of webhooksToRegister) {const response = await adminClient.request( mutation WebhookSubscriptionCreate($topic: WebhookSubscriptionTopic!, $webhookSubscription: WebhookSubscriptionInput!) {webhookSubscriptionCreate(topic: $topic, webhookSubscription: $webhookSubscription) {webhookSubscription {id topic} userErrors {field message}}} , {variables: {topic, webhookSubscription: {callbackUrl, format: "JSON",},},}); const {userErrors} = response.data.webhookSubscriptionCreate; if (userErrors.length > 0) {// ALREADY_EXISTS is expected on reinstall — not a real error const realErrors = userErrors.filter((e: any) => e.message!== "Address for this topic has already been taken"); if (realErrors.length > 0) throw new Error(Webhook registration failed: ${realErrors[0].message});}}} `
  2. Verify the HMAC signature The most critical step — never process a webhook without verifying its signature: // middleware/verify-shopify-webhook.ts import crypto from "crypto"; export function verifyShopifyWebhook(rawBody: Buffer, hmacHeader: string, secret: string): boolean {const digest = crypto.createHmac("sha256", secret).update(rawBody).digest("base64"); // Use timingSafeEqual to prevent timing attacks try {return crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(hmacHeader));} catch {return false;}} Express middleware example: // routes/webhooks.ts (Express) import express from "express"; import {verifyShopifyWebhook} from "../middleware/verify-shopify-webhook"; const router = express.Router(); // CRITICAL: Use raw body parser BEFORE json parser for webhook routes router.use("/webhooks", express.raw({type: "application/json"}), (req, res, next) => {const hmac = req.headers["x-shopify-hmac-sha256"] as string; if (!verifyShopifyWebhook(req.body, hmac, process.env.SHOPIFY_API_SECRET!)) {return res.status(401).send("Unauthorized");} req.body = JSON.parse(req.body.toString()); next();});
  3. Handle webhook events with idempotency Shopify may deliver the same event multiple times. Use the X-Shopify-Webhook-Id header as an idempotency key: router.post("/webhooks/orders-create", async (req, res) => {// Respond 200 quickly — Shopify retries if response takes > 5 seconds res.status(200).json({received: true}); const webhookId = req.headers["x-shopify-webhook-id"] as string; const shop = req.headers["x-shopify-shop-domain"] as string; const order = req.body; // Idempotency check — skip if already processed const alreadyProcessed = await db.processedWebhooks.findFirst({where: {webhookId, shop},}); if (alreadyProcessed) return; // Record processing attempt await db.processedWebhooks.create({data: {webhookId, shop, topic: "orders/create", processedAt: new Date()},}); // Process the order asynchronously await processNewOrder(order, shop);});
  4. Handle the mandatory GDPR webhooks Shopify requires these three endpoints for all App Store apps. They must respond 200 even if your app doesn't store personal data: router.post("/webhooks/gdpr/customers-data-request", async (req, res) => {const {shop_id, shop_domain, customer, orders_requested} = req.body; // Return customer data your app has stored for this customer await sendCustomerDataReport(shop_domain, customer.id); res.status(200).json({received: true});}); router.post("/webhooks/gdpr/customers-redact", async (req, res) => {const {shop_domain, customer} = req.body; // Delete all personal data for this customer await deleteCustomerData(shop_domain, customer.id); res.status(200).json({received: true});}); router.post("/webhooks/gdpr/shop-redact", async (req, res) => {const {shop_domain} = req.body; // Delete all store data 48 hours after APP_UNINSTALLED await deleteShopData(shop_domain); res.status(200).json({received: true});});
  5. Monitor delivery failures and set up retry awareness Shopify retries failed webhooks (non-2xx response or timeout) up to 19 times over 48 hours using exponential backoff. Check delivery health via Admin API: ` export async function getWebhookFailures(adminClient: GraphqlClient) {const response = await adminClient.request( query {webhookSubscriptions(first: 20) {edges {node {id topic callbackUrl endpoint {... on WebhookHttpEndpoint {callbackUrl}}}}}} ); return response.data.webhookSubscriptions.edges;} `

Examples

Full order creation handler with error handling and queue

import { Queue, Worker } from "bullmq";

const connection = { host: "localhost", port: 6379 };

const orderQueue = new Queue("order-processing", {
  connection,
  defaultJobOptions: {
    attempts: 3,
    backoff: { type: "exponential", delay: 5000 },
  },
});

router.post("/webhooks/orders-create", async (req, res) => {
  // Must respond within 5 seconds
  res.status(200).json({ received: true });

  const webhookId = req.headers["x-shopify-webhook-id"] as string;
  const shop = req.headers["x-shopify-shop-domain"] as string;

  // Push to queue for reliable async processing
  await orderQueue.add(
    "process-order",
    { order: req.body, shop, webhookId },
    {
      jobId: webhookId, // Prevents duplicate jobs for same webhook
    }
  );
});

const worker = new Worker("order-processing", async (job) => {
  const { order, shop, webhookId } = job.data;
  await syncOrderToERP(order, shop);
  await updateInventoryInWarehouse(order.line_items);
  await sendConfirmationNotification(order);
}, { connection });

List and delete stale webhook subscriptions

export async function cleanupWebhooks(adminClient: GraphqlClient, appUrl: string) {
  const response = await adminClient.request(`
    query {
      webhookSubscriptions(first: 100) {
        edges { node { id callbackUrl topic } }
      }
    }
  `);

  const stale = response.data.webhookSubscriptions.edges.filter(
    ({ node }: any) => !node.callbackUrl.startsWith(appUrl)
  );

  for (const { node } of stale) {
    await adminClient.request(`
      mutation DeleteWebhook($id: ID!) {
        webhookSubscriptionDelete(id: $id) {
          deletedWebhookSubscriptionId
          userErrors { field message }
        }
      }
    `, { variables: { id: node.id } });
  }
}

Best Practices

  • Respond 200 within 5 seconds — offload heavy processing to a background queue (Bull, BullMQ, SQS); Shopify marks slow responses as failures and starts retry cycle
  • Never trust without verifying HMAC — reject any request that fails signature validation with 401
  • Use raw body for HMAC computation — any body parsing before HMAC check corrupts the byte representation and causes false signature failures
  • Store X-Shopify-Webhook-Id for idempotency — keep a table of processed webhook IDs to prevent double-processing on retries
  • Re-register webhooks on every OAuth completion — merchants who reinstall the app get a new session; without re-registration, webhooks point to deleted subscriptions
  • Use EventBridge or Pub/Sub delivery for high volume — Shopify supports delivering webhooks to AWS EventBridge and Google Pub/Sub; these provide built-in retry and ordering guarantees

Common Pitfalls

ProblemSolution
HMAC verification always failsEnsure raw body (Buffer) is used — Express's JSON body parser converts Buffer to object; configure raw parser before the JSON parser on webhook routes
Webhook events processed twiceImplement idempotency using X-Shopify-Webhook-Id as a unique key; Bull jobId option prevents duplicate queue entries
APP_UNINSTALLED not receivedEnsure this topic is registered — without it, app cleanup (session deletion, data purge) won't fire and merchant data leaks
Shopify stops retrying after 48 hoursAdd monitoring to detect gaps in event processing; implement a reconciliation job that queries Admin API for events missed during downtime
GDPR webhooks fail Shopify reviewAll three GDPR endpoints must return 200 within the timeout — even if your app stores no data, acknowledge receipt and log the request
Webhook registrations duplicatedUse webhookSubscriptionUpdate instead of webhookSubscriptionCreate for existing topics, or check for ALREADY_EXISTS user errors and skip

Related Skills

  • @shopify-app-development
  • @shopify-admin-api
  • @webhook-architecture
  • @event-driven-architecture
  • @gdpr-compliance

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

36.69%
按下载量换算54

Claude

27.55%
按下载量换算40

Cursor

18.76%
按下载量换算28

Gemini CLI

8.92%
按下载量换算13

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills