@aglyn/plugins-marketing 1.0.0-beta.219 → 1.0.0-beta.220
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 +3 -1
- package/package.json +16 -16
- package/src/lib/components/besigner-section-experiments.d.ts +20 -0
- package/src/lib/components/besigner-section-experiments.js +128 -0
- package/src/lib/components/besigner-section-experiments.js.map +1 -0
- package/src/lib/components/campaign-conversions-card.js +1 -1
- package/src/lib/components/campaign-conversions-card.js.map +1 -1
- package/src/lib/components/campaign-members-section.js +4 -3
- package/src/lib/components/campaign-members-section.js.map +1 -1
- package/src/lib/components/campaign-reach-sections.js +4 -1
- package/src/lib/components/campaign-reach-sections.js.map +1 -1
- package/src/lib/components/campaign-report-card.js +2 -2
- package/src/lib/components/campaign-report-card.js.map +1 -1
- package/src/lib/components/conversion-attribution.component.d.ts +1 -1
- package/src/lib/components/conversion-attribution.component.js +1 -1
- package/src/lib/components/conversion-attribution.component.js.map +1 -1
- package/src/lib/components/record-attribution-widget.js +1 -1
- package/src/lib/components/record-attribution-widget.js.map +1 -1
- package/src/lib/components/site-runtime.js +2 -2
- package/src/lib/components/site-runtime.js.map +1 -1
- package/src/lib/constants/operator-alerts.js +4 -1
- package/src/lib/constants/operator-alerts.js.map +1 -1
- package/src/lib/declarations.server.d.ts +3 -1
- package/src/lib/declarations.server.js +17 -1
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/model/campaign-conversions.d.ts +301 -0
- package/src/lib/model/campaign-conversions.js +252 -0
- package/src/lib/model/campaign-conversions.js.map +1 -0
- package/src/lib/model/campaign-kind.d.ts +50 -0
- package/src/lib/model/campaign-kind.js +52 -0
- package/src/lib/model/campaign-kind.js.map +1 -0
- package/src/lib/model/campaign-members-query.js +1 -1
- package/src/lib/model/campaign-members-query.js.map +1 -1
- package/src/lib/model/campaign-revenue.d.ts +327 -0
- package/src/lib/model/campaign-revenue.js +332 -0
- package/src/lib/model/campaign-revenue.js.map +1 -0
- package/src/lib/model/index.d.ts +3 -0
- package/src/lib/model/index.js +4 -1
- package/src/lib/model/index.js.map +1 -1
- package/src/lib/model/overlay-record-list.d.ts +33 -0
- package/src/lib/model/overlay-record-list.js +53 -0
- package/src/lib/model/overlay-record-list.js.map +1 -0
- package/src/lib/plugin.js +12 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/server/campaign-manage.js +19 -60
- package/src/lib/server/campaign-manage.js.map +1 -1
- package/src/lib/server/campaign-send.d.ts +1 -1
- package/src/lib/server/campaign-send.js +23 -7
- package/src/lib/server/campaign-send.js.map +1 -1
- package/src/lib/server/email-events.js +9 -10
- package/src/lib/server/email-events.js.map +1 -1
- package/src/lib/server/overlay-beacon.d.ts +46 -0
- package/src/lib/server/overlay-beacon.js +76 -0
- package/src/lib/server/overlay-beacon.js.map +1 -0
|
@@ -14,7 +14,7 @@ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
|
14
14
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
15
|
* See the License for the specific language governing permissions and
|
|
16
16
|
* limitations under the License.
|
|
17
|
-
*/ import { checkQuota, contactMatchesSegment,
|
|
17
|
+
*/ import { checkQuota, contactMatchesSegment, isSubscriptionTopicId, DEFAULT_SUBSCRIPTION_TOPIC_ID, readMarketingBasis, resolveMarketingConsentPolicy, splitByMarketingConsent, createResourceUid, decodeStoredNodes, emailStarterSendBlock, resolveBrandingProfile, seenOnlyThroughGrant, siteLockdownFromDocs, visibleToHost } from "@aglyn/aglyn/server";
|
|
18
18
|
import { renderRecipientEmail } from "@aglyn/aglyn/app-utils/recipient-email-render";
|
|
19
19
|
import { composeHostComponentNodes } from "@aglyn/aglyn/app-utils/load-referenced-components";
|
|
20
20
|
import { assignExperimentVariant } from "../model/index.js";
|
|
@@ -72,6 +72,7 @@ import { campaignSendSearchFields } from "../model/campaign-list-query.js";
|
|
|
72
72
|
import { createHash } from "crypto";
|
|
73
73
|
import { EMAIL_MAX_AUDIENCE_PER_SEND, EMAIL_MAX_RECIPIENTS_PER_SEND, createProviderRequestPacer, effectiveReputationPolicy, HOST_SENDERS_COLLECTION, isEmailConfigured, rateLimitedRetryAtMs, readHostSender, sendEmail, sendingIdentityRefusal, sentAsStamp } from "@aglyn/shared-util-email";
|
|
74
74
|
import { campaignBatchPlan } from "./campaign-batch-plan.js";
|
|
75
|
+
import { stampRecordEmailReach } from "@aglyn/aglyn/plugin-manager/plugin-record-email-state";
|
|
75
76
|
/*
|
|
76
77
|
* The List-Unsubscribe setting sequences share (AGL-3307), from its LEAF
|
|
77
78
|
* module: the specs that reach this file spread the real barrel under their
|
|
@@ -450,10 +451,10 @@ export async function performCampaignSend(options) {
|
|
|
450
451
|
* two different parameter tuples — see `signedSubject` in the email plugin's
|
|
451
452
|
* `unsubscribe-link.ts`. Refused at the point the topic ENTERS the send, so
|
|
452
453
|
* the link that leaves it is unambiguous by construction.
|
|
453
|
-
*/ if (options.topicId && !
|
|
454
|
+
*/ if (options.topicId && !isSubscriptionTopicId(options.topicId)) {
|
|
454
455
|
throw new CampaignSendError('Invalid topicId', 400);
|
|
455
456
|
}
|
|
456
|
-
const topicId = options.topicId ||
|
|
457
|
+
const topicId = options.topicId || DEFAULT_SUBSCRIPTION_TOPIC_ID;
|
|
457
458
|
/**
|
|
458
459
|
* Whether this send ADDS to an email that already exists, rather than
|
|
459
460
|
* starting one.
|
|
@@ -1132,14 +1133,21 @@ export async function performCampaignSend(options) {
|
|
|
1132
1133
|
* merchant who cannot send and cannot find out why will open a ticket
|
|
1133
1134
|
* that says the product is broken.
|
|
1134
1135
|
*/ if (reputation.blocked) {
|
|
1136
|
+
var _ref4;
|
|
1137
|
+
var _orgForHost_org4;
|
|
1135
1138
|
// The merchant is told by the refusal; the operator, once a day per
|
|
1136
1139
|
// workspace, so a tripped breaker on a shared domain is looked at
|
|
1137
1140
|
// before it is reinstated (AGL-3377).
|
|
1138
1141
|
await raiseOperatorAlert(MARKETING_REPUTATION_BREAKER, {
|
|
1139
1142
|
dedupeKey: orgId,
|
|
1143
|
+
// The findings in numbers, and the workspace by name off the org doc
|
|
1144
|
+
// this send already holds. `reputation.reason` is the merchant's
|
|
1145
|
+
// refusal, written to them, so it is not staff's copy.
|
|
1140
1146
|
context: {
|
|
1141
1147
|
orgId,
|
|
1142
|
-
|
|
1148
|
+
orgName: String((_ref4 = orgForHost == null ? void 0 : (_orgForHost_org4 = orgForHost.org) == null ? void 0 : _orgForHost_org4['name']) != null ? _ref4 : '').trim(),
|
|
1149
|
+
windowDays: reputation.windowDays,
|
|
1150
|
+
detail: reputation.findings.filter((finding)=>finding.actionable).map((finding)=>finding.detail).join(' ')
|
|
1143
1151
|
},
|
|
1144
1152
|
orgId
|
|
1145
1153
|
});
|
|
@@ -1477,14 +1485,14 @@ export async function performCampaignSend(options) {
|
|
|
1477
1485
|
* back on the clock and this screen finds it released — and actioning the
|
|
1478
1486
|
* row cancels it.
|
|
1479
1487
|
*/ if (!options.followUp) {
|
|
1480
|
-
var
|
|
1488
|
+
var _ref5, _hostSnapshot_data, _options_fromName, _sendingIdentity_from, _options_replyTo, _options_preheader, _options_plainText, _experiment_variants;
|
|
1481
1489
|
const sendRef = sends.doc(campaignId);
|
|
1482
1490
|
const screened = await screenOutboundSend({
|
|
1483
1491
|
kind: 'campaign',
|
|
1484
1492
|
path: sendRef.path,
|
|
1485
1493
|
hostId,
|
|
1486
1494
|
orgId,
|
|
1487
|
-
org: (
|
|
1495
|
+
org: (_ref5 = orgForHost == null ? void 0 : orgForHost.org) != null ? _ref5 : null,
|
|
1488
1496
|
host: (_hostSnapshot_data = hostSnapshot.data()) != null ? _hostSnapshot_data : null,
|
|
1489
1497
|
subject,
|
|
1490
1498
|
fromName: (_options_fromName = options.fromName) != null ? _options_fromName : null,
|
|
@@ -2071,6 +2079,14 @@ export async function performCampaignSend(options) {
|
|
|
2071
2079
|
* follow-up, which is also safe but loses the feature over a transient.
|
|
2072
2080
|
*/ if (options.recordCampaign !== false) {
|
|
2073
2081
|
await recordCampaignReach(sends.doc(campaignId), reached);
|
|
2082
|
+
// The record system hears who it reached, so a lead nobody had touched
|
|
2083
|
+
// moves to Nurturing (AGL-3446). A test send reached nobody's lead, so it
|
|
2084
|
+
// is left out with the reach record. Never throws.
|
|
2085
|
+
await stampRecordEmailReach({
|
|
2086
|
+
orgId,
|
|
2087
|
+
hostId,
|
|
2088
|
+
emails: reached
|
|
2089
|
+
});
|
|
2074
2090
|
/*
|
|
2075
2091
|
* And who it decided NOT to mail, under a field of its own.
|
|
2076
2092
|
*
|
|
@@ -2865,7 +2881,7 @@ function storedSendOptionsFrom(snapshot, hostId, senderUid, followUp) {
|
|
|
2865
2881
|
* An empty value is not an error: it means "the composer did not say", which
|
|
2866
2882
|
* `performCampaignSend` resolves to the default topic.
|
|
2867
2883
|
*/ const topicId = String((_ref10 = (_req_body14 = req.body) == null ? void 0 : _req_body14.topicId) != null ? _ref10 : '');
|
|
2868
|
-
if (topicId && !
|
|
2884
|
+
if (topicId && !isSubscriptionTopicId(topicId)) {
|
|
2869
2885
|
return res.status(400).json({
|
|
2870
2886
|
error: 'Unknown topic'
|
|
2871
2887
|
});
|