From medusa-commerce
Implements Medusa v2 event subscribers for pub/sub handling, handler functions, cron scheduled jobs, and Redis/in-memory event bus. Use when reacting to commerce events like product.created or order.placed.
npx claudepluginhub orcaqubits/agentic-commerce-skills-plugins --plugin medusa-commerceThis skill is limited to using the following tools:
**Fetch live docs**:
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Fetch live docs:
https://docs.medusajs.com/learn/fundamentals/events-and-subscribers for subscriber overviewsite:docs.medusajs.com subscriber handler function for handler APIsite:docs.medusajs.com scheduled jobs cron for scheduled job patternssite:docs.medusajs.com event module redis for event bus configurationsite:docs.medusajs.com built-in events list for available event namesSubscribers react to events emitted by Medusa workflows and services:
src/subscribers/config object{entity}.{action} (e.g., product.created)src/subscribers/
├── product-created.ts # Reacts to product.created
├── order-placed.ts # Reacts to order.placed
└── customer-registered.ts # Reacts to customer.created
Each file is auto-discovered -- no manual registration required.
// src/subscribers/product-created.ts
// Fetch live docs for SubscriberArgs and SubscriberConfig types
import type { SubscriberArgs, SubscriberConfig } from "@medusajs/framework"
export default async function productCreatedHandler(
{ event, container }: SubscriberArgs<{ id: string }>) {
// event.data.id contains the entity ID — fetch live docs for payload shapes
}
// Fetch live docs for SubscriberConfig options
export const config: SubscriberConfig = {
event: "product.created",
}
| Domain | Event Examples |
|---|---|
| Products | product.created, product.updated, product.deleted |
| Orders | order.placed, order.canceled, order.completed |
| Customers | customer.created, customer.updated |
| Cart | cart.created, cart.updated |
| Fulfillment | fulfillment.created, fulfillment.canceled |
| Payment | payment.captured, payment.refunded |
| Inventory | inventory-item.created |
| Auth | invite.created, invite.accepted |
Fetch live docs for the complete event list -- events are added and renamed across Medusa releases.
A single subscriber can listen to multiple events:
// Fetch live docs for multi-event config
export const config: SubscriberConfig = {
event: ["product.created", "product.updated"],
}
The handler receives the event name in event.name to distinguish which event triggered it.
| Property | Type | Description |
|---|---|---|
event.name | string | The event that triggered the subscriber |
event.data | object | Payload emitted by the workflow/service |
event.metadata | object | Internal metadata (event ID, timestamp) |
The data shape varies per event. Typically contains the entity ID(s) affected.
| Module | Transport | Use Case |
|---|---|---|
| In-memory (default) | Process memory | Development, single-instance |
| Redis Event Module | Redis Pub/Sub | Production, multi-instance |
// In medusa-config.ts modules array
// Fetch live docs for Redis event module configuration
{
resolve: "@medusajs/medusa/event-bus-redis",
options: { redisUrl: process.env.REDIS_URL },
}
In production, always use the Redis event module to ensure events are delivered across multiple server instances.
Scheduled jobs run on a cron schedule, independent of events:
src/jobs/
├── daily-sync.ts # Daily data synchronization
└── cleanup-expired.ts # Periodic cleanup
// src/jobs/daily-sync.ts
// Fetch live docs for MedusaContainer type
import type { MedusaContainer } from "@medusajs/framework"
export default async function dailySyncJob(container: MedusaContainer) {
const service = container.resolve("my-module")
// Fetch live docs for job handler API
}
// Fetch live docs for cron expression format
export const config = {
name: "daily-sync",
schedule: "0 0 * * *", // Midnight daily (cron syntax)
}
| Schedule | Cron Expression |
|---|---|
| Every minute | * * * * * |
| Every 15 minutes | */15 * * * * |
| Every hour | 0 * * * * |
| Daily at midnight | 0 0 * * * |
| Weekly on Monday | 0 0 * * 1 |
| Monthly on the 1st | 0 0 1 * * |
| Worker Mode | Subscribers | Scheduled Jobs |
|---|---|---|
shared | Processed in-process | Processed in-process |
server | Emitted only, not processed | Not processed |
worker | Processed | Processed |
In production, run a dedicated worker instance to handle subscribers and scheduled jobs separately from HTTP traffic.
Custom events can be emitted from workflows using the emitEventStep:
// Inside a workflow
// Fetch live docs for emitEventStep import
import { emitEventStep } from "@medusajs/medusa/core-flows"
emitEventStep({ eventName: "custom.event", data: { id: "123" } })
SubscriberArgs<{ id: string }>Fetch the Medusa subscriber and events documentation for exact event names, payload shapes, and Redis event module configuration before implementing.