You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

复现步骤

  1. 按官方文档创建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;
  1. 创建通知订阅者,文件路径subscribers/notification.js:
class NotificationSubscriber {
  constructor({ notificationService  }) {
    notificationService.subscribe(
        "order.placed",
        "custom-email-sender"
    )
  }
}

export default NotificationSubscriber;
  1. 构建并运行Medusa开发环境:
npm run build
npx medusa develop
  1. 确认Provider已存在于数据库且已安装
  2. 创建订单后查看日志,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 20:42:17