@api-buddy/sendgrid
Version:
API Buddy integration for SendGrid - Email delivery service for transactional and marketing emails
144 lines (130 loc) • 4.62 kB
text/typescript
import sgMail, { ClientResponse } from '@sendgrid/mail';
import { SendGridConfig, EmailOptions, BatchSendGridResponse } from './types';
export class SendGridClient {
private config: SendGridConfig;
private initialized = false;
constructor(config: SendGridConfig) {
this.config = config;
this.initialize();
}
/**
* Initialize the SendGrid client with the API key
*/
private initialize(): void {
if (!this.initialized) {
if (!this.config.apiKey && !process.env.SENDGRID_API_KEY) {
throw new Error(
'SendGrid API key is required. Either provide it in the config or set the SENDGRID_API_KEY environment variable.'
);
}
sgMail.setApiKey(this.config.apiKey || process.env.SENDGRID_API_KEY!);
this.initialized = true;
}
}
/**
* Send an email using SendGrid
* @param options Email options
* @returns Promise with the SendGrid response
*/
public async sendEmail(options: EmailOptions) {
if (!this.initialized) {
this.initialize();
}
try {
const msg = {
to: options.to,
from: options.from || this.config.defaultFrom || 'no-reply@example.com',
subject: options.subject,
text: options.text,
html: options.html,
templateId: options.templateId,
dynamicTemplateData: options.dynamicTemplateData,
attachments: options.attachments,
categories: options.categories,
customArgs: options.customArgs,
headers: options.headers,
mailSettings: options.mailSettings || this.config.mailSettings,
trackingSettings: options.trackingSettings || this.config.trackingSettings,
replyTo: options.replyTo || this.config.defaultReplyTo,
sendAt: options.sendAt,
batchId: options.batchId,
asm: options.asm || this.config.asm,
ipPoolName: options.ipPoolName || this.config.ipPoolName,
};
const [response] = await sgMail.send(msg as any);
return {
success: true,
statusCode: response.statusCode,
headers: response.headers,
body: response.body,
};
} catch (error) {
console.error('Error sending email:', error);
throw error;
}
}
/**
* Send multiple emails in a single request
* @param messages Array of email options
* @returns Promise with the SendGrid response
*/
public async sendMultipleEmails(messages: EmailOptions[]) {
if (!this.initialized) {
this.initialize();
}
try {
const formattedMessages = messages.map((msg) => ({
to: msg.to,
from: msg.from || this.config.defaultFrom || 'no-reply@example.com',
subject: msg.subject,
text: msg.text,
html: msg.html,
templateId: msg.templateId,
dynamicTemplateData: msg.dynamicTemplateData,
attachments: msg.attachments,
categories: msg.categories,
customArgs: msg.customArgs,
headers: msg.headers,
mailSettings: msg.mailSettings || this.config.mailSettings,
trackingSettings: msg.trackingSettings || this.config.trackingSettings,
replyTo: msg.replyTo || this.config.defaultReplyTo,
sendAt: msg.sendAt,
batchId: msg.batchId,
asm: msg.asm || this.config.asm,
ipPoolName: msg.ipPoolName || this.config.ipPoolName,
}));
const response = await sgMail.send(formattedMessages as any, true) as ClientResponse[];
return {
success: true,
responses: response.map((res) => ({
statusCode: res.statusCode,
headers: res.headers,
body: res.body,
})),
} as BatchSendGridResponse;
} catch (error) {
console.error('Error sending multiple emails:', error);
throw error;
}
}
}
// Create a singleton instance
export const sendGridClient = new SendGridClient({
apiKey: process.env.SENDGRID_API_KEY || '',
});
/**
* Send an email using the default SendGrid client
* @param options Email options
* @returns Promise with the SendGrid response
*/
export const sendEmail = (options: EmailOptions) => {
return sendGridClient.sendEmail(options);
};
/**
* Send multiple emails in a single request using the default SendGrid client
* @param messages Array of email options
* @returns Promise with the SendGrid response
*/
export const sendMultipleEmails = (messages: EmailOptions[]) => {
return sendGridClient.sendMultipleEmails(messages);
};