@letterstory/cli 0.61.0 → 0.61.1
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/lib/cli.mjs +5 -2
- package/lib/commands/outbound.mjs +29 -2
- package/package.json +1 -1
package/lib/cli.mjs
CHANGED
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
} from "./commands.mjs";
|
|
56
56
|
|
|
57
57
|
// Keep in sync with cli/package.json.
|
|
58
|
-
export const VERSION = "0.61.
|
|
58
|
+
export const VERSION = "0.61.1";
|
|
59
59
|
|
|
60
60
|
// Flags that never take a value. Listing them explicitly means `deploy get --json <id>`
|
|
61
61
|
// can't accidentally swallow the id as --json's value.
|
|
@@ -807,10 +807,13 @@ Sequences (multi-step cold email sent from your mailers; approving or enrolling
|
|
|
807
807
|
sequences get <sequence-id> Flow, enrollments, who replied at each step
|
|
808
808
|
sequences create --name <n> (--flow '<json>'|--flow-file <path>) [--mailer <mailer-id>]...
|
|
809
809
|
[--[no-]opt-out-footer] [--[no-]postal-address-footer] [--[no-]unsubscribe-links] [--[no-]detect-reply-opt-outs]
|
|
810
|
-
|
|
810
|
+
[--send-window-start <HH:MM>] [--send-window-end <HH:MM>] [--send-window-timezone <IANA tz>]
|
|
811
|
+
New draft sequence (nothing sends yet; rails default on, opt-out line off;
|
|
812
|
+
sends 9:00-17:00 in each recipient's inferred timezone, else the sender's)
|
|
811
813
|
sequences update <sequence-id> [--name <n>] [--flow '<json>'|--flow-file <path>]
|
|
812
814
|
[--status draft|active|paused|archived] [--mailer <mailer-id>]...
|
|
813
815
|
[--[no-]opt-out-footer] [--[no-]postal-address-footer] [--[no-]unsubscribe-links] [--[no-]detect-reply-opt-outs]
|
|
816
|
+
[--send-window-start <HH:MM>] [--send-window-end <HH:MM>] [--send-window-timezone <IANA tz>]
|
|
814
817
|
sequences pause|resume <sequence-id> Stop / restart sending
|
|
815
818
|
sequences enroll <sequence-id> (--list <list-id> | --email <addr>... | --recipients '<json>'|--recipients-file <path>)
|
|
816
819
|
sequences stop <sequence-id> <enrollment-id> Stop one recipient
|
|
@@ -60,6 +60,31 @@ const SEQUENCE_RAIL_ARGS = {
|
|
|
60
60
|
unsubscribe_links: { flag: "unsubscribe-links", type: "bool", negate: "no-unsubscribe-links" },
|
|
61
61
|
detect_reply_opt_outs: { flag: "detect-reply-opt-outs", type: "bool", negate: "no-detect-reply-opt-outs" },
|
|
62
62
|
};
|
|
63
|
+
|
|
64
|
+
// A send-window edge from --<flag> HH:MM (or a raw minute of day) → the
|
|
65
|
+
// schema's minute-of-day number.
|
|
66
|
+
function windowMinute(flag) {
|
|
67
|
+
return (flags) => {
|
|
68
|
+
const raw = flagStr(flags[flag]);
|
|
69
|
+
if (raw === undefined) return undefined;
|
|
70
|
+
if (/^\d+$/.test(raw)) return Number(raw);
|
|
71
|
+
const match = /^(\d{1,2}):(\d{2})$/.exec(raw);
|
|
72
|
+
if (!match || Number(match[1]) > 23 || Number(match[2]) > 59) {
|
|
73
|
+
throw new CliError(`--${flag} takes HH:MM or a minute of day 0–1439 (got ${raw})`);
|
|
74
|
+
}
|
|
75
|
+
return Number(match[1]) * 60 + Number(match[2]);
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// The send window, shared by create and update: when emails may go out
|
|
80
|
+
// (default 9:00–17:00), in each recipient's inferred timezone, falling back to
|
|
81
|
+
// the sender's --send-window-timezone when the location is unknown. Equal
|
|
82
|
+
// start and end turns the window off.
|
|
83
|
+
const SEQUENCE_WINDOW_ARGS = {
|
|
84
|
+
send_window_start_minute: { value: windowMinute("send-window-start") },
|
|
85
|
+
send_window_end_minute: { value: windowMinute("send-window-end") },
|
|
86
|
+
send_window_timezone: "send-window-timezone",
|
|
87
|
+
};
|
|
63
88
|
const PROSPECT_STATUSES = ["new", "contacted", "replied", "unsubscribed", "archived"];
|
|
64
89
|
const mailerIds = {
|
|
65
90
|
value: (flags) => {
|
|
@@ -101,6 +126,7 @@ export const ARGS = {
|
|
|
101
126
|
},
|
|
102
127
|
mailer_ids: mailerIds,
|
|
103
128
|
...SEQUENCE_RAIL_ARGS,
|
|
129
|
+
...SEQUENCE_WINDOW_ARGS,
|
|
104
130
|
},
|
|
105
131
|
update_sequence: {
|
|
106
132
|
sequence_id: { positional: 0, label: "sequence-id", required: true },
|
|
@@ -109,6 +135,7 @@ export const ARGS = {
|
|
|
109
135
|
status: { flag: "status", enum: SEQUENCE_STATUSES },
|
|
110
136
|
mailer_ids: mailerIds,
|
|
111
137
|
...SEQUENCE_RAIL_ARGS,
|
|
138
|
+
...SEQUENCE_WINDOW_ARGS,
|
|
112
139
|
},
|
|
113
140
|
enroll_in_sequence: {
|
|
114
141
|
sequence_id: { positional: 0, label: "sequence-id", required: true },
|
|
@@ -260,8 +287,8 @@ export const ARGS = {
|
|
|
260
287
|
|
|
261
288
|
// Flags the computed `value` sources read (refuseUnknownFlags can't see them).
|
|
262
289
|
const VALUE_FLAGS = {
|
|
263
|
-
create_sequence: ["flow", "flow-file", "mailer"],
|
|
264
|
-
update_sequence: ["flow", "flow-file", "mailer"],
|
|
290
|
+
create_sequence: ["flow", "flow-file", "mailer", "send-window-start", "send-window-end"],
|
|
291
|
+
update_sequence: ["flow", "flow-file", "mailer", "send-window-start", "send-window-end"],
|
|
265
292
|
enroll_in_sequence: ["recipients", "recipients-file", "email"],
|
|
266
293
|
update_review_item: ["body", "file"],
|
|
267
294
|
import_prospects_csv: ["csv", "csv-file"],
|