toonvanstrijp / nestjs-i18n

The i18n module for nestjs.
https://nestjs-i18n.com
Other
624 stars 102 forks source link

Cant access translations in mailer over a BullJS processor #634

Open fr6nco opened 2 months ago

fr6nco commented 2 months ago

Describe the bug

I have a specific use case, where I want to send out emails based on requests from a BullJS @Processor().

Such component does not have an execution Context so resolvers are not executed. How can I force certain locale using the mailerService?

  @Process()
  async send(job: Job<Order>) {
    const jobContext = this.orderService.createOrderContext(job.data);
    this.mailerService.sendMail({
      to: jobContext.body.billing_address.email,
      from: 'shop@----',
      subject: 'Order Created',
      template: './order-create',
      context: jobContext,
    });
  }

This is a very quick snippet above, the selected locale is passed down in the job data as job.data.locale. Tried to use a custom resolver, but on a processor the middleware is not executed.

Here is my module config:


@Module({
  imports: [
    CommonModule,
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    I18nModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      resolvers: [new ProcessorDataResolver()],
      useFactory: (configService: ConfigService) => ({
        fallbackLanguage: 'sk',
        loaderOptions: {
          path:
            configService.get('MAILER_LOCALE_DIR') ??
            process.cwd() + '/src/locale',
          watch: true,
        },
      }),
    }),
    BullModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        redis: {
          host: configService.get('REDIS_HOST'),
          port: configService.get('REDIS_PORT'),
          password: configService.get('REDIS_PASSWORD') ?? undefined,
        },
      }),
    }),
    BullModule.registerQueue({
      name: 'mailer-order-create',
    }),
    MailerModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService, I18nService],
      useFactory: (configService: ConfigService, i18n: I18nService) => ({
        transport: {
          host: configService.get('MAILER_HOST'),
          port: +configService.get('MAILER_PORT'),
          secure: false,
          auth: {
            user: configService.get('MAILER_USER') ?? undefined,
            pass: configService.get('MAILER_PASS') ?? undefined,
          },
        },
        defaults: {
          from: configService.get('MAILER_FROM'),
        },
        preview: configService.get('MAILER_PREV') === 'true',
        template: {
          dir:
            configService.get('MAILER_TEMPLATES_DIR') ??
            process.cwd() + '/src/templates',
          adapter: new HandlebarsAdapter({ t: i18n.hbsHelper }),
          options: {
            strict: true,
          },
        },
        options: {
          partials: {
            dir:
              configService.get('MAILER_PARTIALS_DIR') ??
              process.cwd() + '/src/templates/partials',
          },
        },
      }),
    }),
    CommonModule,
  ],
  controllers: [AppController],
  providers: [OrderCreateConsumer, OrderService],
  exports: [],
})
export class AppModule {}

Any idea how can I force a language dynamically without resolvers?

Reproduction

in comment

System Info

Tomass-MacBook-Pro:paintit-mailer thomas$ npx envinfo --system --binaries --browsers
Need to install the following packages:
envinfo@7.13.0
Ok to proceed? (y) 

  System:
    OS: macOS 14.0
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 22.89 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 20.10.0 - ~/.nvm/versions/node/v20.10.0/bin/node
    npm: 10.2.3 - ~/.nvm/versions/node/v20.10.0/bin/npm
  Browsers:
    Chrome: 124.0.6367.119
    Safari: 17.0

Used Package Manager

npm

Validations