@drawbridge/drawbridge-utils 0.0.162 → 0.0.164
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/dist/connections/index.cjs +105 -8
- package/dist/connections/index.d.cts +104 -4
- package/dist/connections/index.d.ts +104 -4
- package/dist/connections/index.js +105 -8
- package/dist/html.cjs +5 -2
- package/dist/html.d.cts +20 -1
- package/dist/html.d.ts +20 -1
- package/dist/html.js +3 -1
- package/dist/index.cjs +34 -1
- package/dist/index.d.cts +34 -1
- package/dist/index.d.ts +34 -1
- package/dist/index.js +34 -1
- package/dist/notification.cjs +84 -20
- package/dist/notification.d.cts +117 -34
- package/dist/notification.d.ts +117 -34
- package/dist/notification.js +82 -20
- package/dist/providers.cjs +137 -17
- package/dist/providers.d.cts +104 -12
- package/dist/providers.d.ts +104 -12
- package/dist/providers.js +133 -16
- package/package.json +1 -1
|
@@ -634,10 +634,15 @@ var attentive_default2 = {
|
|
|
634
634
|
"Attentive accepts these updates and applies them in the background, so a contact appears in your segment shortly after the sync rather than the instant it runs."
|
|
635
635
|
],
|
|
636
636
|
excerpt: "Sync your Drawbridge contacts into an Attentive segment.",
|
|
637
|
+
// NAMES THE SEGMENT STEP, because `status` below gates on it: a grant with
|
|
638
|
+
// no segment chosen sits at Pending, and a guide that stops at the consent
|
|
639
|
+
// leaves a merchant looking at a connection they think is broken. Same
|
|
640
|
+
// omission Klaviyo's guide already carries a note about.
|
|
637
641
|
guide: [
|
|
638
642
|
"Press Connect. Drawbridge sends you to Attentive to approve access.",
|
|
639
643
|
"Sign in to Attentive if you are not already, and authorize the permissions listed.",
|
|
640
|
-
"You
|
|
644
|
+
"You come back here to choose which Attentive segment your contacts should sync into.",
|
|
645
|
+
"The connection shows Pending until you choose a segment, then Active."
|
|
641
646
|
]
|
|
642
647
|
},
|
|
643
648
|
// A contact destination, like Klaviyo and Mailchimp — a merchant could
|
|
@@ -900,6 +905,9 @@ var attentive_default2 = {
|
|
|
900
905
|
// merchant would recognise in a builder label.
|
|
901
906
|
key: "Sync contact to Attentive",
|
|
902
907
|
queue: "connection",
|
|
908
|
+
// Attentive applies the update in the background and returns no id we
|
|
909
|
+
// could hand on, so there is nothing for a later step to interpolate.
|
|
910
|
+
returns: [],
|
|
903
911
|
// Nothing for a merchant to configure on the step itself — the segment
|
|
904
912
|
// is chosen once on the connection. Declared empty rather than omitted,
|
|
905
913
|
// so "this step takes no settings" and "nobody thought about settings"
|
|
@@ -2127,13 +2135,18 @@ var drawbridge_default2 = {
|
|
|
2127
2135
|
request: request2,
|
|
2128
2136
|
response: { count, notified: recipients.length },
|
|
2129
2137
|
writes: recipients.map((member) => {
|
|
2130
|
-
var _a2, _b2;
|
|
2138
|
+
var _a2, _b2, _c2;
|
|
2131
2139
|
return queueNotification({
|
|
2132
2140
|
audience: "member",
|
|
2133
2141
|
message: interpolate((_a2 = step.settings) == null ? void 0 : _a2.message, values),
|
|
2134
2142
|
organization: workflow.organization,
|
|
2135
2143
|
send: { type: "email", email: member.email },
|
|
2136
|
-
|
|
2144
|
+
// The editor's plain rendering, interpolated the same way so
|
|
2145
|
+
// {{count}} resolves in the text part too. Spread rather than
|
|
2146
|
+
// written as null: a step saved before `text` existed has none,
|
|
2147
|
+
// and the send path strips the markup itself for those.
|
|
2148
|
+
...((_b2 = step.settings) == null ? void 0 : _b2.text) && { text: interpolate(step.settings.text, values) },
|
|
2149
|
+
title: interpolate((_c2 = step.settings) == null ? void 0 : _c2.subject, values),
|
|
2137
2150
|
workflow: workflow.id
|
|
2138
2151
|
});
|
|
2139
2152
|
})
|
|
@@ -2202,7 +2215,7 @@ var drawbridge_default2 = {
|
|
|
2202
2215
|
// unsubscribe token and the CAN-SPAM footer. The step's job is to say who
|
|
2203
2216
|
// and what, correctly, and to refuse early when it must not send at all.
|
|
2204
2217
|
send: async ({ context, step, workflow }, { canSend, read } = {}) => {
|
|
2205
|
-
var _a, _b;
|
|
2218
|
+
var _a, _b, _c;
|
|
2206
2219
|
const to = context == null ? void 0 : context.email;
|
|
2207
2220
|
if (!to) throw new Error("No email address on context (context.email is required)");
|
|
2208
2221
|
const request2 = { to };
|
|
@@ -2239,7 +2252,11 @@ var drawbridge_default2 = {
|
|
|
2239
2252
|
message: interpolate((_a = step.settings) == null ? void 0 : _a.message, context),
|
|
2240
2253
|
organization: workflow.organization,
|
|
2241
2254
|
send: { type: "email", email: to },
|
|
2242
|
-
|
|
2255
|
+
// The editor's plain rendering, so the text/plain part of this
|
|
2256
|
+
// email is what the merchant wrote rather than a regex's guess at
|
|
2257
|
+
// it. See the digest above for why it is spread, not nulled.
|
|
2258
|
+
...((_b = step.settings) == null ? void 0 : _b.text) && { text: interpolate(step.settings.text, context) },
|
|
2259
|
+
title: interpolate((_c = step.settings) == null ? void 0 : _c.subject, context),
|
|
2243
2260
|
workflow: workflow.id
|
|
2244
2261
|
})
|
|
2245
2262
|
]
|
|
@@ -2659,6 +2676,11 @@ var drawbridge_default2 = {
|
|
|
2659
2676
|
hook: "email.digest",
|
|
2660
2677
|
key: "Email \u2014 Digest",
|
|
2661
2678
|
queue: "notification",
|
|
2679
|
+
// Nothing for a later step to interpolate. Declared empty rather than
|
|
2680
|
+
// omitted, so "this step leaves nothing behind" and "nobody thought
|
|
2681
|
+
// about it" stay different statements — the second is what emptied the
|
|
2682
|
+
// builder's Variables menu for every step in the product.
|
|
2683
|
+
returns: [],
|
|
2662
2684
|
settings: {
|
|
2663
2685
|
// The organization OWNER is always a recipient, resolved by the
|
|
2664
2686
|
// hook, so this is additional recipients rather than the list. It
|
|
@@ -2667,7 +2689,22 @@ var drawbridge_default2 = {
|
|
|
2667
2689
|
// pick and could never save the step.
|
|
2668
2690
|
members: { of: "string", type: "array" },
|
|
2669
2691
|
message: { max: 2e3, required: true, type: "string" },
|
|
2670
|
-
|
|
2692
|
+
// THE LAST SPAM CHECK, stored beside the copy it measured. Shape is
|
|
2693
|
+
// pinned no further than the pair that proves the match, which is the
|
|
2694
|
+
// only part the api reads; the rest is SpamAssassin's own output and
|
|
2695
|
+
// is stored as it arrives. Same declaration the campaign's draw
|
|
2696
|
+
// notification validates against.
|
|
2697
|
+
//
|
|
2698
|
+
// Undeclared, this was silently dropped at submit — the settings
|
|
2699
|
+
// validator is noUnknown().strict(), so the dashboard's step form
|
|
2700
|
+
// mapped the key away rather than 400 — and every open of a workflow
|
|
2701
|
+
// step re-ran a check against a free service to be told what the last
|
|
2702
|
+
// open had already been told.
|
|
2703
|
+
score: { shape: { message: { type: "string" }, subject: { type: "string" } }, type: "object" },
|
|
2704
|
+
subject: { max: 150, required: true, type: "string" },
|
|
2705
|
+
// The editor's plain rendering of `message`, written beside it rather
|
|
2706
|
+
// than reconstructed by running a regex over the markup at send time.
|
|
2707
|
+
text: { max: 2e3, type: "string" }
|
|
2671
2708
|
},
|
|
2672
2709
|
triggers: ["schedule.day", "schedule.week", "schedule.month"],
|
|
2673
2710
|
usage: { actions: 0 }
|
|
@@ -2688,6 +2725,7 @@ var drawbridge_default2 = {
|
|
|
2688
2725
|
hook: "email.notify",
|
|
2689
2726
|
key: "Email \u2014 Notification",
|
|
2690
2727
|
queue: "notification",
|
|
2728
|
+
returns: [],
|
|
2691
2729
|
settings: {
|
|
2692
2730
|
members: { of: "string", type: "array" },
|
|
2693
2731
|
message: { max: 2e3, type: "string" },
|
|
@@ -2704,9 +2742,14 @@ var drawbridge_default2 = {
|
|
|
2704
2742
|
hook: "email.send",
|
|
2705
2743
|
key: "Email \u2014 Send email",
|
|
2706
2744
|
queue: "notification",
|
|
2745
|
+
returns: [],
|
|
2707
2746
|
settings: {
|
|
2708
2747
|
message: { max: 2e3, required: true, type: "string" },
|
|
2709
|
-
|
|
2748
|
+
// See email.digest above — the last spam check, and the editor's
|
|
2749
|
+
// plain rendering of the message.
|
|
2750
|
+
score: { shape: { message: { type: "string" }, subject: { type: "string" } }, type: "object" },
|
|
2751
|
+
subject: { max: 150, required: true, type: "string" },
|
|
2752
|
+
text: { max: 2e3, type: "string" }
|
|
2710
2753
|
},
|
|
2711
2754
|
triggers: ["lead.insert"],
|
|
2712
2755
|
// ONE SOURCE FOR THE PRICE. lib/pricing.js is the index of every
|
|
@@ -3305,6 +3348,13 @@ var klaviyo_default2 = {
|
|
|
3305
3348
|
// than a label that could be any of their Klaviyo accounts.
|
|
3306
3349
|
key: "Sync contact to " + (((_a = data2 == null ? void 0 : data2.settings) == null ? void 0 : _a.account) || "Klaviyo"),
|
|
3307
3350
|
queue: "connection",
|
|
3351
|
+
// The key the hook puts in `context`, which the runner merges into the
|
|
3352
|
+
// run so a later step can interpolate {{klaviyoProfileId}}. Declared
|
|
3353
|
+
// beside the hook that writes it — see the note on Shopify's
|
|
3354
|
+
// commerce.code, which is where this came back from.
|
|
3355
|
+
returns: [
|
|
3356
|
+
{ key: "klaviyoProfileId", label: "Klaviyo Profile ID" }
|
|
3357
|
+
],
|
|
3308
3358
|
// Nothing for a merchant to configure on the step itself — the list
|
|
3309
3359
|
// is chosen once on the connection. Declared empty rather than
|
|
3310
3360
|
// omitted, so "this step takes no settings" and "nobody thought about
|
|
@@ -3420,10 +3470,15 @@ var mailchimp_default2 = {
|
|
|
3420
3470
|
"Someone who unsubscribed inside Mailchimp keeps that choice: a resync only sets the status of a subscriber Mailchimp has never seen before."
|
|
3421
3471
|
],
|
|
3422
3472
|
excerpt: "Sync your Drawbridge contacts into a Mailchimp audience.",
|
|
3473
|
+
// NAMES THE AUDIENCE STEP, because `status` below gates on it: a grant with
|
|
3474
|
+
// no audience chosen sits at Pending, and a guide that stops at the consent
|
|
3475
|
+
// leaves a merchant looking at a connection they think is broken.
|
|
3423
3476
|
guide: [
|
|
3424
3477
|
"Press Connect. Drawbridge sends you to Mailchimp to approve access.",
|
|
3425
3478
|
"Sign in to Mailchimp if you are not already, and choose the account to connect.",
|
|
3426
|
-
"You come back here to pick the audience your contacts should sync into."
|
|
3479
|
+
"You come back here to pick the audience your contacts should sync into.",
|
|
3480
|
+
"The connection shows Pending until you pick an audience, then Active.",
|
|
3481
|
+
"You can remove Drawbridge at any time from the Authorized Apps page in your Mailchimp account."
|
|
3427
3482
|
]
|
|
3428
3483
|
},
|
|
3429
3484
|
// Mailchimp and SendGrid shared a group while they were SENDERS, where an org
|
|
@@ -3665,6 +3720,11 @@ var mailchimp_default2 = {
|
|
|
3665
3720
|
// than showing a string like a1b2c3d4e5.
|
|
3666
3721
|
key: "Sync contact to Mailchimp",
|
|
3667
3722
|
queue: "connection",
|
|
3723
|
+
// The key the hook puts in `context`, for a later step to interpolate
|
|
3724
|
+
// as {{mailchimpMemberId}}. Same reasoning as Klaviyo's.
|
|
3725
|
+
returns: [
|
|
3726
|
+
{ key: "mailchimpMemberId", label: "Mailchimp Member ID" }
|
|
3727
|
+
],
|
|
3668
3728
|
// Nothing for a merchant to configure on the step itself — the audience
|
|
3669
3729
|
// is chosen once on the connection. Declared empty rather than omitted,
|
|
3670
3730
|
// so "this step takes no settings" and "nobody thought about settings"
|
|
@@ -4926,6 +4986,24 @@ var shopify_default2 = {
|
|
|
4926
4986
|
hook: "commerce.code",
|
|
4927
4987
|
key: "Issue a discount code",
|
|
4928
4988
|
queue: "connection",
|
|
4989
|
+
// WHAT THIS STEP LEAVES BEHIND FOR THE ONES AFTER IT, and the only
|
|
4990
|
+
// reason the builder can offer a Variables menu.
|
|
4991
|
+
//
|
|
4992
|
+
// These are the exact keys the hook puts in `context` — the runner
|
|
4993
|
+
// merges that into the run's context, and a later step interpolates
|
|
4994
|
+
// {{shopifyDiscountCode}} out of it. Declared beside the hook that
|
|
4995
|
+
// writes them so the two cannot drift; there is nowhere else that
|
|
4996
|
+
// knows both.
|
|
4997
|
+
//
|
|
4998
|
+
// They existed as a hand-written list in the api's workflow catalog
|
|
4999
|
+
// until it was derived from these manifests, and the derivation
|
|
5000
|
+
// hardcoded `returns : []` for every step. Nothing has offered a
|
|
5001
|
+
// variable since — an email step after a discount step had no way to
|
|
5002
|
+
// name the code it was supposed to send.
|
|
5003
|
+
returns: [
|
|
5004
|
+
{ key: "shopifyDiscountCode", label: "Shopify Discount Code" },
|
|
5005
|
+
{ key: "shopifyDiscountId", label: "Shopify Discount ID" }
|
|
5006
|
+
],
|
|
4929
5007
|
settings: {
|
|
4930
5008
|
discount: {
|
|
4931
5009
|
required: true,
|
|
@@ -4944,6 +5022,12 @@ var shopify_default2 = {
|
|
|
4944
5022
|
hook: "commerce.customer",
|
|
4945
5023
|
key: "Create customer",
|
|
4946
5024
|
queue: "connection",
|
|
5025
|
+
// Written on every path the hook can take — created, reused from an
|
|
5026
|
+
// earlier step, or reused from the lead — so a later step can rely on
|
|
5027
|
+
// it being there whenever this one succeeded.
|
|
5028
|
+
returns: [
|
|
5029
|
+
{ key: "shopifyCustomerId", label: "Shopify Customer ID" }
|
|
5030
|
+
],
|
|
4947
5031
|
settings: {},
|
|
4948
5032
|
triggers: ["lead.insert"],
|
|
4949
5033
|
usage: { actions: 1 }
|
|
@@ -5341,6 +5425,13 @@ var webhook_default = {
|
|
|
5341
5425
|
hook: "webhook.send",
|
|
5342
5426
|
key: "Send webhook",
|
|
5343
5427
|
queue: "webhook",
|
|
5428
|
+
// The receiver's response is buffered, not merged into the run — a
|
|
5429
|
+
// receiver owes us a status, not a document — so there is nothing here
|
|
5430
|
+
// for a later step to interpolate. Declared empty rather than omitted:
|
|
5431
|
+
// "leaves nothing behind" and "nobody thought about it" are different
|
|
5432
|
+
// statements, and the second one is what emptied the builder's
|
|
5433
|
+
// Variables menu for every step in the product.
|
|
5434
|
+
returns: [],
|
|
5344
5435
|
settings: {
|
|
5345
5436
|
url: { format: "url", required: true, type: "string" }
|
|
5346
5437
|
},
|
|
@@ -5717,6 +5808,12 @@ var publicConnectionKeys = Object.freeze([
|
|
|
5717
5808
|
// excerpt, guide, and any vendor redirect copy.
|
|
5718
5809
|
"content",
|
|
5719
5810
|
"createdAt",
|
|
5811
|
+
// THE MERCHANT'S OWN SWITCH. `enabled : false` is a connection the merchant
|
|
5812
|
+
// paused — kept, configured, and not run — as distinct from a vendor the
|
|
5813
|
+
// platform switched off (which the api overlays as an error). Absent means
|
|
5814
|
+
// on; the dashboard renders Paused from it and the sync gates refuse a paused
|
|
5815
|
+
// connection the way they refuse a missing one.
|
|
5816
|
+
"enabled",
|
|
5720
5817
|
// The connection DOCUMENT's own errors array — scope-drift entries written by
|
|
5721
5818
|
// drawbridge-sync. NOT the manifest's error copy, which is content.errors:
|
|
5722
5819
|
// the document is spread OVER the resolved manifest downstream, so the two
|
|
@@ -914,10 +914,15 @@ var attentive = {
|
|
|
914
914
|
'Attentive accepts these updates and applies them in the background, so a contact appears in your segment shortly after the sync rather than the instant it runs.'
|
|
915
915
|
],
|
|
916
916
|
excerpt : 'Sync your Drawbridge contacts into an Attentive segment.',
|
|
917
|
+
// NAMES THE SEGMENT STEP, because `status` below gates on it: a grant with
|
|
918
|
+
// no segment chosen sits at Pending, and a guide that stops at the consent
|
|
919
|
+
// leaves a merchant looking at a connection they think is broken. Same
|
|
920
|
+
// omission Klaviyo's guide already carries a note about.
|
|
917
921
|
guide : [
|
|
918
922
|
'Press Connect. Drawbridge sends you to Attentive to approve access.',
|
|
919
923
|
'Sign in to Attentive if you are not already, and authorize the permissions listed.',
|
|
920
|
-
'You
|
|
924
|
+
'You come back here to choose which Attentive segment your contacts should sync into.',
|
|
925
|
+
'The connection shows Pending until you choose a segment, then Active.'
|
|
921
926
|
]
|
|
922
927
|
},
|
|
923
928
|
// A contact destination, like Klaviyo and Mailchimp — a merchant could
|
|
@@ -1239,6 +1244,10 @@ var attentive = {
|
|
|
1239
1244
|
|
|
1240
1245
|
queue : 'connection',
|
|
1241
1246
|
|
|
1247
|
+
// Attentive applies the update in the background and returns no id we
|
|
1248
|
+
// could hand on, so there is nothing for a later step to interpolate.
|
|
1249
|
+
returns : [],
|
|
1250
|
+
|
|
1242
1251
|
// Nothing for a merchant to configure on the step itself — the segment
|
|
1243
1252
|
// is chosen once on the connection. Declared empty rather than omitted,
|
|
1244
1253
|
// so "this step takes no settings" and "nobody thought about settings"
|
|
@@ -2236,6 +2245,11 @@ var drawbridge = {
|
|
|
2236
2245
|
message : interpolate( step.settings?.message, values ),
|
|
2237
2246
|
organization : workflow.organization,
|
|
2238
2247
|
send : { type : 'email', email : member.email },
|
|
2248
|
+
// The editor's plain rendering, interpolated the same way so
|
|
2249
|
+
// {{count}} resolves in the text part too. Spread rather than
|
|
2250
|
+
// written as null: a step saved before `text` existed has none,
|
|
2251
|
+
// and the send path strips the markup itself for those.
|
|
2252
|
+
...( step.settings?.text && { text : interpolate( step.settings.text, values ) }),
|
|
2239
2253
|
title : interpolate( step.settings?.subject, values ),
|
|
2240
2254
|
workflow : workflow.id
|
|
2241
2255
|
}) )
|
|
@@ -2423,6 +2437,10 @@ var drawbridge = {
|
|
|
2423
2437
|
message : interpolate( step.settings?.message, context ),
|
|
2424
2438
|
organization : workflow.organization,
|
|
2425
2439
|
send : { type : 'email', email : to },
|
|
2440
|
+
// The editor's plain rendering, so the text/plain part of this
|
|
2441
|
+
// email is what the merchant wrote rather than a regex's guess at
|
|
2442
|
+
// it. See the digest above for why it is spread, not nulled.
|
|
2443
|
+
...( step.settings?.text && { text : interpolate( step.settings.text, context ) }),
|
|
2426
2444
|
title : interpolate( step.settings?.subject, context ),
|
|
2427
2445
|
workflow : workflow.id
|
|
2428
2446
|
})
|
|
@@ -2978,6 +2996,11 @@ var drawbridge = {
|
|
|
2978
2996
|
hook : 'email.digest',
|
|
2979
2997
|
key : 'Email — Digest',
|
|
2980
2998
|
queue : 'notification',
|
|
2999
|
+
// Nothing for a later step to interpolate. Declared empty rather than
|
|
3000
|
+
// omitted, so "this step leaves nothing behind" and "nobody thought
|
|
3001
|
+
// about it" stay different statements — the second is what emptied the
|
|
3002
|
+
// builder's Variables menu for every step in the product.
|
|
3003
|
+
returns : [],
|
|
2981
3004
|
settings : {
|
|
2982
3005
|
// The organization OWNER is always a recipient, resolved by the
|
|
2983
3006
|
// hook, so this is additional recipients rather than the list. It
|
|
@@ -2986,7 +3009,22 @@ var drawbridge = {
|
|
|
2986
3009
|
// pick and could never save the step.
|
|
2987
3010
|
members : { of : 'string', type : 'array' },
|
|
2988
3011
|
message : { max : 2000, required : true, type : 'string' },
|
|
2989
|
-
|
|
3012
|
+
// THE LAST SPAM CHECK, stored beside the copy it measured. Shape is
|
|
3013
|
+
// pinned no further than the pair that proves the match, which is the
|
|
3014
|
+
// only part the api reads; the rest is SpamAssassin's own output and
|
|
3015
|
+
// is stored as it arrives. Same declaration the campaign's draw
|
|
3016
|
+
// notification validates against.
|
|
3017
|
+
//
|
|
3018
|
+
// Undeclared, this was silently dropped at submit — the settings
|
|
3019
|
+
// validator is noUnknown().strict(), so the dashboard's step form
|
|
3020
|
+
// mapped the key away rather than 400 — and every open of a workflow
|
|
3021
|
+
// step re-ran a check against a free service to be told what the last
|
|
3022
|
+
// open had already been told.
|
|
3023
|
+
score : { shape : { message : { type : 'string' }, subject : { type : 'string' } }, type : 'object' },
|
|
3024
|
+
subject : { max : 150, required : true, type : 'string' },
|
|
3025
|
+
// The editor's plain rendering of `message`, written beside it rather
|
|
3026
|
+
// than reconstructed by running a regex over the markup at send time.
|
|
3027
|
+
text : { max : 2000, type : 'string' }
|
|
2990
3028
|
},
|
|
2991
3029
|
triggers : [ 'schedule.day', 'schedule.week', 'schedule.month' ],
|
|
2992
3030
|
usage : { actions : 0 }
|
|
@@ -3008,6 +3046,7 @@ var drawbridge = {
|
|
|
3008
3046
|
hook : 'email.notify',
|
|
3009
3047
|
key : 'Email — Notification',
|
|
3010
3048
|
queue : 'notification',
|
|
3049
|
+
returns : [],
|
|
3011
3050
|
settings : {
|
|
3012
3051
|
members : { of : 'string', type : 'array' },
|
|
3013
3052
|
message : { max : 2000, type : 'string' },
|
|
@@ -3025,9 +3064,14 @@ var drawbridge = {
|
|
|
3025
3064
|
hook : 'email.send',
|
|
3026
3065
|
key : 'Email — Send email',
|
|
3027
3066
|
queue : 'notification',
|
|
3067
|
+
returns : [],
|
|
3028
3068
|
settings : {
|
|
3029
3069
|
message : { max : 2000, required : true, type : 'string' },
|
|
3030
|
-
|
|
3070
|
+
// See email.digest above — the last spam check, and the editor's
|
|
3071
|
+
// plain rendering of the message.
|
|
3072
|
+
score : { shape : { message : { type : 'string' }, subject : { type : 'string' } }, type : 'object' },
|
|
3073
|
+
subject : { max : 150, required : true, type : 'string' },
|
|
3074
|
+
text : { max : 2000, type : 'string' }
|
|
3031
3075
|
},
|
|
3032
3076
|
triggers : [ 'lead.insert' ],
|
|
3033
3077
|
// ONE SOURCE FOR THE PRICE. lib/pricing.js is the index of every
|
|
@@ -3813,6 +3857,14 @@ var klaviyo = {
|
|
|
3813
3857
|
|
|
3814
3858
|
queue : 'connection',
|
|
3815
3859
|
|
|
3860
|
+
// The key the hook puts in `context`, which the runner merges into the
|
|
3861
|
+
// run so a later step can interpolate {{klaviyoProfileId}}. Declared
|
|
3862
|
+
// beside the hook that writes it — see the note on Shopify's
|
|
3863
|
+
// commerce.code, which is where this came back from.
|
|
3864
|
+
returns : [
|
|
3865
|
+
{ key : 'klaviyoProfileId', label : 'Klaviyo Profile ID' }
|
|
3866
|
+
],
|
|
3867
|
+
|
|
3816
3868
|
// Nothing for a merchant to configure on the step itself — the list
|
|
3817
3869
|
// is chosen once on the connection. Declared empty rather than
|
|
3818
3870
|
// omitted, so "this step takes no settings" and "nobody thought about
|
|
@@ -3978,10 +4030,15 @@ var mailchimp = {
|
|
|
3978
4030
|
'Someone who unsubscribed inside Mailchimp keeps that choice: a resync only sets the status of a subscriber Mailchimp has never seen before.'
|
|
3979
4031
|
],
|
|
3980
4032
|
excerpt : 'Sync your Drawbridge contacts into a Mailchimp audience.',
|
|
4033
|
+
// NAMES THE AUDIENCE STEP, because `status` below gates on it: a grant with
|
|
4034
|
+
// no audience chosen sits at Pending, and a guide that stops at the consent
|
|
4035
|
+
// leaves a merchant looking at a connection they think is broken.
|
|
3981
4036
|
guide : [
|
|
3982
4037
|
'Press Connect. Drawbridge sends you to Mailchimp to approve access.',
|
|
3983
4038
|
'Sign in to Mailchimp if you are not already, and choose the account to connect.',
|
|
3984
|
-
'You come back here to pick the audience your contacts should sync into.'
|
|
4039
|
+
'You come back here to pick the audience your contacts should sync into.',
|
|
4040
|
+
'The connection shows Pending until you pick an audience, then Active.',
|
|
4041
|
+
'You can remove Drawbridge at any time from the Authorized Apps page in your Mailchimp account.'
|
|
3985
4042
|
]
|
|
3986
4043
|
},
|
|
3987
4044
|
// Mailchimp and SendGrid shared a group while they were SENDERS, where an org
|
|
@@ -4332,6 +4389,12 @@ var mailchimp = {
|
|
|
4332
4389
|
|
|
4333
4390
|
queue : 'connection',
|
|
4334
4391
|
|
|
4392
|
+
// The key the hook puts in `context`, for a later step to interpolate
|
|
4393
|
+
// as {{mailchimpMemberId}}. Same reasoning as Klaviyo's.
|
|
4394
|
+
returns : [
|
|
4395
|
+
{ key : 'mailchimpMemberId', label : 'Mailchimp Member ID' }
|
|
4396
|
+
],
|
|
4397
|
+
|
|
4335
4398
|
// Nothing for a merchant to configure on the step itself — the audience
|
|
4336
4399
|
// is chosen once on the connection. Declared empty rather than omitted,
|
|
4337
4400
|
// so "this step takes no settings" and "nobody thought about settings"
|
|
@@ -6096,6 +6159,24 @@ var shopify = {
|
|
|
6096
6159
|
hook : 'commerce.code',
|
|
6097
6160
|
key : 'Issue a discount code',
|
|
6098
6161
|
queue : 'connection',
|
|
6162
|
+
// WHAT THIS STEP LEAVES BEHIND FOR THE ONES AFTER IT, and the only
|
|
6163
|
+
// reason the builder can offer a Variables menu.
|
|
6164
|
+
//
|
|
6165
|
+
// These are the exact keys the hook puts in `context` — the runner
|
|
6166
|
+
// merges that into the run's context, and a later step interpolates
|
|
6167
|
+
// {{shopifyDiscountCode}} out of it. Declared beside the hook that
|
|
6168
|
+
// writes them so the two cannot drift; there is nowhere else that
|
|
6169
|
+
// knows both.
|
|
6170
|
+
//
|
|
6171
|
+
// They existed as a hand-written list in the api's workflow catalog
|
|
6172
|
+
// until it was derived from these manifests, and the derivation
|
|
6173
|
+
// hardcoded `returns : []` for every step. Nothing has offered a
|
|
6174
|
+
// variable since — an email step after a discount step had no way to
|
|
6175
|
+
// name the code it was supposed to send.
|
|
6176
|
+
returns : [
|
|
6177
|
+
{ key : 'shopifyDiscountCode', label : 'Shopify Discount Code' },
|
|
6178
|
+
{ key : 'shopifyDiscountId', label : 'Shopify Discount ID' }
|
|
6179
|
+
],
|
|
6099
6180
|
settings : {
|
|
6100
6181
|
discount : {
|
|
6101
6182
|
required : true,
|
|
@@ -6115,6 +6196,12 @@ var shopify = {
|
|
|
6115
6196
|
hook : 'commerce.customer',
|
|
6116
6197
|
key : 'Create customer',
|
|
6117
6198
|
queue : 'connection',
|
|
6199
|
+
// Written on every path the hook can take — created, reused from an
|
|
6200
|
+
// earlier step, or reused from the lead — so a later step can rely on
|
|
6201
|
+
// it being there whenever this one succeeded.
|
|
6202
|
+
returns : [
|
|
6203
|
+
{ key : 'shopifyCustomerId', label : 'Shopify Customer ID' }
|
|
6204
|
+
],
|
|
6118
6205
|
settings : {},
|
|
6119
6206
|
triggers : [ 'lead.insert' ],
|
|
6120
6207
|
usage : { actions : 1 }
|
|
@@ -6425,6 +6512,13 @@ var webhook = {
|
|
|
6425
6512
|
hook : 'webhook.send',
|
|
6426
6513
|
key : 'Send webhook',
|
|
6427
6514
|
queue : 'webhook',
|
|
6515
|
+
// The receiver's response is buffered, not merged into the run — a
|
|
6516
|
+
// receiver owes us a status, not a document — so there is nothing here
|
|
6517
|
+
// for a later step to interpolate. Declared empty rather than omitted:
|
|
6518
|
+
// "leaves nothing behind" and "nobody thought about it" are different
|
|
6519
|
+
// statements, and the second one is what emptied the builder's
|
|
6520
|
+
// Variables menu for every step in the product.
|
|
6521
|
+
returns : [],
|
|
6428
6522
|
settings : {
|
|
6429
6523
|
url : { format : 'url', required : true, type : 'string' }
|
|
6430
6524
|
},
|
|
@@ -7406,6 +7500,12 @@ const publicConnectionKeys = Object.freeze([
|
|
|
7406
7500
|
// excerpt, guide, and any vendor redirect copy.
|
|
7407
7501
|
'content',
|
|
7408
7502
|
'createdAt',
|
|
7503
|
+
// THE MERCHANT'S OWN SWITCH. `enabled : false` is a connection the merchant
|
|
7504
|
+
// paused — kept, configured, and not run — as distinct from a vendor the
|
|
7505
|
+
// platform switched off (which the api overlays as an error). Absent means
|
|
7506
|
+
// on; the dashboard renders Paused from it and the sync gates refuse a paused
|
|
7507
|
+
// connection the way they refuse a missing one.
|
|
7508
|
+
'enabled',
|
|
7409
7509
|
// The connection DOCUMENT's own errors array — scope-drift entries written by
|
|
7410
7510
|
// drawbridge-sync. NOT the manifest's error copy, which is content.errors:
|
|
7411
7511
|
// the document is spread OVER the resolved manifest downstream, so the two
|