MedusaJS中'order.placed'事件无法触发通知发送问题
MedusaJS配置Notification Provider后
order.placed事件无法触发通知发送 系统信息
Medusa版本(含插件): "@medusajs/admin": "^6.0.5", "@medusajs/cache-inmemory": "^1.8.7", "@medusajs/cache-redis": "^1.8.7", "@medusajs/event-bus-local": "^1.9.6", "@medusajs/event-bus-redis": "^1.8.7", "@medusajs/file-local": "^1.0.1", "@medusajs/medusa": "^1.14.0", "body-parser": "^1.19.0", "cors": "^2.8.5", "dotenv": "^16.1.4", "express": "^4.17.2", "medusa-fulfillment-manual": "^1.1.37", "medusa-interfaces": "^1.3.7", "medusa-payment-manual": "^1.0.23", "medusa-payment-stripe": "^6.0.3", "typeorm": "^0.3.16" Node.js版本:14.21.3 数据库:Postgres 操作系统:Windows 10
复现步骤
- 按官方文档创建Notification Provider,文件路径
services/custom-email-sender.ts:
import { AbstractNotificationService, Logger, OrderService, } from "@medusajs/medusa"; class CustomEmailSenderService extends AbstractNotificationService { static identifier = "custom-email-sender"; static is_installed = true; protected orderService_: OrderService; protected logger_: Logger; constructor(container, _options) { super(container); this.logger_ = container.logger; this.logger_.info("EMAIL SENDER v1"); this.orderService_ = container.orderService; } async sendNotification( event: string, data: unknown, attachmentGenerator: unknown ): Promise<{ to: string; status: string; data: Record<string, unknown>; }> { this.logger_.info("sendNotification"); if (event === "order.placed") { // retrieve order const order = await this.orderService_.retrieve(data.id); // TODO send email this.logger_.info("Notification sent"); return { to: order.email, status: "done", data: { // any data necessary to send the email // for example: subject: "You placed a new order!", items: order.items, }, }; } } resendNotification( notification: unknown, config: unknown, attachmentGenerator: unknown ): Promise<{ to: string; status: string; data: Record<string, unknown>; }> { throw new Error("Method not implemented."); } } export default CustomEmailSenderService;
- 创建通知订阅者,文件路径
subscribers/notification.js:
class NotificationSubscriber { constructor({ notificationService }) { notificationService.subscribe( "order.placed", "custom-email-sender" ) } } export default NotificationSubscriber;
- 构建并运行Medusa开发环境:
npm run build npx medusa develop
- 确认Provider已存在于数据库且已安装
- 创建订单后查看日志,
sendNotification从未被调用,数据库中无通知记录;尝试其他事件,通知提供者也无法订阅任何事件。
排查与解决方案
1. 统一文件扩展名与导出规范
项目使用TypeScript,订阅者文件建议改为.ts格式,确保编译流程能正确识别加载:
// subscribers/notification.ts class NotificationSubscriber { constructor({ notificationService, logger }) { logger.info("订阅order.placed事件"); notificationService.subscribe("order.placed", "custom-email-sender"); } } export default NotificationSubscriber;
2. 修复sendNotification的返回逻辑
当前代码仅处理order.placed事件,其他场景无返回值会导致Promise异常,需补充默认返回:
async sendNotification( event: string, data: unknown, attachmentGenerator: unknown ): Promise<{ to: string; status: string; data: Record<string, unknown>; }> { this.logger_.info(`收到事件: ${event}`); if (event === "order.placed") { const order = await this.orderService_.retrieve((data as any).id); this.logger_.info("Notification sent"); return { to: order.email, status: "done", data: { subject: "You placed a new order!", items: order.items, }, }; } // 非目标事件返回跳过状态 return { to: "", status: "skipped", data: {} }; }
3. 验证事件总线配置
确保medusa-config.js中事件总线配置正确,以本地事件总线为例:
module.exports = { // 其他配置 modules: { eventBus: { resolve: "@medusajs/event-bus-local", }, }, };
若使用Redis事件总线,需确认Redis服务正常运行且连接参数无误。
4. 确认Provider与订阅者的加载状态
- 启动服务时检查日志是否输出
EMAIL SENDER v1,确认Provider已被初始化 - 查看订阅者日志是否输出
订阅order.placed事件,确认订阅逻辑已执行
5. 验证订单事件是否正常发布
可通过监听事件总线的所有事件,确认order.placed是否被正确触发:
// 新增订阅者文件 subscribers/event-debug.ts class EventDebugSubscriber { constructor({ eventBusService, logger }) { eventBusService.subscribe("*", (eventName, data) => { logger.info(`事件总线收到: ${eventName}`, data); }); } } export default EventDebugSubscriber;
启动服务后创建订单,查看日志是否有order.placed的记录。
内容的提问来源于stack exchange,提问作者Jakub
相关产品推荐
相关产品推荐

