Open-Source Cold Email & Warmup Platform
Warmbly는 메일함을 예열하고 캠페인 전송·답변 triage를 지원하는 오픈소스 콜드 이메일 플랫폼입니다
무료 Shopify 스토어 감사: SEO·속도·전환·AI 가시성을 점수화하고 주요 문제와 PDF 보고서를 제공합니다
Free Shopify store audit: score your store's SEO, speed, conversion (CRO) and AI visibility, with the top issues to fix and a free PDF report.
마케팅JavaScriptGitHub @EcomswiftLLC온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Verify, log, and replay Shopify webhooks locally: HMAC-SHA256 verification, X-Shopify-Webhook-Id dedupe, a zero-dependency dev server, and a replay CLI.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Verify, log, and replay Shopify webhooks locally — a zero-dependency dev server plus a small CLI, so you can build and test a webhook handler without a live store, a tunnel, or waiting for Shopify to fire the event again.
We built this because every Shopify app we've shipped needed the same three things on day one: verify the X-Shopify-Hmac-Sha256 signature correctly (the raw-body gotcha below has bitten us more than once), dedupe retried deliveries, and replay a captured payload while iterating on a handler. This is that, extracted and made reusable.README 전문 보기 ↗Verify, log, and replay Shopify webhooks locally — a zero-dependency dev server plus a small CLI, so you can build and test a webhook handler without a live store, a tunnel, or waiting for Shopify to fire the event again.
We built this because every Shopify app we've shipped needed the same three things on day one: verify the X-Shopify-Hmac-Sha256 signature correctly (the raw-body gotcha below has bitten us more than once), dedupe retried deliveries, and replay a captured payload while iterating on a handler. This is that, extracted and made reusable.
Free audit for your own store while you're here: audit.ecomswiftllc.com checks SEO, speed, CRO and AI-visibility in one pass.
const { createWebhookServer } = require('shopify-webhook-toolkit');
const server = createWebhookServer({
secret: process.env.SHOPIFY_WEBHOOK_SECRET,
logDir: './webhook-captures',
onWebhook(ctx) {
// ctx.verified, ctx.topic, ctx.shop, ctx.webhookId, ctx.body (parsed JSON)
console.log(`${ctx.topic} from ${ctx.shop}`, ctx.body);
},
});
server.listen(3000);
$ npx swt listen --secret shpss_xxx --log ./webhook-captures
shopify-webhook-toolkit listening on http://localhost:3000/webhooks
[swt] received topic=orders/create shop=example-shop.myshopify.com id=<webhook-id> verified=true
[swt] handled topic=orders/create shop=example-shop.myshopify.com id=<webhook-id> verified=true
Every request is answered fast (before your handler even runs) and logged to disk, so you can replay it later:
$ npx swt replay ./webhook-captures/captures/orders_create__<webhook-id>.json \
--url http://localhost:3000/webhooks --secret shpss_xxx
swt replay: 200 OK
verifyHmac(rawBody, hmacHeader, secret) — HMAC-SHA256 verification against the raw request body, using crypto.timingSafeEqual for the comparison (the pattern Shopify's own docs use), not a naive ===.createWebhookServer(options) — a dependency-free HTTP server for local development: verifies signatures, responds within milliseconds (Shopify times out and retries slow endpoints), then runs your handler.X-Shopify-Webhook-Id via IdempotencyStore, exported separately for reuse in your real server.swt replay — resend a captured or hand-written payload to any URL, with the signature recomputed for the target secret, so you can drive a handler with real-shaped data on demand.swt sign — print the HMAC signature for a payload file, plus a ready-to-run curl command, for manual testing.node:http, node:crypto, fetch). No framework required, though examples/express-middleware.js shows the Express integration if you use one.npm install shopify-webhook-toolkit
# or use the CLI without installing:
npx shopify-webhook-toolkit --help
Requires Node.js 18 or later (for the built-in fetch used by replay).
const { createWebhookServer, IdempotencyStore, verifyHmac } = require('shopify-webhook-toolkit');
verifyHmac(rawBody, hmacHeader, secret) → boolean. Use this inside your own framework's route if you're not using createWebhookServer directly — see examples/express-middleware.js.createWebhookServer({ secret, onWebhook, onInvalidSignature, path, logDir, dedupe, maxBodyBytes }) → an http.Server. See examples/basic-server.js for a full annotated example, including routing by topic.new IdempotencyStore({ ttlMs, maxEntries }) with .seen(id) → boolean, for dedupe logic you want to run yourself.replay({ file, url, secret, resign, webhookId }) — the function behind swt replay, if you want to drive it from a test script instead of the CLI.swt listen --secret $SHOPIFY_WEBHOOK_SECRET --log ./webhook-captures
swt replay ./webhook-captures/captures/orders_create__<id>.json --url http://localhost:3000/webhooks --secret $SHOPIFY_WEBHOOK_SECRET
swt sign examples/captured-webhooks/orders-create.sample.json --secret $SHOPIFY_WEBHOOK_SECRET
Run swt --help for the full flag list. There's also a ready-made sample payload at examples/captured-webhooks/orders-create.sample.json if you want to try listen + replay without a real store at all:
npx swt listen --secret devsecret &
npx swt replay examples/captured-webhooks/orders-create.sample.json --url http://localhost:3000/webhooks --secret devsecret
Verification must run against the exact bytes Shopify sent — not a JSON.parse'd-and-JSON.stringify'd copy. Re-serializing can reorder keys or reformat numbers, producing different bytes and a signature mismatch even for a genuinely valid webhook. If you're on Express, that means using express.raw({ type: 'application/json' }) on the webhook route specifically, not express.json(). examples/express-middleware.js shows the working pattern; test/verifyHmac.test.js has a test that reproduces the failure if you get this wrong.
createWebhookServer is a development/testing tool — verifyHmac and IdempotencyStore are exported separately so you can use the verification and dedupe logic inside your real framework/queue, but this package doesn't handle TLS, horizontal scaling, durable queues, or graceful shutdown for you.IdempotencyStore is in-memory and resets on restart. For production, back dedupe with something durable (Redis, a unique constraint in your database).shopify.app.toml) mutation, not something this package does.shopify app dev's built-in one, ngrok, etc) — swt replay exists specifically so you don't have to set one up just to iterate on a handler.Why not just use express.json() and compare the header myself?
You can — verifyHmac is exported standalone for exactly that. The gotcha above (raw body vs. re-serialized) is the part people get wrong, so it's worth using a tested function for it either way.
Does this handle Shopify's retry/backoff behavior?
It's aware of it: Shopify expects a response within a few seconds and retries on timeout, so createWebhookServer always answers before running your handler, and dedupes retries by X-Shopify-Webhook-Id so a retry doesn't run your handler twice. The exact timeout/retry-count numbers are Shopify's to change — check shopify.dev's webhook docs for the current values rather than hardcoding them into your app.
Can I use this with GraphQL Admin API webhook subscriptions, not just the legacy REST ones? Yes — the headers and HMAC scheme are the same regardless of how the subscription was created.
If webhooks are just one piece of a bigger app or store project, our free Shopify tools and store audit cover the rest of what we build day to day.
shopify-store-audit-toolkit — CLI that audits a live store's SEO, structured data, and performance signals.shopify-audit-mcp — connect Claude/Cursor/other MCP clients to the same audit as a callable tool.shopify-seo-checklist — interactive, open-source SEO checklist.shopify-cro-playbook — 75 conversion-rate checks across 14 categories.shopify-functions-examples — annotated Shopify Functions in Rust and JavaScript, the other half of "customize backend behavior" alongside webhooks.Issues and PRs welcome — especially real-world webhook payload shapes for the examples/captured-webhooks/ folder, or reports of anything in Shopify's webhook headers/behavior that's changed since this was written.
IdempotencyStore implementation.swt listen --forward <url> to fan a captured webhook out to multiple local handlers at once.MIT — see LICENSE.
This project is maintained by Ecom Swift LLC, a Shopify Partner.
Building or debugging a Shopify app and want a second pair of eyes on more than just webhooks? Get a free store audit (SEO, speed, CRO, AI visibility) or browse our other free Shopify tools. We're Ecom Swift LLC, a Shopify Partner Agency — www.ecomswiftllc.com.