medusajs / medusa

The world's most flexible commerce platform.
https://medusajs.com
MIT License
25.8k stars 2.58k forks source link

Events in Redis event bus not triggering subscribers (notification service) #7850

Closed akomis closed 4 months ago

akomis commented 4 months ago

Bug report

Describe the bug

Events in Redis do not trigger subscribers - I do not see any logging coming out of them (using Logger as described in the documentation) nor any expected behaviour implemented in the handlers like sending emails.

System information

Medusa version (including plugins): 1.20.2 "@medusajs/cache-redis": "1.9.1", "@medusajs/event-bus-redis": "1.8.13", Node.js version: v20.13.1 Database: PostgreSQL Operating system: Linux Browser (if relevant):

Steps to reproduce the behavior

  1. Setup redis event bus with Medusa
  2. Create NotificationProvider and loader to subscribe the notifications to the events as noted in the code snippets
  3. create an order or shipment or refund

Expected behavior

I expect the loader to have subscribed to the events and when triggering any event run the sendNotification() function of the notification service

Screenshots

RedisInsight showing that events are indeed being registered in redis so redis configuration and integration with medusa seems to be fine image

Code snippets

src/loaders/notification.ts

import { Logger, MedusaContainer, NotificationService } from "@medusajs/medusa";

export default async (container: MedusaContainer): Promise<void> => {
  const logger = container.resolve<Logger>("logger");

  logger.info("Starting loader...");
  const notificationService = container.resolve<NotificationService>(
    "notificationService"
  );

  notificationService.subscribe("order.placed", "email-sender");
  notificationService.subscribe("order.completed", "email-sender");
  notificationService.subscribe("order.payment_captured", "email-sender");
  notificationService.subscribe("order.shipment_created", "email-sender");
  notificationService.subscribe("order.refund_created", "email-sender");
};

src/services/email-sender.ts

import {
  AbstractNotificationService,
  CartService,
  Logger,
  OrderService,
} from "@medusajs/medusa";
import { Resend } from "resend";

export default class EmailSenderService extends AbstractNotificationService {
  static identifier = "email-sender";
  protected orderService_: OrderService;
  protected cartService_: CartService;
  protected emailClient_: Resend;
  protected logger_: Logger;

  constructor(container, options) {
    super(container);
    this.orderService_ = container.orderService;
    this.cartService_ = container.cartService;
    this.emailClient_ = new Resend(process.env.RESEND_API_KEY);
    this.logger_ = container.logger;
  }

  /**
   *
   * @param event = event which called the notification service
   * @param data = data of event - look into event reference: https://docs.medusajs.com/development/events/events-list#order-events
   * @param attachmentGenerator = default = null
   */
  async sendNotification(
    event: string,
    data: any,
    attachmentGenerator: unknown
  ): Promise<{
    to: string;
    status: string;
    data: Record<string, unknown>;
  }> {
    this.logger_.info("Trying to send email...");
    const order = await this.orderService_.retrieve(data.id, {
      relations: ["items", "customer", "shipping_address"],
    });

    await this.emailClient_.emails.send({
      from: process.env.FROM_EMAIL,
      to: order.email,
      subject: "TEST EMAIL",
      html: "test email!",
    });

    return Promise.resolve({
      to: order.email,
      status: "done",
      data: {
        subject: "You placed a new order!",
        items: order.items,
      },
    });
  }

  resendNotification(
    notification: any,
    config: any,
    attachmentGenerator: unknown
  ): Promise<{
    to: string;
    status: string;
    data: Record<string, unknown>;
  }> {
    const to: string = config.to || notification.to;

    return Promise.resolve({
      to,
      status: "done",
      data: notification.data,
    });
  }
}

Additional context

The provider exists in the database but the notification table is empty.

Things I have tried while troubleshooting and didn't help/work:

akomis commented 4 months ago

updating @medusajs/medusa to 1.20.7 seems to solve the issue.