shipmail 0.2.2 → 0.3.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/README.md +42 -3
- package/dist/index.cjs +87 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +253 -169
- package/dist/index.d.ts +253 -169
- package/dist/index.js +87 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ Official TypeScript SDK for the [Shipmail](https://shipmail.to) API. Zero runtim
|
|
|
20
20
|
- [Messages](#messages)
|
|
21
21
|
- [Sandbox](#sandbox)
|
|
22
22
|
- [Threads](#threads)
|
|
23
|
+
- [Reply scans](#reply-scans)
|
|
23
24
|
- [Webhooks](#webhooks)
|
|
24
25
|
- [Suppressions](#suppressions)
|
|
25
26
|
- [Audiences](#audiences)
|
|
@@ -158,8 +159,6 @@ const folder = await shipmail.mailboxes.createFolder("mbx_...", {
|
|
|
158
159
|
await shipmail.mailboxes.updateFolder("mbx_...", folder.id, { name: "VIP Clients" });
|
|
159
160
|
await shipmail.mailboxes.deleteFolder("mbx_...", folder.id);
|
|
160
161
|
const identities = await shipmail.mailboxes.listIdentities("mbx_...");
|
|
161
|
-
const rules = await shipmail.mailboxes.getRules("mbx_...");
|
|
162
|
-
await shipmail.mailboxes.updateRules("mbx_...", { rules: rules.rules });
|
|
163
162
|
await shipmail.mailboxes.updateSpamFilter("mbx_...", { threshold: 8 });
|
|
164
163
|
await shipmail.mailboxes.delete("mbx_...");
|
|
165
164
|
|
|
@@ -170,6 +169,26 @@ await shipmail.mailboxes.updateAutoReply("mbx_...", {
|
|
|
170
169
|
from_date: "2026-06-01",
|
|
171
170
|
to_date: "2026-06-07",
|
|
172
171
|
});
|
|
172
|
+
|
|
173
|
+
const mailboxId = "550e8400-e29b-41d4-a716-446655440000";
|
|
174
|
+
const inbox = await shipmail.mailboxes.listInboxMessages(mailboxId, {
|
|
175
|
+
after: "2025-07-20T00:00:00.000Z",
|
|
176
|
+
before: "2026-07-20T00:00:00.000Z",
|
|
177
|
+
limit: 50,
|
|
178
|
+
});
|
|
179
|
+
const exact = await shipmail.mailboxes.getInboxMessage(mailboxId, inbox.data[0].id);
|
|
180
|
+
|
|
181
|
+
const queue = await shipmail.mailboxes.listInboxThreads(mailboxId, {
|
|
182
|
+
reply_state: "needs_reply",
|
|
183
|
+
after: "2025-07-20T00:00:00.000Z",
|
|
184
|
+
});
|
|
185
|
+
const candidate = queue.data[0];
|
|
186
|
+
const draft = await shipmail.mailboxes.createInboxReplyDraft(mailboxId, candidate.thread_id, {
|
|
187
|
+
text: "Thanks for the note.",
|
|
188
|
+
expected_reply_version: candidate.reply_version,
|
|
189
|
+
});
|
|
190
|
+
// Apply your approval policy before sending. Stale versions fail with 409 without delivery.
|
|
191
|
+
await shipmail.mailboxes.sendInboxReplyDraft(mailboxId, candidate.thread_id, draft.id);
|
|
173
192
|
```
|
|
174
193
|
|
|
175
194
|
## Messages
|
|
@@ -195,7 +214,7 @@ await shipmail.messages.reply("msg_...", {
|
|
|
195
214
|
|
|
196
215
|
## Sandbox
|
|
197
216
|
|
|
198
|
-
Create a test API key (`sm_test_...`) to simulate email without contacting real recipients. Test messages, threads,
|
|
217
|
+
Create a test API key (`sm_test_...`) to simulate email without contacting real recipients. Test messages, threads, Assistant automations, webhooks, quota, suppressions, and reputation are isolated from live mode.
|
|
199
218
|
|
|
200
219
|
```ts
|
|
201
220
|
const testClient = new ShipMailClient("sm_test_...");
|
|
@@ -229,6 +248,21 @@ await shipmail.threads.reply(threadId, {
|
|
|
229
248
|
});
|
|
230
249
|
```
|
|
231
250
|
|
|
251
|
+
## Reply scans
|
|
252
|
+
|
|
253
|
+
Use a durable, atomically captured scan for a historical window. Creation returns a completed
|
|
254
|
+
snapshot; retry a `409` with bounded backoff while historical classification finishes, then follow
|
|
255
|
+
every opaque `next_cursor`; never parse or fabricate cursors. Scans are retained for 30 days.
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
const scan = await shipmail.replyScans.create({
|
|
259
|
+
mailbox_ids: ["550e8400-e29b-41d4-a716-446655440000"],
|
|
260
|
+
after: new Date(Date.now() - 365 * 86_400_000).toISOString(),
|
|
261
|
+
});
|
|
262
|
+
const results = await shipmail.replyScans.listResults(scan.id, { limit: 100 });
|
|
263
|
+
console.log(results.data);
|
|
264
|
+
```
|
|
265
|
+
|
|
232
266
|
## Webhooks
|
|
233
267
|
|
|
234
268
|
```ts
|
|
@@ -261,6 +295,7 @@ message.sent
|
|
|
261
295
|
message.delivered
|
|
262
296
|
message.bounced
|
|
263
297
|
message.complained
|
|
298
|
+
thread.needs_reply
|
|
264
299
|
domain.verified
|
|
265
300
|
domain.verification_failed
|
|
266
301
|
domain.degraded
|
|
@@ -428,6 +463,10 @@ if (page.pagination.has_more) {
|
|
|
428
463
|
}
|
|
429
464
|
```
|
|
430
465
|
|
|
466
|
+
Cursors are opaque and operation-specific. Return them unchanged to the same operation. Inbox and
|
|
467
|
+
reply-queue cursors are bound to their mailbox, time window, sort, and filters; omit those filters on
|
|
468
|
+
later pages or repeat them exactly.
|
|
469
|
+
|
|
431
470
|
Auto-paginate over all pages:
|
|
432
471
|
|
|
433
472
|
```ts
|
package/dist/index.cjs
CHANGED
|
@@ -624,7 +624,9 @@ var Mailboxes = class extends ApiResource {
|
|
|
624
624
|
folder_id: params?.folder_id,
|
|
625
625
|
folder_role: params?.folder_role,
|
|
626
626
|
search_text: params?.search_text,
|
|
627
|
-
|
|
627
|
+
cursor: params?.cursor,
|
|
628
|
+
after: params?.after,
|
|
629
|
+
before: params?.before,
|
|
628
630
|
limit: params?.limit,
|
|
629
631
|
has_keyword: params?.has_keyword,
|
|
630
632
|
not_keyword: params?.not_keyword
|
|
@@ -632,6 +634,29 @@ var Mailboxes = class extends ApiResource {
|
|
|
632
634
|
methodOptions: options
|
|
633
635
|
});
|
|
634
636
|
}
|
|
637
|
+
getInboxMessage(id, messageId, options) {
|
|
638
|
+
return this.client.request({
|
|
639
|
+
method: "GET",
|
|
640
|
+
path: `/mailboxes/${encodeURIComponent(id)}/inbox/messages/${encodeURIComponent(messageId)}`,
|
|
641
|
+
methodOptions: options
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
listInboxThreads(id, params, options) {
|
|
645
|
+
return this.client.request({
|
|
646
|
+
method: "GET",
|
|
647
|
+
path: `/mailboxes/${encodeURIComponent(id)}/inbox/threads`,
|
|
648
|
+
query: {
|
|
649
|
+
reply_state: params?.reply_state,
|
|
650
|
+
sort_by: params?.sort_by,
|
|
651
|
+
order: params?.order,
|
|
652
|
+
after: params?.after,
|
|
653
|
+
before: params?.before,
|
|
654
|
+
cursor: params?.cursor,
|
|
655
|
+
limit: params?.limit
|
|
656
|
+
},
|
|
657
|
+
methodOptions: options
|
|
658
|
+
});
|
|
659
|
+
}
|
|
635
660
|
getInboxThread(id, threadId, options) {
|
|
636
661
|
return this.client.request({
|
|
637
662
|
method: "GET",
|
|
@@ -639,6 +664,29 @@ var Mailboxes = class extends ApiResource {
|
|
|
639
664
|
methodOptions: options
|
|
640
665
|
});
|
|
641
666
|
}
|
|
667
|
+
updateInboxThreadReplyState(id, threadId, params, options) {
|
|
668
|
+
return this.client.request({
|
|
669
|
+
method: "PATCH",
|
|
670
|
+
path: `/mailboxes/${encodeURIComponent(id)}/inbox/threads/${encodeURIComponent(threadId)}`,
|
|
671
|
+
body: params,
|
|
672
|
+
methodOptions: options
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
createInboxReplyDraft(id, threadId, params, options) {
|
|
676
|
+
return this.client.request({
|
|
677
|
+
method: "POST",
|
|
678
|
+
path: `/mailboxes/${encodeURIComponent(id)}/inbox/threads/${encodeURIComponent(threadId)}/drafts`,
|
|
679
|
+
body: params,
|
|
680
|
+
methodOptions: options
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
sendInboxReplyDraft(id, threadId, draftId, options) {
|
|
684
|
+
return this.client.request({
|
|
685
|
+
method: "POST",
|
|
686
|
+
path: `/mailboxes/${encodeURIComponent(id)}/inbox/threads/${encodeURIComponent(threadId)}/drafts/${encodeURIComponent(draftId)}/send`,
|
|
687
|
+
methodOptions: options
|
|
688
|
+
});
|
|
689
|
+
}
|
|
642
690
|
replyToInboxMessage(id, messageId, params, options) {
|
|
643
691
|
return this.client.request({
|
|
644
692
|
method: "POST",
|
|
@@ -719,21 +767,6 @@ var Mailboxes = class extends ApiResource {
|
|
|
719
767
|
methodOptions: options
|
|
720
768
|
});
|
|
721
769
|
}
|
|
722
|
-
getRules(id, options) {
|
|
723
|
-
return this.client.request({
|
|
724
|
-
method: "GET",
|
|
725
|
-
path: `/mailboxes/${encodeURIComponent(id)}/rules`,
|
|
726
|
-
methodOptions: options
|
|
727
|
-
});
|
|
728
|
-
}
|
|
729
|
-
updateRules(id, params, options) {
|
|
730
|
-
return this.client.request({
|
|
731
|
-
method: "PUT",
|
|
732
|
-
path: `/mailboxes/${encodeURIComponent(id)}/rules`,
|
|
733
|
-
body: params,
|
|
734
|
-
methodOptions: options
|
|
735
|
-
});
|
|
736
|
-
}
|
|
737
770
|
listForwarding(id, options) {
|
|
738
771
|
return this.client.request({
|
|
739
772
|
method: "GET",
|
|
@@ -1097,6 +1130,33 @@ var Partner = class extends ApiResource {
|
|
|
1097
1130
|
}
|
|
1098
1131
|
};
|
|
1099
1132
|
|
|
1133
|
+
// src/resources/reply-scans.ts
|
|
1134
|
+
var ReplyScans = class extends ApiResource {
|
|
1135
|
+
create(params, options) {
|
|
1136
|
+
return this.client.request({
|
|
1137
|
+
method: "POST",
|
|
1138
|
+
path: "/reply-scans",
|
|
1139
|
+
body: params,
|
|
1140
|
+
methodOptions: options
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
get(id, options) {
|
|
1144
|
+
return this.client.request({
|
|
1145
|
+
method: "GET",
|
|
1146
|
+
path: `/reply-scans/${encodeURIComponent(id)}`,
|
|
1147
|
+
methodOptions: options
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
listResults(id, params, options) {
|
|
1151
|
+
return this.client.request({
|
|
1152
|
+
method: "GET",
|
|
1153
|
+
path: `/reply-scans/${encodeURIComponent(id)}/results`,
|
|
1154
|
+
query: { cursor: params?.cursor, limit: params?.limit },
|
|
1155
|
+
methodOptions: options
|
|
1156
|
+
});
|
|
1157
|
+
}
|
|
1158
|
+
};
|
|
1159
|
+
|
|
1100
1160
|
// src/resources/status.ts
|
|
1101
1161
|
var Status = class extends ApiResource {
|
|
1102
1162
|
get(options) {
|
|
@@ -1280,7 +1340,7 @@ var Webhooks = class extends ApiResource {
|
|
|
1280
1340
|
};
|
|
1281
1341
|
|
|
1282
1342
|
// src/version.ts
|
|
1283
|
-
var VERSION = "0.
|
|
1343
|
+
var VERSION = "0.3.0";
|
|
1284
1344
|
|
|
1285
1345
|
// src/client.ts
|
|
1286
1346
|
var DEFAULT_BASE_URL = "https://shipmail.to/api/v1";
|
|
@@ -1341,6 +1401,7 @@ var ShipMailClient = class {
|
|
|
1341
1401
|
this.messages = new Messages(this);
|
|
1342
1402
|
this.newsletters = new Newsletters(this);
|
|
1343
1403
|
this.partner = new Partner(this);
|
|
1404
|
+
this.replyScans = new ReplyScans(this);
|
|
1344
1405
|
this.suppressions = new Suppressions(this);
|
|
1345
1406
|
this.threads = new Threads(this);
|
|
1346
1407
|
this.webhooks = new Webhooks(this);
|
|
@@ -1451,7 +1512,7 @@ var WEBHOOK_EVENT_TYPES = [
|
|
|
1451
1512
|
"message.delivered",
|
|
1452
1513
|
"message.bounced",
|
|
1453
1514
|
"message.complained",
|
|
1454
|
-
"
|
|
1515
|
+
"thread.needs_reply",
|
|
1455
1516
|
"domain.verified",
|
|
1456
1517
|
"domain.verification_failed",
|
|
1457
1518
|
"domain.degraded",
|
|
@@ -1473,7 +1534,14 @@ var MESSAGE_STATUSES = [
|
|
|
1473
1534
|
"suppressed",
|
|
1474
1535
|
"cancelled"
|
|
1475
1536
|
];
|
|
1476
|
-
var MESSAGE_SOURCES = [
|
|
1537
|
+
var MESSAGE_SOURCES = [
|
|
1538
|
+
"api",
|
|
1539
|
+
"newsletter",
|
|
1540
|
+
"dashboard",
|
|
1541
|
+
"inbound",
|
|
1542
|
+
"smtp",
|
|
1543
|
+
"assistant"
|
|
1544
|
+
];
|
|
1477
1545
|
var WEBHOOK_DELIVERY_STATUSES = ["pending", "delivered", "failed"];
|
|
1478
1546
|
|
|
1479
1547
|
// src/webhook-verification.ts
|