Skip to content

Commit

Permalink
Add transactional mail service (#67)
Browse files Browse the repository at this point in the history
* add brevo transactional mail service - also add controller route in demo to show an example usage

* Add changelog

* Fix wrong naming due to copy paste error

* remove unnecessary line in changeset

* Simplify code
  • Loading branch information
raphaelblum authored Aug 8, 2024
1 parent 3fac174 commit 3f3fdeb
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 3 deletions.
15 changes: 15 additions & 0 deletions .changeset/sour-yaks-jog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
"@comet/brevo-api": minor
---

Add and export `BrevoTransactionalMailsService` that can be used in the application for sending transactional mails.

**Example Usage of `BrevoTransactionalMailsService`**

```typescript
constructor(private readonly brevoTransactionalMailsService: BrevoTransactionalMailsService) {}

async send(email: string, htmlContent: string, subject: string): Promise<void> {
await this.brevoTransactionalMailsService.send({ to: [{ email }], htmlContent, subject }, data.scope);
}
```
2 changes: 2 additions & 0 deletions demo/api/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { AuthModule } from "./auth/auth.module";
import { AuthLocalModule } from "./auth/auth-local.module";
import { BrevoContactSubscribeModule } from "./brevo-contact/brevo-contact-subscribe.module";
import { BrevoContactAttributes, BrevoContactFilterAttributes } from "./brevo-contact/dto/brevo-contact-attributes";
import { BrevoTransactionalMailsController } from "./brevo-transactional-mails/brevo-transactional-mails.controller";
import { Config } from "./config/config";
import { ConfigModule } from "./config/config.module";
import { DamFile } from "./dam/entities/dam-file.entity";
Expand Down Expand Up @@ -175,6 +176,7 @@ export class AppModule {
},
}),
BrevoContactSubscribeModule,
BrevoTransactionalMailsController,
],
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { BrevoTransactionalMailsService } from "@comet/brevo-api";
import { DisableGlobalGuard } from "@comet/cms-api";
import { Body, Controller, Post } from "@nestjs/common";

import { BrevoTransactionalMailsBody } from "./dto/transactional-mails.body";

@Controller("transactional-mails")
export class BrevoTransactionalMailsController {
constructor(private readonly brevoTransactionalMailsService: BrevoTransactionalMailsService) {}

@DisableGlobalGuard()
@Post(`/send`)
async send(@Body() { text, subject, to, scope }: BrevoTransactionalMailsBody): Promise<void> {
await this.brevoTransactionalMailsService.send({ to: [{ email: to }], textContent: text, subject }, scope);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Module } from "@nestjs/common";

import { BrevoTransactionalMailsController } from "./brevo-transactional-mails.controller";

@Module({
controllers: [BrevoTransactionalMailsController],
})
export class BrevoTransactionalMailsModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { EmailContactSubscribeScope } from "@src/brevo-contact/dto/brevo-contact-subscribe.scope";
import { Type } from "class-transformer";
import { IsEmail, IsNotEmpty, IsString, ValidateNested } from "class-validator";

export class BrevoTransactionalMailsBody {
@IsString()
subject: string;

@IsString()
text: string;

@IsEmail()
to: string;

@ValidateNested()
@Type(() => EmailContactSubscribeScope)
@IsNotEmpty()
scope: EmailContactSubscribeScope;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as Brevo from "@getbrevo/brevo";
import { Inject, Injectable } from "@nestjs/common";
import { EmailCampaignScopeInterface } from "src/types";

import { BrevoModuleConfig } from "../config/brevo-module.config";
import { BREVO_MODULE_CONFIG } from "../config/brevo-module.constants";

type SendTransacEmailResponse = ReturnType<Brevo.TransactionalEmailsApi["sendTransacEmail"]>;

@Injectable()
export class BrevoTransactionalMailsService {
private readonly transactionalEmailsApi = new Map<string, Brevo.TransactionalEmailsApi>();

constructor(@Inject(BREVO_MODULE_CONFIG) private readonly config: BrevoModuleConfig) {}

private getTransactionalEmailsApi(scope: EmailCampaignScopeInterface): Brevo.TransactionalEmailsApi {
const existingTransactionalEmailsApiForScope = this.transactionalEmailsApi.get(JSON.stringify(scope));

if (existingTransactionalEmailsApiForScope) {
return existingTransactionalEmailsApiForScope;
}

const { apiKey } = this.config.brevo.resolveConfig(scope);
const transactionalEmailApi = new Brevo.TransactionalEmailsApi();
transactionalEmailApi.setApiKey(Brevo.TransactionalEmailsApiApiKeys.apiKey, apiKey);

this.transactionalEmailsApi.set(JSON.stringify(scope), transactionalEmailApi);

return transactionalEmailApi;
}

async send(options: Omit<Brevo.SendSmtpEmail, "sender">, scope: EmailCampaignScopeInterface): SendTransacEmailResponse {
const config = this.config.brevo.resolveConfig(scope);
return this.getTransactionalEmailsApi(scope).sendTransacEmail({ ...options, sender: config.sender });
}
}
5 changes: 3 additions & 2 deletions packages/api/src/brevo-api/brevo-api.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { Module } from "@nestjs/common";
import { ConfigModule } from "../config/config.module";
import { BrevoApiCampaignsService } from "./brevo-api-campaigns.service";
import { BrevoApiContactsService } from "./brevo-api-contact.service";
import { BrevoTransactionalMailsService } from "./brevo-api-transactional-mails.service";

@Module({
imports: [ConfigModule, CacheModule.register({ ttl: 1000 * 60 })],
providers: [BrevoApiContactsService, BrevoApiCampaignsService],
exports: [BrevoApiContactsService, BrevoApiCampaignsService],
providers: [BrevoApiContactsService, BrevoApiCampaignsService, BrevoTransactionalMailsService],
exports: [BrevoApiContactsService, BrevoApiCampaignsService, BrevoTransactionalMailsService],
})
export class BrevoApiModule {}
2 changes: 1 addition & 1 deletion packages/api/src/brevo-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class BrevoModule {
}),
ConfigModule.forRoot(config),
],
exports: [TargetGroupModule, BrevoContactModule],
exports: [TargetGroupModule, BrevoContactModule, BrevoApiModule],
};
}
}
1 change: 1 addition & 0 deletions packages/api/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { BrevoTransactionalMailsService } from "./brevo-api/brevo-api-transactional-mails.service";
export { BrevoContactsService } from "./brevo-contact/brevo-contacts.service";
export { SubscribeResponse } from "./brevo-contact/dto/subscribe-response.enum";
export { IsValidRedirectURL } from "./brevo-contact/validator/redirect-url.validator";
Expand Down

0 comments on commit 3f3fdeb

Please sign in to comment.