email.module.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import { Module, OnModuleInit } from '@nestjs/common';
  2. import * as fs from 'fs-extra';
  3. import { ConfigModule } from '../config/config.module';
  4. import { ConfigService } from '../config/config.service';
  5. import { EmailTypeConfig } from '../config/email/email-options';
  6. import { EventBus } from '../event-bus/event-bus';
  7. import { EventBusModule } from '../event-bus/event-bus.module';
  8. import { VendureEvent } from '../event-bus/vendure-event';
  9. import { EmailContext } from './email-context';
  10. import { EmailSender } from './email-sender';
  11. import { TemplateLoader } from './template-loader';
  12. @Module({
  13. imports: [ConfigModule, EventBusModule],
  14. providers: [TemplateLoader, EmailSender],
  15. })
  16. export class EmailModule implements OnModuleInit {
  17. constructor(
  18. private configService: ConfigService,
  19. private eventBus: EventBus,
  20. private templateLoader: TemplateLoader,
  21. private emailSender: EmailSender,
  22. ) {}
  23. async onModuleInit() {
  24. await this.setupEventSubscribers();
  25. }
  26. async setupEventSubscribers() {
  27. const { emailTypes } = this.configService.emailOptions;
  28. for (const [type, config] of Object.entries(emailTypes)) {
  29. this.eventBus.subscribe(config.triggerEvent, event => {
  30. return this.handleEvent(type, config, event);
  31. });
  32. }
  33. if (this.configService.emailOptions.transport.type === 'file') {
  34. // ensure the configured directory exists before
  35. // we attempt to write files to it
  36. const emailPath = this.configService.emailOptions.transport.outputPath;
  37. await fs.ensureDir(emailPath);
  38. }
  39. }
  40. private async handleEvent(type: string, config: EmailTypeConfig<any>, event: VendureEvent) {
  41. const { generator, transport } = this.configService.emailOptions;
  42. const contextConfig = config.createContext(event);
  43. if (contextConfig) {
  44. const emailContext = new EmailContext({
  45. ...contextConfig,
  46. type,
  47. event,
  48. });
  49. const { subject, body, templateContext } = await this.templateLoader.loadTemplate(
  50. type,
  51. emailContext,
  52. );
  53. const generatedEmailContext = await generator.generate(
  54. subject,
  55. body,
  56. templateContext,
  57. emailContext,
  58. );
  59. await this.emailSender.send(generatedEmailContext, transport);
  60. }
  61. }
  62. }