@unsent/sdk 0.25.2
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/.eslintrc.cjs +10 -0
- package/LICENSE +21 -0
- package/README.md +328 -0
- package/dist/index.d.mts +1054 -0
- package/dist/index.d.ts +1054 -0
- package/dist/index.js +228 -0
- package/dist/index.mjs +201 -0
- package/package.json +29 -0
package/.eslintrc.cjs
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 unsent
|
|
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,328 @@
|
|
|
1
|
+
# @unsent/sdk SDK
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
|
|
5
|
+
- [unsent API key](https://app.unsent.dev/dev-settings/api-keys)
|
|
6
|
+
- [Verified domain](https://app.unsent.dev/domains)
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
### NPM
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @unsent/sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Yarn
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
yarn add @unsent/sdk
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### PNPM
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm add @unsent/sdk
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Bun
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
bun add @unsent/sdk
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
### Basic Setup
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { unsent } from "@unsent/sdk"
|
|
40
|
+
|
|
41
|
+
const client = new unsent("us_12345")
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Environment Variables
|
|
45
|
+
|
|
46
|
+
You can also set your API key using environment variables:
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
// Set UNSENT_API_KEY or UNSENT_API_KEY in your environment
|
|
50
|
+
// Then initialize without passing the key
|
|
51
|
+
const client = new unsent()
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Sending Emails
|
|
55
|
+
|
|
56
|
+
#### Simple Email
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
const { data, error } = await client.emails.send({
|
|
60
|
+
to: "hello@acme.com",
|
|
61
|
+
from: "hello@company.com",
|
|
62
|
+
subject: "unsent email",
|
|
63
|
+
html: "<p>unsent is the best open source product to send emails</p>",
|
|
64
|
+
text: "unsent is the best open source product to send emails",
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
if (error) {
|
|
68
|
+
console.error("Error:", error)
|
|
69
|
+
} else {
|
|
70
|
+
console.log("Email sent! ID:", data.id)
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### Email with Attachments
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
const { data, error } = await client.emails.send({
|
|
78
|
+
to: "hello@acme.com",
|
|
79
|
+
from: "hello@company.com",
|
|
80
|
+
subject: "Email with attachment",
|
|
81
|
+
html: "<p>Please find the attachment below</p>",
|
|
82
|
+
attachments: [
|
|
83
|
+
{
|
|
84
|
+
filename: "document.pdf",
|
|
85
|
+
content: "base64-encoded-content-here",
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
#### Email with React Component
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { MyEmailTemplate } from "./templates/MyEmailTemplate"
|
|
95
|
+
|
|
96
|
+
const { data, error } = await client.emails.send({
|
|
97
|
+
to: "hello@acme.com",
|
|
98
|
+
from: "hello@company.com",
|
|
99
|
+
subject: "Email with React template",
|
|
100
|
+
react: <MyEmailTemplate name="John" />,
|
|
101
|
+
})
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### Scheduled Email
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
const scheduledTime = new Date()
|
|
108
|
+
scheduledTime.setHours(scheduledTime.getHours() + 1) // Schedule for 1 hour from now
|
|
109
|
+
|
|
110
|
+
const { data, error } = await client.emails.send({
|
|
111
|
+
to: "hello@acme.com",
|
|
112
|
+
from: "hello@company.com",
|
|
113
|
+
subject: "Scheduled email",
|
|
114
|
+
html: "<p>This email was scheduled</p>",
|
|
115
|
+
scheduledAt: scheduledTime.toISOString(),
|
|
116
|
+
})
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### Batch Emails
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
const emails = [
|
|
123
|
+
{
|
|
124
|
+
to: "user1@example.com",
|
|
125
|
+
from: "hello@company.com",
|
|
126
|
+
subject: "Hello User 1",
|
|
127
|
+
html: "<p>Welcome User 1</p>",
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
to: "user2@example.com",
|
|
131
|
+
from: "hello@company.com",
|
|
132
|
+
subject: "Hello User 2",
|
|
133
|
+
html: "<p>Welcome User 2</p>",
|
|
134
|
+
},
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
const { data, error } = await client.emails.batch(emails)
|
|
138
|
+
|
|
139
|
+
if (error) {
|
|
140
|
+
console.error("Error:", error)
|
|
141
|
+
} else {
|
|
142
|
+
console.log(`Sent ${data.length} emails`)
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Managing Emails
|
|
147
|
+
|
|
148
|
+
#### Get Email Details
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
const { data, error } = await client.emails.get("email_id")
|
|
152
|
+
|
|
153
|
+
if (error) {
|
|
154
|
+
console.error("Error:", error)
|
|
155
|
+
} else {
|
|
156
|
+
console.log("Email status:", data.status)
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### Update Email
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
const { data, error } = await client.emails.update("email_id", {
|
|
164
|
+
subject: "Updated subject",
|
|
165
|
+
html: "<p>Updated content</p>",
|
|
166
|
+
})
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### Cancel Scheduled Email
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
const { data, error } = await client.emails.cancel("email_id")
|
|
173
|
+
|
|
174
|
+
if (error) {
|
|
175
|
+
console.error("Error:", error)
|
|
176
|
+
} else {
|
|
177
|
+
console.log("Email cancelled successfully")
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Managing Contacts
|
|
182
|
+
|
|
183
|
+
#### Create Contact
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const { data, error } = await client.contacts.create("contact_book_id", {
|
|
187
|
+
email: "user@example.com",
|
|
188
|
+
firstName: "John",
|
|
189
|
+
lastName: "Doe",
|
|
190
|
+
metadata: {
|
|
191
|
+
company: "Acme Inc",
|
|
192
|
+
role: "Developer",
|
|
193
|
+
},
|
|
194
|
+
})
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
#### Get Contact
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
const { data, error } = await client.contacts.get(
|
|
201
|
+
"contact_book_id",
|
|
202
|
+
"contact_id"
|
|
203
|
+
)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
#### Update Contact
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
const { data, error } = await client.contacts.update(
|
|
210
|
+
"contact_book_id",
|
|
211
|
+
"contact_id",
|
|
212
|
+
{
|
|
213
|
+
firstName: "Jane",
|
|
214
|
+
metadata: {
|
|
215
|
+
role: "Senior Developer",
|
|
216
|
+
},
|
|
217
|
+
}
|
|
218
|
+
)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
#### Upsert Contact
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
// Creates if doesn't exist, updates if exists
|
|
225
|
+
const { data, error } = await client.contacts.upsert(
|
|
226
|
+
"contact_book_id",
|
|
227
|
+
"contact_id",
|
|
228
|
+
{
|
|
229
|
+
email: "user@example.com",
|
|
230
|
+
firstName: "John",
|
|
231
|
+
lastName: "Doe",
|
|
232
|
+
}
|
|
233
|
+
)
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
#### Delete Contact
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
const { data, error } = await client.contacts.delete(
|
|
240
|
+
"contact_book_id",
|
|
241
|
+
"contact_id"
|
|
242
|
+
)
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Error Handling
|
|
246
|
+
|
|
247
|
+
The SDK returns a consistent response structure with `data` and `error`:
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
const { data, error } = await client.emails.send({
|
|
251
|
+
to: "invalid-email",
|
|
252
|
+
from: "hello@company.com",
|
|
253
|
+
subject: "Test",
|
|
254
|
+
html: "<p>Test</p>",
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
if (error) {
|
|
258
|
+
console.error(`Error ${error.code}: ${error.message}`)
|
|
259
|
+
return
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Safe to use data here
|
|
263
|
+
console.log("Email sent:", data.id)
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### TypeScript Support
|
|
267
|
+
|
|
268
|
+
The SDK is fully typed with TypeScript:
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
import { unsent } from "@unsent/sdk"
|
|
272
|
+
|
|
273
|
+
const client = new unsent("us_12345")
|
|
274
|
+
|
|
275
|
+
// Full type inference and autocomplete
|
|
276
|
+
const result = await client.emails.send({
|
|
277
|
+
to: "hello@acme.com",
|
|
278
|
+
from: "hello@company.com",
|
|
279
|
+
subject: "Typed email",
|
|
280
|
+
html: "<p>Fully typed!</p>",
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
// Type-safe access
|
|
284
|
+
if (result.data) {
|
|
285
|
+
const emailId: string = result.data.id
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## API Reference
|
|
290
|
+
|
|
291
|
+
### Client Methods
|
|
292
|
+
|
|
293
|
+
- `new unsent(key?, url?)` - Initialize the client
|
|
294
|
+
|
|
295
|
+
### Email Methods
|
|
296
|
+
|
|
297
|
+
- `client.emails.send(payload)` - Send an email (alias for `create`)
|
|
298
|
+
- `client.emails.create(payload)` - Create and send an email
|
|
299
|
+
- `client.emails.batch(emails)` - Send multiple emails in batch (max 100)
|
|
300
|
+
- `client.emails.get(emailId)` - Get email details
|
|
301
|
+
- `client.emails.update(emailId, payload)` - Update a scheduled email
|
|
302
|
+
- `client.emails.cancel(emailId)` - Cancel a scheduled email
|
|
303
|
+
|
|
304
|
+
### Contact Methods
|
|
305
|
+
|
|
306
|
+
- `client.contacts.create(bookId, payload)` - Create a contact
|
|
307
|
+
- `client.contacts.get(bookId, contactId)` - Get contact details
|
|
308
|
+
- `client.contacts.update(bookId, contactId, payload)` - Update a contact
|
|
309
|
+
- `client.contacts.upsert(bookId, contactId, payload)` - Upsert a contact
|
|
310
|
+
- `client.contacts.delete(bookId, contactId)` - Delete a contact
|
|
311
|
+
|
|
312
|
+
## Features
|
|
313
|
+
|
|
314
|
+
- 🔐 **Type-safe** - Full TypeScript support with type inference
|
|
315
|
+
- ⚡ **Modern** - Built with ESM and async/await
|
|
316
|
+
- 🎨 **React Email** - Send emails using React components
|
|
317
|
+
- 📦 **Lightweight** - Minimal dependencies
|
|
318
|
+
- 🔄 **Batch sending** - Send up to 100 emails in a single request
|
|
319
|
+
- ⏰ **Scheduled emails** - Schedule emails for later delivery
|
|
320
|
+
|
|
321
|
+
## Requirements
|
|
322
|
+
|
|
323
|
+
- Node.js 16+
|
|
324
|
+
- TypeScript 4.7+ (for TypeScript projects)
|
|
325
|
+
|
|
326
|
+
## License
|
|
327
|
+
|
|
328
|
+
MIT
|