Examples
Purchase thanks
Official Kody doc
The homepage Trigger it card labeled Event is this example. A purchase is a moment your factory can already know about. The package that reacts does not need a model in the loop and does not need you to paste the receipt into chat.
Live public package:
@kentcdodds/stripe-purchase-thanks.
After a verified successful Stripe checkout it indexes Kent's business Gmail for
the buyer, creates a thank-you draft on a relevant thread (To is the buyer,
never Kent), and posts a one-liner that the draft is ready. Draft only. Never
send.
The homepage calls this an event because the interesting fact is the
purchase, not the HTTP door. Kent's listing uses a Stripe webhook as the way
that fact arrives, then treats the verified checkout as the event that starts
the thank-you. You can also emit @you/purchase.completed from one package and
subscribe from another.
Subscriptions and package-emitted topics: Subscriptions and events. Vendor POST ingress: Inbound webhooks. Drafts the agent must not send: Gmail drafts without send.
Two honest shapes
One package, vendor ingress. Stripe POSTs checkout.session.completed. The
handler fetch-back verifies the event id (the body is untrusted; only id is
used), keeps successful paid checkouts, and calls thankPurchase. That is
Kent's listing.
import handleStripeWebhook from 'kody:@you/stripe-purchase-thanks/handle-stripe-webhook'
export default async function main() {
return await handleStripeWebhook({
request: { json: { id: 'evt_1ABC', type: 'checkout.session.completed' } },
})
}Two packages, an owned topic. The Stripe (or commerce) package verifies the payment, then emits. The thanks package subscribes. Other packages can listen without sharing the webhook secret.
import { events } from 'kody:runtime'
await events.dispatch({
topic: '@you/purchase.completed',
idempotencyKey: `stripe:checkout:${eventId}`,
payload: {
eventId,
product: 'Kody Standard',
customerEmail: 'ada@example.com',
},
}){
"name": "@you/purchase-thanks",
"kody": {
"subscriptions": {
"@you/purchase.completed": {
"handler": "./src/on-purchase-completed.ts",
"description": "Draft a thank-you after a verified purchase."
}
}
}
}events.dispatch is unavailable in ad hoc execute. Emit from package code (or
a static import of an export that dispatches). Payloads are JSON objects capped
at 64 KiB. Store Gmail threads and draft ids in packageStorage() and emit a
reference when the thank-you record is large.
Package shape
Kent's thank-you export is the part you replay from chat after a payment is already verified:
import { thankPurchase } from 'kody:@you/stripe-purchase-thanks/thank-purchase'
export default async function main() {
return await thankPurchase({
eventId: 'evt_1ABC',
amount: 1200,
currency: 'usd',
product: 'Kody Standard',
customerName: 'Ada',
customerEmail: 'ada@example.com',
livemode: true,
})
}Rules that keep this safe:
- Fetch-back verify. Do not trust the webhook JSON beyond the event id.
- Draft. Do not send. If the Google token can send, lock the published package and the integration so execute cannot widen it. See Gmail drafts without send.
- Money alerts stay out of this package. Kent keeps those in
@kentcdodds/stripe-alerts. - Never log customer email, checkout session ids, or receipt URLs in public channels.
- After publish, smoke-test the webhook export with a dry-run payload, or replay
thankPurchaseon facts you already verified. For the owned-topic shape, usepackageSubscriptionDispatch.
Example prompts
Build the event shape
Search Kody for purchase thanks and package-emitted events. I want
@me/purchase.completedemitted after a verified paid checkout, and a second package that drafts a thank-you (never send) when that event lands. Show me thekody.emitsandkody.subscriptionssnippets, then persist both packages. Smoke-test the subscriber with packageSubscriptionDispatch.
Fork the public one
Open https://kody.codes/@kentcdodds/stripe-purchase-thanks, fork it, and point the Stripe webhook at my checkout. Keep drafts-only. Do not send. Do not disable Kent's live
stripewebhook.
Replay one purchase
Import
thankPurchasefrom my fork and replay eventevt_…that I already verified. Show me which Gmail thread it picked and the draft id. Do not send the draft.
What you see
| Surface | What it is for |
|---|---|
| Stripe dashboard → webhooks | The minted Kody URL (copied from package settings, never from chat) |
| Package settings → Webhooks | Mint / reveal / rotate for the stripe door |
| Gmail Drafts | The thank-you, To = buyer, waiting on a human to send |
| Discord (Kent's copy) | One-liner that the draft is ready |
/account/activity | Webhook deliveries and subscription runs |
Chat (execute) | Replay thankPurchase or dry-run the webhook handler |
The homepage card is a tile with the kicker Event and the title Purchase thanks. It links here.
Where to go next
- Subscriptions and events —
kody.emits,events.dispatch, filters, synthetic dispatch. - Inbound webhooks — Stripe signature windows and mint / rotate.
- Gmail drafts without send — lock the package so a later agent cannot send.
- Flake Hunter — the cron sibling on the same homepage row.