@tozielinski/next-brevo-api-helper 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Torsten Zielinski
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,10 @@
1
+ # next-brevo-api-helper
2
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
3
+
4
+ ## Using the Brevo API for create, update and delete contacts, folders and lists and send mails via the API
5
+
6
+ # Quick Start
7
+ ### Install the package:
8
+ ```bash
9
+ npm install @tozielinski/next-brevo-api-helper
10
+ ```
@@ -0,0 +1,59 @@
1
+ import type { BrevoApiResponse, BrevoStatus, BrevoContact, BrevoCreateContactRequest, BrevoCreateContactResponse, BrevoGetContactResponse, BrevoSendEmailRequest, BrevoSendEmailResponse, BrevoSendSmsRequest, BrevoSendSmsResponse, BrevoList, BrevoCreateListRequest, BrevoCreateListResponse, BrevoGetListsResponse, BrevoUpdateListRequest, BrevoDeleteListRequest, BrevoAddContactsToListRequest, BrevoAddContactsToListResponse, BrevoFolder, BrevoCreateFolderRequest, BrevoCreateFolderResponse, BrevoGetFolderRequest, BrevoGetFoldersResponse, BrevoUpdateFolderRequest, BrevoDeleteFolderRequest } from "./brevo";
2
+ /**
3
+ * Create a fabric for brevoFetch with API key preconfigured
4
+ * @param baseUrl
5
+ * @param apiKey
6
+ */
7
+ export declare function createBrevoFetcher(baseUrl: string, apiKey: string): <T>(endpoint: string, options?: RequestInit) => Promise<BrevoApiResponse<T>>;
8
+ /**
9
+ * Configuration for BrevoClient, when Toke is not available in environment
10
+ */
11
+ export interface BrevoClientConfig {
12
+ apiKey?: string;
13
+ baseUrl?: string;
14
+ }
15
+ /**
16
+ * BrevoClient – typed wrapper for Brevo REST API v3
17
+ */
18
+ export declare class BrevoClient {
19
+ private brevoFetcher;
20
+ constructor(config?: BrevoClientConfig);
21
+ /** Create or update a contact */
22
+ createContact(contact: BrevoCreateContactRequest): Promise<BrevoApiResponse<BrevoCreateContactResponse>>;
23
+ /** Get contact by email or ID */
24
+ getContact(identifier: string | number): Promise<BrevoApiResponse<BrevoGetContactResponse>>;
25
+ /** Delete a contact */
26
+ deleteContact(identifier: string | number): Promise<BrevoApiResponse<null>>;
27
+ /** Get all lists */
28
+ getLists(): Promise<BrevoApiResponse<BrevoGetListsResponse>>;
29
+ /** Get lists of a folder */
30
+ getListContacts(listId: number): Promise<BrevoApiResponse<BrevoContact[]>>;
31
+ /** Get list details */
32
+ getListDetails(listId: number): Promise<BrevoApiResponse<BrevoList>>;
33
+ /** Create a new list */
34
+ createList(list: BrevoCreateListRequest): Promise<BrevoApiResponse<BrevoCreateListResponse>>;
35
+ updateList(req: BrevoUpdateListRequest): Promise<BrevoApiResponse<BrevoStatus>>;
36
+ /** Delete a list */
37
+ deleteList(req: BrevoDeleteListRequest): Promise<BrevoApiResponse<BrevoStatus>>;
38
+ /** Add existing contacts to a list */
39
+ addContactsToList(req: BrevoAddContactsToListRequest): Promise<BrevoApiResponse<BrevoAddContactsToListResponse>>;
40
+ /** Get all folders */
41
+ getFolders(): Promise<BrevoApiResponse<BrevoGetFoldersResponse>>;
42
+ /** Get lists of a folder */
43
+ getFolderLists(req: BrevoGetFolderRequest): Promise<BrevoApiResponse<BrevoList[]>>;
44
+ /** Get folder details */
45
+ getFolderDetails(req: BrevoGetFolderRequest): Promise<BrevoApiResponse<BrevoFolder>>;
46
+ /** Create a new folder */
47
+ createFolder(req: BrevoCreateFolderRequest): Promise<BrevoApiResponse<BrevoCreateFolderResponse>>;
48
+ /** Update a folders name */
49
+ updateFolder(req: BrevoUpdateFolderRequest): Promise<BrevoApiResponse<BrevoStatus>>;
50
+ /** Delete a folder and all its lists */
51
+ deleteFolder(req: BrevoDeleteFolderRequest): Promise<BrevoApiResponse<BrevoStatus>>;
52
+ /** Send transactional email */
53
+ sendEmail(email: BrevoSendEmailRequest): Promise<BrevoApiResponse<BrevoSendEmailResponse>>;
54
+ /** Send SMS */
55
+ static sendSms(sms: BrevoSendSmsRequest): Promise<BrevoApiResponse<BrevoSendSmsResponse>>;
56
+ /** Ping Brevo API (GET /account) */
57
+ static ping(): Promise<BrevoApiResponse<unknown>>;
58
+ }
59
+ //# sourceMappingURL=brevo-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brevo-client.d.ts","sourceRoot":"","sources":["../src/brevo-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrevoClient = void 0;
4
+ exports.createBrevoFetcher = createBrevoFetcher;
5
+ /**
6
+ * Environment-based configuration
7
+ */
8
+ const BREVO_BASE_URL = "https://api.brevo.com/v3";
9
+ const BREVO_API_KEY = process.env.BREVO_API_KEY;
10
+ if (!BREVO_API_KEY) {
11
+ console.warn("⚠️ BREVO_API_KEY not set in environment. API calls will fail.");
12
+ }
13
+ /**
14
+ * Create a fabric for brevoFetch with API key preconfigured
15
+ * @param baseUrl
16
+ * @param apiKey
17
+ */
18
+ function createBrevoFetcher(baseUrl, apiKey) {
19
+ return async function brevoFetcher(endpoint, options = {}) {
20
+ const res = await fetch(`${baseUrl}${endpoint}`, {
21
+ ...options,
22
+ headers: {
23
+ "Content-Type": "application/json",
24
+ "api-key": apiKey,
25
+ ...options.headers,
26
+ },
27
+ });
28
+ const status = res.status;
29
+ let data = null;
30
+ try {
31
+ data = await res.json();
32
+ }
33
+ catch {
34
+ data = null;
35
+ }
36
+ if (!res.ok) {
37
+ const error = {
38
+ status,
39
+ message: data?.message || res.statusText,
40
+ code: data?.code,
41
+ details: data,
42
+ };
43
+ return { status, error };
44
+ }
45
+ return { status, data };
46
+ };
47
+ }
48
+ /**
49
+ * Minimal helper for making API requests
50
+ */
51
+ async function brevoFetch(endpoint, options = {}) {
52
+ const res = await fetch(`${BREVO_BASE_URL}${endpoint}`, {
53
+ ...options,
54
+ headers: {
55
+ "Content-Type": "application/json",
56
+ "api-key": BREVO_API_KEY,
57
+ ...options.headers,
58
+ },
59
+ });
60
+ const status = res.status;
61
+ let data = null;
62
+ try {
63
+ data = await res.json();
64
+ }
65
+ catch {
66
+ data = null;
67
+ }
68
+ if (!res.ok) {
69
+ const error = {
70
+ status,
71
+ message: data?.message || res.statusText,
72
+ code: data?.code,
73
+ details: data,
74
+ };
75
+ return { status, error };
76
+ }
77
+ return { status, data };
78
+ }
79
+ async function fetchAllPaginated(endpoint, responseKey, limit = 50, extraQuery = "") {
80
+ let offset = 0;
81
+ const allItems = [];
82
+ let items;
83
+ do {
84
+ const url = `${endpoint}?limit=${limit}&offset=${offset}${extraQuery}`;
85
+ const response = await brevoFetch(url, { method: "GET" });
86
+ if (response.status !== 200) {
87
+ return response; // Fehler durchreichen
88
+ }
89
+ items = response.data?.[responseKey] ?? [];
90
+ allItems.push(...items);
91
+ offset += limit;
92
+ } while (items.length === limit);
93
+ return {
94
+ status: 200,
95
+ data: {
96
+ count: allItems.length,
97
+ [responseKey]: allItems,
98
+ },
99
+ };
100
+ }
101
+ /**
102
+ * BrevoClient – typed wrapper for Brevo REST API v3
103
+ */
104
+ class BrevoClient {
105
+ brevoFetcher;
106
+ // private apiKey: string;
107
+ constructor(config) {
108
+ const apiKey = config?.apiKey ?? process.env.BREVO_API_KEY;
109
+ const baseUrl = config?.baseUrl ?? process.env.BREVO_BASE_URL ?? "https://api.brevo.com/v3";
110
+ this.brevoFetcher = createBrevoFetcher(baseUrl, apiKey);
111
+ }
112
+ //
113
+ // ────────────────────────────────
114
+ // CONTACTS
115
+ // ────────────────────────────────
116
+ //
117
+ /** Create or update a contact */
118
+ async createContact(contact) {
119
+ return brevoFetch("/contacts", {
120
+ method: "POST",
121
+ body: JSON.stringify(contact),
122
+ });
123
+ }
124
+ /** Get contact by email or ID */
125
+ async getContact(identifier) {
126
+ return brevoFetch(`/contacts/${identifier}`, {
127
+ method: "GET",
128
+ });
129
+ }
130
+ /** Delete a contact */
131
+ async deleteContact(identifier) {
132
+ return brevoFetch(`/contacts/${identifier}`, { method: "DELETE" });
133
+ }
134
+ //
135
+ // ────────────────────────────────
136
+ // LISTS
137
+ // ────────────────────────────────
138
+ //
139
+ /** Get all lists */
140
+ async getLists() {
141
+ return fetchAllPaginated("/contacts/lists", "lists", 50, "&sort=asc");
142
+ }
143
+ /** Get lists of a folder */
144
+ async getListContacts(listId) {
145
+ return fetchAllPaginated(`/contacts/folders/${listId}/contacts`, "contacts", 50, "&sort=asc");
146
+ }
147
+ /** Get list details */
148
+ async getListDetails(listId) {
149
+ return brevoFetch(`/contacts/lists/${listId}`, {
150
+ method: "GET"
151
+ });
152
+ }
153
+ /** Create a new list */
154
+ async createList(list) {
155
+ return brevoFetch("/contacts/lists", {
156
+ method: "POST",
157
+ body: JSON.stringify(list),
158
+ });
159
+ }
160
+ async updateList(req) {
161
+ return brevoFetch(`/contacts/lists/${req.id}`, {
162
+ method: "PUT",
163
+ body: JSON.stringify(req.name),
164
+ });
165
+ }
166
+ /** Delete a list */
167
+ async deleteList(req) {
168
+ return brevoFetch(`/contacts/lists/${req.id}`, {
169
+ method: "DELETE"
170
+ });
171
+ }
172
+ /** Add existing contacts to a list */
173
+ async addContactsToList(req) {
174
+ let body = {};
175
+ if ("emails" in req) {
176
+ body.emails = req.emails;
177
+ }
178
+ else if ("ids" in req) {
179
+ body.ids = req.ids;
180
+ }
181
+ else if ("extIds" in req) {
182
+ body.extIds = req.extIds;
183
+ }
184
+ return brevoFetch(`/contacts/lists/${req.id}/contacts/add`, {
185
+ method: "POST",
186
+ body: JSON.stringify(body),
187
+ });
188
+ }
189
+ // async deleteContactFromList(req: BrevoDeleteContactFromListRequest): Promise<BrevoApiResponse<BrevoStatus>> {
190
+ //
191
+ // }
192
+ //
193
+ // ────────────────────────────────
194
+ // FOLDERS
195
+ // ────────────────────────────────
196
+ //
197
+ /** Get all folders */
198
+ async getFolders() {
199
+ return fetchAllPaginated("/contacts/folders", "folders", 50, "&sort=asc");
200
+ }
201
+ /** Get lists of a folder */
202
+ async getFolderLists(req) {
203
+ return fetchAllPaginated(`/contacts/folders/${req.id}/lists`, "lists", 50, "&sort=asc");
204
+ }
205
+ /** Get folder details */
206
+ async getFolderDetails(req) {
207
+ return brevoFetch(`/contacts/folders/${req.id}`, {
208
+ method: "GET"
209
+ });
210
+ }
211
+ /** Create a new folder */
212
+ async createFolder(req) {
213
+ return brevoFetch("/contacts/folders", {
214
+ method: "POST",
215
+ body: JSON.stringify({ name: req.name }),
216
+ });
217
+ }
218
+ /** Update a folders name */
219
+ async updateFolder(req) {
220
+ return brevoFetch(`/contacts/folders/${req.id}`, {
221
+ method: "PUT",
222
+ body: JSON.stringify({ name: req.name }),
223
+ });
224
+ }
225
+ /** Delete a folder and all its lists */
226
+ async deleteFolder(req) {
227
+ return brevoFetch(`/contacts/folders/${req.id}`, {
228
+ method: "DELETE"
229
+ });
230
+ }
231
+ //
232
+ // ────────────────────────────────
233
+ // TRANSACTIONAL EMAILS
234
+ // ────────────────────────────────
235
+ //
236
+ /** Send transactional email */
237
+ async sendEmail(email) {
238
+ return brevoFetch("/smtp/email", {
239
+ method: "POST",
240
+ body: JSON.stringify(email),
241
+ });
242
+ }
243
+ //
244
+ // ────────────────────────────────
245
+ // TRANSACTIONAL SMS
246
+ // ────────────────────────────────
247
+ //
248
+ /** Send SMS */
249
+ static async sendSms(sms) {
250
+ return brevoFetch("/transactionalSMS/sms", {
251
+ method: "POST",
252
+ body: JSON.stringify(sms),
253
+ });
254
+ }
255
+ //
256
+ // ────────────────────────────────
257
+ // UTILS
258
+ // ────────────────────────────────
259
+ //
260
+ /** Ping Brevo API (GET /account) */
261
+ static async ping() {
262
+ return brevoFetch("/account", { method: "GET" });
263
+ }
264
+ }
265
+ exports.BrevoClient = BrevoClient;
@@ -0,0 +1,358 @@
1
+ /**
2
+ * TypeScript declarations for Brevo (Sendinblue) API v3
3
+ * Compatible with Next.js 15 / TypeScript 5.x
4
+ */
5
+
6
+ export const BrevoHttpStatus = {
7
+ 200: "OK",
8
+ 201: "Created",
9
+ 202: "Accepted",
10
+ 204: "No Content",
11
+ 400: "Bad Request",
12
+ 401: "Unauthorized",
13
+ 403: "Forbidden",
14
+ 404: "Not Found",
15
+ 429: "Too Many Requests",
16
+ 500: "Internal Server Error",
17
+ } as const;
18
+
19
+ export type BrevoStatusCode = keyof typeof BrevoHttpStatus;
20
+
21
+ export type BrevoStatusMessage = (typeof BrevoHttpStatus)[BrevoStatusCode];
22
+
23
+ export type BrevoStatus = {
24
+ code: BrevoStatusCode;
25
+ message: BrevoStatusMessage;
26
+ };
27
+
28
+ /////////////////////////////
29
+ // CONTACTS
30
+ /////////////////////////////
31
+
32
+ export interface BrevoContact {
33
+ id?: number;
34
+ email?: string;
35
+ sms?: string;
36
+ attributes?: Record<string, string | number | boolean | (string | number | boolean)[]>;
37
+ listIds?: number[];
38
+ emailBlacklisted?: boolean;
39
+ smsBlacklisted?: boolean;
40
+ updateEnabled?: boolean;
41
+ extId?: string;
42
+ createdAt?: string;
43
+ modifiedAt?: string;
44
+ }
45
+
46
+ /**
47
+ * Request payload when creating a new contact.
48
+ * API: POST /v3/contact
49
+ */
50
+ export interface BrevoCreateContactRequest {
51
+ email?: string;
52
+ sms?: string;
53
+ attributes?: Record<string, string | number | boolean | (string | number | boolean)[]>;
54
+ listIds?: number[];
55
+ updateEnabled?: boolean;
56
+ emailBlacklisted?: boolean;
57
+ smsBlacklisted?: boolean;
58
+ extId?: string;
59
+ }
60
+
61
+ /**
62
+ * Response from POST /v3/contact
63
+ */
64
+ export interface BrevoCreateContactResponse {
65
+ id: number;
66
+ email?: string;
67
+ sms?: string;
68
+ attributes?: Record<string, string | number | boolean | (string | number | boolean)[]>;
69
+ createdAt: string;
70
+ }
71
+
72
+ /**
73
+ * Response for GET /v3/contact/{identifier}
74
+ */
75
+ export interface BrevoGetContactResponse extends BrevoContact {
76
+ listIds: number[];
77
+ statistics?: BrevoContactStats;
78
+ }
79
+
80
+ /**
81
+ * Contact statistics (opens, clicks, etc.)
82
+ */
83
+ export interface BrevoContactStats {
84
+ messagesSent?: number;
85
+ delivered?: number;
86
+ opened?: number;
87
+ click?: number;
88
+ hardBounces?: number;
89
+ softBounces?: number;
90
+ complaints?: number;
91
+ unsubscriptions?: number;
92
+ transactionalStats?: {
93
+ delivered?: number;
94
+ opened?: number;
95
+ click?: number;
96
+ softBounces?: number;
97
+ hardBounces?: number;
98
+ };
99
+ }
100
+
101
+ /////////////////////////////
102
+ // ATTRIBUTES
103
+ /////////////////////////////
104
+
105
+ export interface BrevoAttributeCategory {
106
+ name: string;
107
+ attributes: BrevoContactAttributeDefinition[];
108
+ }
109
+
110
+ export interface BrevoContactAttributeDefinition {
111
+ name: string;
112
+ type: "text" | "date" | "float" | "boolean" | "id" | "category" | "multiple_choice";
113
+ value?: string | number | boolean;
114
+ enumeration?: { value: number; label: string }[];
115
+ calculatedValue?: boolean;
116
+ createdAt?: string;
117
+ updatedAt?: string;
118
+ }
119
+
120
+ export interface BrevoListAttributesResponse {
121
+ attributes: BrevoContactAttributeDefinition[];
122
+ }
123
+
124
+ /////////////////////////////
125
+ // LISTS
126
+ /////////////////////////////
127
+
128
+ export interface BrevoList {
129
+ id: number;
130
+ name: string;
131
+ totalSubscribers: number;
132
+ uniqueSubscribers: number;
133
+ shared: boolean;
134
+ folderId: number;
135
+ createdAt: string;
136
+ dynamic?: boolean;
137
+ }
138
+
139
+ export interface BrevoGetListsResponse {
140
+ lists: BrevoList[];
141
+ count: number;
142
+ }
143
+
144
+ export interface BrevoGetListContactsResponse {
145
+ contacts: BrevoContact[];
146
+ count: number;
147
+ }
148
+
149
+ export interface BrevoCreateListRequest {
150
+ name: string;
151
+ folderId?: number;
152
+ }
153
+
154
+ export interface BrevoCreateListResponse {
155
+ id: number;
156
+ name: string;
157
+ totalSubscribers: number;
158
+ folderId: number;
159
+ createdAt: string;
160
+ }
161
+
162
+ export interface BrevoUpdateListRequest {
163
+ id: number;
164
+ name: string;
165
+ }
166
+
167
+ export interface BrevoDeleteListRequest {
168
+ id: number;
169
+ }
170
+
171
+ export interface BrevoAddContactsToListBase {
172
+ id: number;
173
+ }
174
+
175
+ export interface BrevoAddContactsToListByEmail extends BrevoAddContactsToListBase {
176
+ emails: string[];
177
+ ids?: never;
178
+ extIds?: never;
179
+ }
180
+
181
+ export interface BrevoAddContactsToListById extends BrevoAddContactsToListBase {
182
+ ids: number[];
183
+ emails?: never;
184
+ extIds?: never;
185
+ }
186
+
187
+ export interface BrevoAddContactsToListByExtId extends BrevoAddContactsToListBase {
188
+ extIds: string[];
189
+ emails?: never;
190
+ ids?: never;
191
+ }
192
+
193
+ export type BrevoAddContactsToListRequest =
194
+ | BrevoAddContactsToListByEmail
195
+ | BrevoAddContactsToListById
196
+ | BrevoAddContactsToListByExtId;
197
+
198
+ export interface BrevoAddContactsToListResponse {
199
+ contacts: {
200
+ success: number[] | string[],
201
+ failure: number[] | string[],
202
+ };
203
+ }
204
+
205
+ /////////////////////////////
206
+ // FOLDERS
207
+ /////////////////////////////
208
+
209
+ export interface BrevoFolder {
210
+ id: number;
211
+ name: string;
212
+ uniqueSubscribers: number;
213
+ }
214
+
215
+ export interface BrevoGetFoldersResponse {
216
+ folders: BrevoFolder[];
217
+ count: number;
218
+ }
219
+
220
+ export interface BrevoGetFolderRequest {
221
+ id: number;
222
+ }
223
+
224
+ export interface BrevoGetFolderListsResponse {
225
+ lists: BrevoList[];
226
+ count: number;
227
+ }
228
+
229
+ export interface BrevoCreateFolderRequest {
230
+ name: string;
231
+ }
232
+
233
+ export interface BrevoCreateFolderResponse {
234
+ id: number;
235
+ }
236
+
237
+ export interface BrevoUpdateFolderRequest {
238
+ id: number;
239
+ name: string;
240
+ }
241
+
242
+ export interface BrevoDeleteFolderRequest {
243
+ id: number;
244
+ }
245
+
246
+ /////////////////////////////
247
+ // TRANSACTIONAL EMAILS
248
+ /////////////////////////////
249
+
250
+ export interface BrevoEmailRecipient {
251
+ email: string;
252
+ name?: string;
253
+ }
254
+
255
+ export interface BrevoSendEmailRequest {
256
+ sender: BrevoEmailRecipient & { id?: number };
257
+ to: BrevoEmailRecipient[];
258
+ cc?: BrevoEmailRecipient[];
259
+ bcc?: BrevoEmailRecipient[];
260
+ replyTo?: BrevoEmailRecipient;
261
+ subject?: string;
262
+ htmlContent?: string;
263
+ textContent?: string;
264
+ templateId?: number;
265
+ params?: Record<string, string | number | boolean>;
266
+ headers?: Record<string, string>;
267
+ attachment?: {
268
+ url?: string;
269
+ content?: string; // Base64 encoded
270
+ name?: string;
271
+ }[];
272
+ tags?: string[];
273
+ }
274
+
275
+ export interface BrevoSendEmailResponse {
276
+ messageId: string;
277
+ }
278
+
279
+ /////////////////////////////
280
+ // TRANSACTIONAL SMS
281
+ /////////////////////////////
282
+
283
+ export interface BrevoSendSmsRequest {
284
+ sender: string; // must be alphanumeric and <= 11 chars
285
+ recipient: string;
286
+ content: string;
287
+ type?: "transactional" | "marketing";
288
+ tag?: string;
289
+ webUrl?: string;
290
+ }
291
+
292
+ export interface BrevoSendSmsResponse {
293
+ messageId: string;
294
+ reference?: string;
295
+ }
296
+
297
+ /////////////////////////////
298
+ // SMTP / EMAIL EVENT WEBHOOKS
299
+ /////////////////////////////
300
+
301
+ export interface BrevoEmailWebhookEvent {
302
+ event: "delivered" | "opened" | "clicked" | "hardBounce" | "softBounce" | "spam" | "invalidEmail" | "deferred" | "blocked" | "unsubscribed" | "error";
303
+ email: string;
304
+ id: string;
305
+ date: string;
306
+ subject?: string;
307
+ tag?: string;
308
+ messageId?: string;
309
+ reason?: string;
310
+ sendingIp?: string;
311
+ ts?: number;
312
+ ts_event?: number;
313
+ }
314
+
315
+ /////////////////////////////
316
+ // MARKETING CAMPAIGNS (optional)
317
+ /////////////////////////////
318
+
319
+ export interface BrevoCampaign {
320
+ id: number;
321
+ name: string;
322
+ subject: string;
323
+ sender: {
324
+ name: string;
325
+ email: string;
326
+ };
327
+ type: "classic" | "trigger";
328
+ status: "draft" | "sent" | "archive" | "queued" | "suspended" | "inProcess";
329
+ statistics?: {
330
+ delivered?: number;
331
+ opened?: number;
332
+ click?: number;
333
+ };
334
+ createdAt?: string;
335
+ modifiedAt?: string;
336
+ }
337
+
338
+ /////////////////////////////
339
+ // ERROR HANDLING
340
+ /////////////////////////////
341
+
342
+ export interface BrevoApiError {
343
+ code?: string | number;
344
+ message: string;
345
+ status?: number;
346
+ details?: any;
347
+ }
348
+
349
+ /////////////////////////////
350
+ // GENERIC UTILS
351
+ /////////////////////////////
352
+
353
+ export type BrevoApiResponse<T> = {
354
+ data?: T;
355
+ error?: BrevoApiError;
356
+ status: number;
357
+ };
358
+
@@ -0,0 +1,3 @@
1
+ export * from "./brevo-client";
2
+ export type * from "./brevo";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,mBAAmB,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./brevo-client"), exports);
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@tozielinski/next-brevo-api-helper",
3
+ "version": "1.0.0",
4
+ "description": "Lightweight helper to use Brevo to send mails via the Brevo API and maintain all",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc && cp src/brevo.d.ts dist/",
12
+ "test": "vitest run",
13
+ "typecheck": "tsc --noEmit",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/tozielinski/next-brevo-api-helper.git"
22
+ },
23
+ "keywords": [
24
+ "next",
25
+ "nextjs",
26
+ "brevo",
27
+ "api",
28
+ "mail"
29
+ ],
30
+ "author": "Torsten Zielinski",
31
+ "license": "MIT",
32
+ "bugs": {
33
+ "url": "https://github.com/tozielinski/next-brevo-api-helper/issues"
34
+ },
35
+ "homepage": "https://github.com/tozielinski/next-brevo-api-helper#readme",
36
+ "devDependencies": {
37
+ "@types/node": "^20.19.25",
38
+ "typescript": "^5.0.0",
39
+ "vitest": "^4.0.12"
40
+ }
41
+ }