alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
87 lines (79 loc) • 2.42 kB
text/typescript
import { $env, z } from "alepha";
import {
EmailError,
type EmailProvider,
type EmailSendOptions,
} from "alepha/email";
import { $logger } from "alepha/logger";
/**
* Environment variables for Brevo configuration.
*/
const envSchema = z.object({
BREVO_API_KEY: z.text({
description: "Brevo API key for transactional email",
}),
EMAIL_FROM: z.text({
description: "Default sender email address",
}),
});
/**
* Email provider using Brevo (formerly Sendinblue) transactional email API.
*
* Sends emails via `POST https://api.brevo.com/v3/smtp/email`.
*
* Configuration is provided via environment variables:
* - `BREVO_API_KEY`: Brevo API key
* - `EMAIL_FROM`: Default sender email address
*
* @example
* ```typescript
* // .env
* // BREVO_API_KEY=xkeysib-xxx
* // EMAIL_FROM=noreply@example.com
*
* // app.ts
* import { AlephaEmailBrevo } from "alepha/email/brevo";
*
* const app = Alepha.create().with(AlephaEmailBrevo);
* ```
*/
export class BrevoEmailProvider implements EmailProvider {
protected readonly env = $env(envSchema);
protected readonly log = $logger();
public async send(options: EmailSendOptions): Promise<void> {
const { to, subject, body } = options;
this.log.info("Sending email via Brevo", { to, subject });
const recipients = Array.isArray(to) ? to : [to];
try {
const response = await fetch("https://api.brevo.com/v3/smtp/email", {
method: "POST",
headers: {
"api-key": this.env.BREVO_API_KEY,
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({
sender: { email: this.env.EMAIL_FROM },
to: recipients.map((email) => ({ email })),
subject,
htmlContent: body,
}),
});
if (!response.ok) {
const text = await response.text();
throw new EmailError(`Brevo API returned ${response.status}: ${text}`);
}
this.log.info("Email sent successfully via Brevo", {
to,
subject,
});
} catch (error) {
if (error instanceof EmailError) {
throw error;
}
const message = `Failed to send email via Brevo: ${error instanceof Error ? error.message : String(error)}`;
this.log.error(message, { to, subject });
throw new EmailError(message, error instanceof Error ? error : undefined);
}
}
}