Skip to content

Commit

Permalink
feat: Add new batch methods (#199)
Browse files Browse the repository at this point in the history
Co-authored-by: Bu Kinoshita <[email protected]>
  • Loading branch information
vcapretz and bukinoshita authored Oct 27, 2023
1 parent 4bb4f65 commit ae19ac7
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 25 deletions.
96 changes: 96 additions & 0 deletions src/batch/batch.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { enableFetchMocks } from 'jest-fetch-mock';
import { Resend } from '../resend';

enableFetchMocks();

const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');

describe('Batch', () => {
afterEach(() => fetchMock.resetMocks());

describe('create', () => {
it('sends multiple emails', async () => {
const payload = [
{
from: '[email protected]',
to: '[email protected]',
subject: 'Hello World',
html: '<h1>Hello world</h1>',
},
{
from: '[email protected]',
to: '[email protected]',
subject: 'Olá mundo',
html: '<h1>olá mundo</h1>',
},
{
from: '[email protected]',
to: '[email protected]',
subject: 'Hi there',
html: '<h1>Hi there</h1>',
},
];

fetchMock.mockOnce(
JSON.stringify({
data: [{ id: '1234' }, { id: '4567' }, { id: '4242' }],
}),
{
status: 200,
headers: {
'content-type': 'application/json',
Authorization: 'Bearer re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop',
},
},
);

const data = await resend.batch.create(payload);
expect(data).toMatchObject({
data: [{ id: '1234' }, { id: '4567' }, { id: '4242' }],
});
});
});

describe('send', () => {
it('sends multiple emails', async () => {
const payload = [
{
from: '[email protected]',
to: '[email protected]',
subject: 'Hello World',
html: '<h1>Hello world</h1>',
},
{
from: '[email protected]',
to: '[email protected]',
subject: 'Olá mundo',
html: '<h1>olá mundo</h1>',
},
{
from: '[email protected]',
to: '[email protected]',
subject: 'Hi there',
html: '<h1>Hi there</h1>',
},
];

fetchMock.mockOnce(
JSON.stringify({
data: [{ id: '1234' }, { id: '4567' }, { id: '4242' }],
}),
{
status: 200,
headers: {
'content-type': 'application/json',
Authorization: 'Bearer re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop',
},
},
);

const data = await resend.batch.send(payload);
expect(data).toMatchObject({
data: [{ id: '1234' }, { id: '4567' }, { id: '4242' }],
});
});
});
});
39 changes: 39 additions & 0 deletions src/batch/batch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { render } from '@react-email/render';
import * as React from 'react';
import { Resend } from '../resend';
import {
CreateBatchOptions,
CreateBatchRequestOptions,
CreateBatchResponse,
} from './interfaces';

export class Batch {
constructor(private readonly resend: Resend) {}

async send(
payload: CreateBatchOptions,
options: CreateBatchRequestOptions = {},
): Promise<CreateBatchResponse> {
return this.create(payload, options);
}

async create(
payload: CreateBatchOptions,
options: CreateBatchRequestOptions = {},
): Promise<CreateBatchResponse> {
for (const email of payload) {
if (email.react) {
email.html = render(email.react as React.ReactElement);
delete email.react;
}
}

const data = await this.resend.post<CreateBatchResponse>(
'/emails/batch',
payload,
options,
);

return data;
}
}
13 changes: 13 additions & 0 deletions src/batch/interfaces/create-batch-options.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { PostOptions } from '../../common/interfaces';
import { CreateEmailOptions } from '../../emails/interfaces/create-email-options.interface';

export type CreateBatchOptions = CreateEmailOptions[];

export interface CreateBatchRequestOptions extends PostOptions {}

export interface CreateBatchResponse {
data: {
/** The ID of the newly created email. */
id: string;
}[];
}
1 change: 1 addition & 0 deletions src/batch/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './create-batch-options.interface';
30 changes: 5 additions & 25 deletions src/resend.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as React from 'react';
import { render } from '@react-email/render';
import { version } from '../package.json';
import { GetOptions, PostOptions, PutOptions } from './common/interfaces';
import { ApiKeys } from './api-keys/api-keys';
import { Batch } from './batch/batch';
import { GetOptions, PostOptions, PutOptions } from './common/interfaces';
import { Domains } from './domains/domains';
import { Emails } from './emails/emails';
import { CreateEmailOptions, CreateEmailResponse } from './emails/interfaces';
Expand All @@ -18,6 +17,7 @@ export class Resend {
readonly apiKeys = new ApiKeys(this);
readonly domains = new Domains(this);
readonly emails = new Emails(this);
readonly batch = new Batch(this);

constructor(readonly key?: string) {
if (!key) {
Expand Down Expand Up @@ -100,27 +100,7 @@ export class Resend {
return await this.fetchRequest<T>(path, requestOptions);
}

async sendEmail(data: CreateEmailOptions) {
const path = '/email';

if (data.react) {
data.html = render(data.react as React.ReactElement);
delete data.react;
}

const response = await this.post<CreateEmailResponse>(path, {
from: data.from,
to: data.to,
bcc: data.bcc,
cc: data.cc,
reply_to: data.reply_to,
subject: data.subject,
text: data.text,
html: data.html,
attachments: data.attachments,
tags: data.tags,
});

return response;
async sendEmail(data: CreateEmailOptions): Promise<CreateEmailResponse> {
return this.emails.create(data);
}
}

0 comments on commit ae19ac7

Please sign in to comment.