shipmail-cli 0.6.2 → 0.6.4
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 +7 -2
- package/dist/cli.js +98 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -98,6 +98,7 @@ shipmail mailboxes sandbox-inbound mbx_123 --from customer@example.com --subject
|
|
|
98
98
|
|
|
99
99
|
# Read inbound mail
|
|
100
100
|
shipmail inbox list 550e8400-e29b-41d4-a716-446655440000 --folder-role inbox --after 2025-07-20T00:00:00Z --limit 25
|
|
101
|
+
shipmail inbox list 550e8400-e29b-41d4-a716-446655440000 --from billing@vendor.example --subject invoice --has-attachment
|
|
101
102
|
shipmail inbox message 550e8400-e29b-41d4-a716-446655440000 eml_123
|
|
102
103
|
shipmail inbox threads 550e8400-e29b-41d4-a716-446655440000 --attention-state needs_reply --after 2025-07-20T00:00:00Z --limit 50
|
|
103
104
|
shipmail inbox thread 550e8400-e29b-41d4-a716-446655440000 thr_123
|
|
@@ -137,7 +138,11 @@ shipmail newsletter-assets register-url https://cdn.shipmail.to/newsletter-image
|
|
|
137
138
|
# Manage webhooks
|
|
138
139
|
shipmail webhooks create \
|
|
139
140
|
--url https://example.com/shipmail/webhook \
|
|
140
|
-
--events message.received,message.bounced
|
|
141
|
+
--events message.received,message.bounced \
|
|
142
|
+
--authorization "Bearer your-endpoint-key"
|
|
143
|
+
shipmail webhooks update whk_123 --clear-authorization
|
|
144
|
+
shipmail webhooks update whk_123 --standard-webhooks-secret "whsec_..."
|
|
145
|
+
shipmail webhooks update whk_123 --clear-standard-webhooks-secret
|
|
141
146
|
shipmail webhooks deliveries whk_123 --status failed
|
|
142
147
|
shipmail webhooks replay-delivery whk_123 dlv_123 --idempotency-key replay-123
|
|
143
148
|
```
|
|
@@ -173,7 +178,7 @@ Use repeatable `--header "Name: value"` flags for request headers. Use `--output
|
|
|
173
178
|
- `messages send|list|analytics|get|reply` (test keys also support `--sandbox-outcome`)
|
|
174
179
|
- `scheduled-messages list|get|update|cancel`
|
|
175
180
|
- `mailboxes sandbox-inbound`
|
|
176
|
-
- `webhooks list|create|test|deliveries|replay-delivery`
|
|
181
|
+
- `webhooks list|create|update|test|deliveries|replay-delivery`
|
|
177
182
|
- `suppressions list|remove`
|
|
178
183
|
- `audiences list|create|get|update|delete`
|
|
179
184
|
- `audiences feed get|update|rotate|revoke`
|
package/dist/cli.js
CHANGED
|
@@ -649,7 +649,7 @@ async function login(options) {
|
|
|
649
649
|
}
|
|
650
650
|
|
|
651
651
|
// src/version.ts
|
|
652
|
-
var VERSION = "0.6.
|
|
652
|
+
var VERSION = "0.6.4";
|
|
653
653
|
|
|
654
654
|
// src/cli.ts
|
|
655
655
|
var DEFAULT_BASE_URL = "https://shipmail.to/api/v1";
|
|
@@ -1035,6 +1035,7 @@ async function newsletterCreateParams(options) {
|
|
|
1035
1035
|
const feed_entry_url = getString(options, "feed-entry-url");
|
|
1036
1036
|
const styling_mode = parseStylingMode(options);
|
|
1037
1037
|
const track_engagement = getBoolean(options, "track-engagement");
|
|
1038
|
+
const add_utm_tags = getBoolean(options, "add-utm-tags");
|
|
1038
1039
|
const preview_text = getString(options, "preview-text");
|
|
1039
1040
|
return {
|
|
1040
1041
|
audience_id,
|
|
@@ -1049,7 +1050,8 @@ async function newsletterCreateParams(options) {
|
|
|
1049
1050
|
...archive_visibility !== void 0 ? { archive_visibility } : {},
|
|
1050
1051
|
...feed_entry_url !== void 0 ? { feed_entry_url } : {},
|
|
1051
1052
|
...styling_mode !== void 0 ? { styling_mode } : {},
|
|
1052
|
-
...track_engagement !== void 0 ? { track_engagement } : {}
|
|
1053
|
+
...track_engagement !== void 0 ? { track_engagement } : {},
|
|
1054
|
+
...add_utm_tags !== void 0 ? { add_utm_tags } : {}
|
|
1053
1055
|
};
|
|
1054
1056
|
}
|
|
1055
1057
|
async function newsletterUpdateParams(options) {
|
|
@@ -1063,6 +1065,7 @@ async function newsletterUpdateParams(options) {
|
|
|
1063
1065
|
const feed_entry_url = getString(options, "feed-entry-url");
|
|
1064
1066
|
const styling_mode = parseStylingMode(options);
|
|
1065
1067
|
const track_engagement = getBoolean(options, "track-engagement");
|
|
1068
|
+
const add_utm_tags = getBoolean(options, "add-utm-tags");
|
|
1066
1069
|
const blocksInput = getString(options, "blocks");
|
|
1067
1070
|
const bodyHtmlInput = getString(options, "body-html");
|
|
1068
1071
|
const bodyTextInput = getString(options, "body-text");
|
|
@@ -1082,7 +1085,8 @@ async function newsletterUpdateParams(options) {
|
|
|
1082
1085
|
...archive_visibility !== void 0 ? { archive_visibility } : {},
|
|
1083
1086
|
...feed_entry_url !== void 0 ? { feed_entry_url } : {},
|
|
1084
1087
|
...styling_mode !== void 0 ? { styling_mode } : {},
|
|
1085
|
-
...track_engagement !== void 0 ? { track_engagement } : {}
|
|
1088
|
+
...track_engagement !== void 0 ? { track_engagement } : {},
|
|
1089
|
+
...add_utm_tags !== void 0 ? { add_utm_tags } : {}
|
|
1086
1090
|
};
|
|
1087
1091
|
if (Object.keys(params).length === 0) {
|
|
1088
1092
|
throw new CliUsageError("Provide at least one field to update.");
|
|
@@ -1202,7 +1206,7 @@ Usage:
|
|
|
1202
1206
|
shipmail mailboxes sandbox-inbound <id> --from sender@example.com --subject "Test" (--text "Hello" | --html "<p>Hello</p>") [--to support@example.com]
|
|
1203
1207
|
shipmail members list [--limit 25] [--cursor cur]
|
|
1204
1208
|
shipmail members get <id>
|
|
1205
|
-
shipmail inbox list <mailbox-id> [--folder-role inbox] [--search text] [--after ISO] [--before ISO] [--limit 25] [--cursor cur]
|
|
1209
|
+
shipmail inbox list <mailbox-id> [--folder-role inbox] [--search text] [--from text] [--to text] [--subject text] [--has-attachment [true|false]] [--after ISO] [--before ISO] [--limit 25] [--cursor cur]
|
|
1206
1210
|
shipmail inbox message <mailbox-id> <message-id>
|
|
1207
1211
|
shipmail inbox threads <mailbox-id> [--attention-state needs_reply] [--after ISO] [--before ISO] [--limit 25] [--cursor cur]
|
|
1208
1212
|
shipmail inbox thread <mailbox-id> <thread-id>
|
|
@@ -1227,7 +1231,8 @@ Usage:
|
|
|
1227
1231
|
shipmail reply-scans status <scan-id>
|
|
1228
1232
|
shipmail reply-scans results <scan-id> [--limit 25] [--cursor cur]
|
|
1229
1233
|
shipmail webhooks list
|
|
1230
|
-
shipmail webhooks create --url https://example.com/hook --events message.received,message.bounced
|
|
1234
|
+
shipmail webhooks create --url https://example.com/hook --events message.received,message.bounced [--authorization "Bearer key"] [--standard-webhooks-secret whsec_...] [--include-reply-text] [--authenticated-senders-only] [--allowed-sender jane@customer.com --allowed-sender customer.com]
|
|
1235
|
+
shipmail webhooks update <webhook-id> [--url https://example.com/hook] [--events message.received] [--description text] [--active true|false] [--authorization "Bearer key" | --clear-authorization] [--standard-webhooks-secret whsec_... | --clear-standard-webhooks-secret] [--include-reply-text true|false] [--authenticated-senders-only true|false] [--allowed-sender customer.com ... | --clear-allowed-senders]
|
|
1231
1236
|
shipmail webhooks replay-delivery <webhook-id> <delivery-id> [--idempotency-key key]
|
|
1232
1237
|
shipmail suppressions list
|
|
1233
1238
|
shipmail suppressions remove <email>
|
|
@@ -1237,8 +1242,8 @@ Usage:
|
|
|
1237
1242
|
--name "July changelog" \\
|
|
1238
1243
|
--subject "What shipped in July" \\
|
|
1239
1244
|
--blocks @blocks.json \\
|
|
1240
|
-
[--feed-entry-url https://example.com/post] [--styling-mode styled|plain] [--track-engagement true|false]
|
|
1241
|
-
shipmail newsletters update nws_789 --subject "Updated subject" --blocks @blocks-v2.json [--feed-entry-url https://example.com/post] [--styling-mode styled|plain] [--track-engagement true|false]
|
|
1245
|
+
[--feed-entry-url https://example.com/post] [--styling-mode styled|plain] [--track-engagement true|false] [--add-utm-tags true|false]
|
|
1246
|
+
shipmail newsletters update nws_789 --subject "Updated subject" --blocks @blocks-v2.json [--feed-entry-url https://example.com/post] [--styling-mode styled|plain] [--track-engagement true|false] [--add-utm-tags true|false]
|
|
1242
1247
|
shipmail newsletters preview <id>
|
|
1243
1248
|
shipmail newsletters preflight <id>
|
|
1244
1249
|
shipmail newsletters test-send <id> --recipient-email owner@example.com
|
|
@@ -1296,6 +1301,7 @@ Newsletter styling:
|
|
|
1296
1301
|
|
|
1297
1302
|
Newsletter tracking:
|
|
1298
1303
|
--track-engagement <true|false> Track opens and clicks for this issue. Off by default. Changes only while the issue is a draft or scheduled for later.
|
|
1304
|
+
--add-utm-tags <true|false> Add utm_source, utm_medium and utm_campaign to the issue's links in the email and the feed. Off by default. Changes only while the issue is a draft or scheduled for later.
|
|
1299
1305
|
|
|
1300
1306
|
Newsletter block prose:
|
|
1301
1307
|
Paragraph, quote, callout, list-item, and column bodies accept bare text or sanitized inline HTML. Use <p> and <br> for line breaks.
|
|
@@ -1346,11 +1352,22 @@ function requirePositional(positional, index, label) {
|
|
|
1346
1352
|
if (!value) throw new CliUsageError(`Missing ${label}.`);
|
|
1347
1353
|
return value;
|
|
1348
1354
|
}
|
|
1355
|
+
function inboxTextFilters(options) {
|
|
1356
|
+
const from = getString(options, "from");
|
|
1357
|
+
const to = getString(options, "to");
|
|
1358
|
+
const subject = getString(options, "subject");
|
|
1359
|
+
return {
|
|
1360
|
+
...from ? { from } : {},
|
|
1361
|
+
...to ? { to } : {},
|
|
1362
|
+
...subject ? { subject } : {}
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1349
1365
|
function inboxListParams(options) {
|
|
1350
1366
|
const params = {};
|
|
1351
1367
|
const folderId = getString(options, "folder-id");
|
|
1352
1368
|
const folderRole = getString(options, "folder-role");
|
|
1353
1369
|
const searchText = getString(options, "search");
|
|
1370
|
+
const hasAttachment = getBoolean(options, "has-attachment");
|
|
1354
1371
|
const cursor = getString(options, "cursor");
|
|
1355
1372
|
const after = getString(options, "after");
|
|
1356
1373
|
const before = getString(options, "before");
|
|
@@ -1360,6 +1377,8 @@ function inboxListParams(options) {
|
|
|
1360
1377
|
if (folderId) params.folder_id = folderId;
|
|
1361
1378
|
if (folderRole) params.folder_role = folderRole;
|
|
1362
1379
|
if (searchText) params.search_text = searchText;
|
|
1380
|
+
Object.assign(params, inboxTextFilters(options));
|
|
1381
|
+
if (hasAttachment !== void 0) params.has_attachment = hasAttachment;
|
|
1363
1382
|
if (cursor) params.cursor = cursor;
|
|
1364
1383
|
if (after) params.after = after;
|
|
1365
1384
|
if (before) params.before = before;
|
|
@@ -1380,6 +1399,59 @@ function webhookEvents(options) {
|
|
|
1380
1399
|
}
|
|
1381
1400
|
return events;
|
|
1382
1401
|
}
|
|
1402
|
+
function webhookWriteOnlyOption(options, name) {
|
|
1403
|
+
const value = optionValue(options, name);
|
|
1404
|
+
if (value === void 0) return void 0;
|
|
1405
|
+
if (typeof value === "boolean") throw new CliUsageError(`Missing value for --${name}.`);
|
|
1406
|
+
return getString(options, name);
|
|
1407
|
+
}
|
|
1408
|
+
function webhookWriteOnlyUpdate(options, name) {
|
|
1409
|
+
const value = webhookWriteOnlyOption(options, name);
|
|
1410
|
+
const clear = getBoolean(options, `clear-${name}`) === true;
|
|
1411
|
+
if (value !== void 0 && clear) {
|
|
1412
|
+
throw new CliUsageError(`Use --${name} or --clear-${name}, not both.`);
|
|
1413
|
+
}
|
|
1414
|
+
return clear ? null : value;
|
|
1415
|
+
}
|
|
1416
|
+
function webhookAllowedSenders(options) {
|
|
1417
|
+
const value = optionValue(options, "allowed-sender");
|
|
1418
|
+
if (value === void 0) return void 0;
|
|
1419
|
+
if (typeof value === "boolean") throw new CliUsageError("Missing value for --allowed-sender.");
|
|
1420
|
+
return getStringList(options, "allowed-sender");
|
|
1421
|
+
}
|
|
1422
|
+
function webhookAllowedSendersUpdate(options) {
|
|
1423
|
+
const senders = webhookAllowedSenders(options);
|
|
1424
|
+
const clear = getBoolean(options, "clear-allowed-senders") === true;
|
|
1425
|
+
if (senders !== void 0 && clear) {
|
|
1426
|
+
throw new CliUsageError("Use --allowed-sender or --clear-allowed-senders, not both.");
|
|
1427
|
+
}
|
|
1428
|
+
return clear ? null : senders;
|
|
1429
|
+
}
|
|
1430
|
+
function webhookUpdateParams(options) {
|
|
1431
|
+
const authorization = webhookWriteOnlyUpdate(options, "authorization");
|
|
1432
|
+
const standardWebhooksSecret = webhookWriteOnlyUpdate(options, "standard-webhooks-secret");
|
|
1433
|
+
const url = getString(options, "url");
|
|
1434
|
+
const description = getString(options, "description");
|
|
1435
|
+
const active = getBoolean(options, "active");
|
|
1436
|
+
const includeReplyText = getBoolean(options, "include-reply-text");
|
|
1437
|
+
const authenticatedSendersOnly = getBoolean(options, "authenticated-senders-only");
|
|
1438
|
+
const allowedSenders = webhookAllowedSendersUpdate(options);
|
|
1439
|
+
const params = {
|
|
1440
|
+
...url !== void 0 ? { url } : {},
|
|
1441
|
+
...optionValue(options, "events") !== void 0 ? { events: webhookEvents(options) } : {},
|
|
1442
|
+
...description !== void 0 ? { description } : {},
|
|
1443
|
+
...active !== void 0 ? { active } : {},
|
|
1444
|
+
...authorization !== void 0 ? { authorization } : {},
|
|
1445
|
+
...standardWebhooksSecret !== void 0 ? { standard_webhooks_secret: standardWebhooksSecret } : {},
|
|
1446
|
+
...includeReplyText !== void 0 ? { include_reply_text: includeReplyText } : {},
|
|
1447
|
+
...authenticatedSendersOnly !== void 0 ? { authenticated_senders_only: authenticatedSendersOnly } : {},
|
|
1448
|
+
...allowedSenders !== void 0 ? { allowed_senders: allowedSenders } : {}
|
|
1449
|
+
};
|
|
1450
|
+
if (Object.keys(params).length === 0) {
|
|
1451
|
+
throw new CliUsageError("Nothing to update. Pass at least one webhook option.");
|
|
1452
|
+
}
|
|
1453
|
+
return params;
|
|
1454
|
+
}
|
|
1383
1455
|
function webhookDeliveryParams(options) {
|
|
1384
1456
|
const status = getString(options, "status");
|
|
1385
1457
|
const eventType = getString(options, "event-type");
|
|
@@ -2170,16 +2242,34 @@ async function runWebhooks(client, parsed, out) {
|
|
|
2170
2242
|
}
|
|
2171
2243
|
if (subcommand === "create") {
|
|
2172
2244
|
const description = getString(parsed.options, "description");
|
|
2245
|
+
const authorization = webhookWriteOnlyOption(parsed.options, "authorization");
|
|
2246
|
+
const standardWebhooksSecret = webhookWriteOnlyOption(
|
|
2247
|
+
parsed.options,
|
|
2248
|
+
"standard-webhooks-secret"
|
|
2249
|
+
);
|
|
2250
|
+
const includeReplyText = getBoolean(parsed.options, "include-reply-text");
|
|
2251
|
+
const authenticatedSendersOnly = getBoolean(parsed.options, "authenticated-senders-only");
|
|
2252
|
+
const allowedSenders = webhookAllowedSenders(parsed.options);
|
|
2173
2253
|
writeJson(
|
|
2174
2254
|
out,
|
|
2175
2255
|
await client.webhooks.create({
|
|
2176
2256
|
url: getRequiredString(parsed.options, "url"),
|
|
2177
2257
|
events: webhookEvents(parsed.options),
|
|
2178
|
-
...description ? { description } : {}
|
|
2258
|
+
...description ? { description } : {},
|
|
2259
|
+
...authorization !== void 0 ? { authorization } : {},
|
|
2260
|
+
...standardWebhooksSecret !== void 0 ? { standard_webhooks_secret: standardWebhooksSecret } : {},
|
|
2261
|
+
...includeReplyText !== void 0 ? { include_reply_text: includeReplyText } : {},
|
|
2262
|
+
...authenticatedSendersOnly !== void 0 ? { authenticated_senders_only: authenticatedSendersOnly } : {},
|
|
2263
|
+
...allowedSenders !== void 0 ? { allowed_senders: allowedSenders } : {}
|
|
2179
2264
|
})
|
|
2180
2265
|
);
|
|
2181
2266
|
return;
|
|
2182
2267
|
}
|
|
2268
|
+
if (subcommand === "update") {
|
|
2269
|
+
const webhookId = requirePositional(parsed.positional, 2, "webhook id");
|
|
2270
|
+
writeJson(out, await client.webhooks.update(webhookId, webhookUpdateParams(parsed.options)));
|
|
2271
|
+
return;
|
|
2272
|
+
}
|
|
2183
2273
|
if (subcommand === "test") {
|
|
2184
2274
|
writeJson(
|
|
2185
2275
|
out,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shipmail-cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "Official CLI for the Shipmail API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"shipmail": "0.6.
|
|
44
|
+
"shipmail": "0.6.5",
|
|
45
45
|
"zod": "^4.6.5"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|