@aglyn/plugins-marketing 1.0.0-beta.218 → 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 +5 -1
- package/package.json +16 -16
- package/src/lib/analytics-provider.d.ts +177 -0
- package/src/lib/analytics-provider.js +370 -0
- package/src/lib/analytics-provider.js.map +1 -0
- 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-detail-card.js +16 -16
- package/src/lib/components/campaign-detail-card.js.map +1 -1
- package/src/lib/components/campaign-members-section.js +15 -14
- 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 +8 -6
- package/src/lib/components/campaign-report-card.js.map +1 -1
- package/src/lib/components/campaigns-card.js +1 -1
- package/src/lib/components/campaigns-card.js.map +1 -1
- package/src/lib/components/conversion-attribution.component.d.ts +1 -1
- package/src/lib/components/conversion-attribution.component.js +2 -2
- package/src/lib/components/conversion-attribution.component.js.map +1 -1
- package/src/lib/components/email-detail.js +12 -7
- package/src/lib/components/email-detail.js.map +1 -1
- package/src/lib/components/email-messages-widget.js +1 -1
- package/src/lib/components/email-messages-widget.js.map +1 -1
- package/src/lib/components/emails-list-card.js +11 -5
- package/src/lib/components/emails-list-card.js.map +1 -1
- package/src/lib/components/host-experiments-card.component.js +12 -7
- package/src/lib/components/host-experiments-card.component.js.map +1 -1
- package/src/lib/components/org-experiments-card.js +1 -1
- package/src/lib/components/org-experiments-card.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/record-route-context.d.ts +41 -0
- package/src/lib/components/record-route-context.js +63 -0
- package/src/lib/components/record-route-context.js.map +1 -0
- package/src/lib/components/site-runtime.js +2 -2
- package/src/lib/components/site-runtime.js.map +1 -1
- package/src/lib/components/use-marketing-hub-path.d.ts +18 -5
- package/src/lib/components/use-marketing-hub-path.js +36 -6
- package/src/lib/components/use-marketing-hub-path.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/campaign-send-time.d.ts +74 -0
- package/src/lib/model/campaign-send-time.js +120 -0
- package/src/lib/model/campaign-send-time.js.map +1 -0
- package/src/lib/model/experiments.js +1 -1
- package/src/lib/model/experiments.js.map +1 -1
- 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-batch-plan.d.ts +73 -0
- package/src/lib/server/campaign-batch-plan.js +79 -0
- package/src/lib/server/campaign-batch-plan.js.map +1 -0
- 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 +32 -11
- package/src/lib/server/campaign-send.js.map +1 -1
- package/src/lib/server/email-events.js +16 -16
- package/src/lib/server/email-events.js.map +1 -1
- package/src/lib/server/list-send-time-facts.d.ts +60 -0
- package/src/lib/server/list-send-time-facts.js +108 -0
- package/src/lib/server/list-send-time-facts.js.map +1 -0
- 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
- package/src/lib/server.js +4 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/tenant-emails.d.ts +29 -0
- package/src/lib/tenant-emails.js +41 -0
- package/src/lib/tenant-emails.js.map +1 -0
- package/src/lib/testing/stand-in-emails-page-routes.d.ts +27 -0
- package/src/lib/testing/stand-in-emails-page-routes.js +42 -0
- package/src/lib/testing/stand-in-emails-page-routes.js.map +1 -0
- package/src/lib/components/use-emails-hub-path.d.ts +0 -58
- package/src/lib/components/use-emails-hub-path.js +0 -109
- package/src/lib/components/use-emails-hub-path.js.map +0 -1
|
@@ -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";
|
|
@@ -70,7 +70,9 @@ import { campaignSendSearchFields } from "../model/campaign-list-query.js";
|
|
|
70
70
|
* against a harness that cannot serve it.
|
|
71
71
|
*/ import { claimOrgEmailSendDay, orgAgeDays, readSenderReputation, reconcileOrgEmailSendDay, recordCampaignAccepted, resolveOrgEmailRamp } from "@aglyn/tenant-data-admin/server/email-sender-reputation";
|
|
72
72
|
import { createHash } from "crypto";
|
|
73
|
-
import { EMAIL_MAX_AUDIENCE_PER_SEND, EMAIL_MAX_RECIPIENTS_PER_SEND,
|
|
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
|
+
import { campaignBatchPlan } from "./campaign-batch-plan.js";
|
|
75
|
+
import { stampRecordEmailReach } from "@aglyn/aglyn/plugin-manager/plugin-record-email-state";
|
|
74
76
|
/*
|
|
75
77
|
* The List-Unsubscribe setting sequences share (AGL-3307), from its LEAF
|
|
76
78
|
* module: the specs that reach this file spread the real barrel under their
|
|
@@ -449,10 +451,10 @@ export async function performCampaignSend(options) {
|
|
|
449
451
|
* two different parameter tuples — see `signedSubject` in the email plugin's
|
|
450
452
|
* `unsubscribe-link.ts`. Refused at the point the topic ENTERS the send, so
|
|
451
453
|
* the link that leaves it is unambiguous by construction.
|
|
452
|
-
*/ if (options.topicId && !
|
|
454
|
+
*/ if (options.topicId && !isSubscriptionTopicId(options.topicId)) {
|
|
453
455
|
throw new CampaignSendError('Invalid topicId', 400);
|
|
454
456
|
}
|
|
455
|
-
const topicId = options.topicId ||
|
|
457
|
+
const topicId = options.topicId || DEFAULT_SUBSCRIPTION_TOPIC_ID;
|
|
456
458
|
/**
|
|
457
459
|
* Whether this send ADDS to an email that already exists, rather than
|
|
458
460
|
* starting one.
|
|
@@ -714,7 +716,9 @@ export async function performCampaignSend(options) {
|
|
|
714
716
|
// MAIL a sibling brand's leads under this site's campaign.
|
|
715
717
|
const leads = await sweepAudience((await orgDataQueryForHost(hostId, 'leads')).query);
|
|
716
718
|
audienceTruncated = leads.truncated;
|
|
717
|
-
|
|
719
|
+
// Held, not merely seen: a lead another site SHARED with this one
|
|
720
|
+
// (AGL-3336) is visible here and was never this site's audience.
|
|
721
|
+
recipients = leads.docs.filter((doc)=>!seenOnlyThroughGrant(doc.data(), hostId)).map((doc)=>{
|
|
718
722
|
var _doc_get;
|
|
719
723
|
const email = String((_doc_get = doc.get('email')) != null ? _doc_get : '');
|
|
720
724
|
collectName(email, doc.get('name'));
|
|
@@ -780,7 +784,9 @@ export async function performCampaignSend(options) {
|
|
|
780
784
|
* reports a small `audienceSize` with `audienceTruncated` set, reading as
|
|
781
785
|
* "at least this many, we stopped counting" and not as a total.
|
|
782
786
|
*/ audienceTruncated = contacts.truncated;
|
|
783
|
-
recipients = contacts.docs
|
|
787
|
+
recipients = contacts.docs// Held, not merely seen — a shared contact is no site's audience but
|
|
788
|
+
// its holders' (AGL-3336).
|
|
789
|
+
.filter((doc)=>!seenOnlyThroughGrant(doc.data(), hostId)).filter((doc)=>{
|
|
784
790
|
var _doc_get, _doc_get1;
|
|
785
791
|
return contactMatchesSegment({
|
|
786
792
|
tags: (_doc_get = doc.get('tags')) != null ? _doc_get : [],
|
|
@@ -1127,14 +1133,21 @@ export async function performCampaignSend(options) {
|
|
|
1127
1133
|
* merchant who cannot send and cannot find out why will open a ticket
|
|
1128
1134
|
* that says the product is broken.
|
|
1129
1135
|
*/ if (reputation.blocked) {
|
|
1136
|
+
var _ref4;
|
|
1137
|
+
var _orgForHost_org4;
|
|
1130
1138
|
// The merchant is told by the refusal; the operator, once a day per
|
|
1131
1139
|
// workspace, so a tripped breaker on a shared domain is looked at
|
|
1132
1140
|
// before it is reinstated (AGL-3377).
|
|
1133
1141
|
await raiseOperatorAlert(MARKETING_REPUTATION_BREAKER, {
|
|
1134
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.
|
|
1135
1146
|
context: {
|
|
1136
1147
|
orgId,
|
|
1137
|
-
|
|
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(' ')
|
|
1138
1151
|
},
|
|
1139
1152
|
orgId
|
|
1140
1153
|
});
|
|
@@ -1472,14 +1485,14 @@ export async function performCampaignSend(options) {
|
|
|
1472
1485
|
* back on the clock and this screen finds it released — and actioning the
|
|
1473
1486
|
* row cancels it.
|
|
1474
1487
|
*/ if (!options.followUp) {
|
|
1475
|
-
var
|
|
1488
|
+
var _ref5, _hostSnapshot_data, _options_fromName, _sendingIdentity_from, _options_replyTo, _options_preheader, _options_plainText, _experiment_variants;
|
|
1476
1489
|
const sendRef = sends.doc(campaignId);
|
|
1477
1490
|
const screened = await screenOutboundSend({
|
|
1478
1491
|
kind: 'campaign',
|
|
1479
1492
|
path: sendRef.path,
|
|
1480
1493
|
hostId,
|
|
1481
1494
|
orgId,
|
|
1482
|
-
org: (
|
|
1495
|
+
org: (_ref5 = orgForHost == null ? void 0 : orgForHost.org) != null ? _ref5 : null,
|
|
1483
1496
|
host: (_hostSnapshot_data = hostSnapshot.data()) != null ? _hostSnapshot_data : null,
|
|
1484
1497
|
subject,
|
|
1485
1498
|
fromName: (_options_fromName = options.fromName) != null ? _options_fromName : null,
|
|
@@ -1804,7 +1817,7 @@ export async function performCampaignSend(options) {
|
|
|
1804
1817
|
siteBase,
|
|
1805
1818
|
hostId,
|
|
1806
1819
|
email,
|
|
1807
|
-
campaignId,
|
|
1820
|
+
sendId: campaignId,
|
|
1808
1821
|
topicId,
|
|
1809
1822
|
secret: unsubscribeSecret
|
|
1810
1823
|
};
|
|
@@ -2066,6 +2079,14 @@ export async function performCampaignSend(options) {
|
|
|
2066
2079
|
* follow-up, which is also safe but loses the feature over a transient.
|
|
2067
2080
|
*/ if (options.recordCampaign !== false) {
|
|
2068
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
|
+
});
|
|
2069
2090
|
/*
|
|
2070
2091
|
* And who it decided NOT to mail, under a field of its own.
|
|
2071
2092
|
*
|
|
@@ -2860,7 +2881,7 @@ function storedSendOptionsFrom(snapshot, hostId, senderUid, followUp) {
|
|
|
2860
2881
|
* An empty value is not an error: it means "the composer did not say", which
|
|
2861
2882
|
* `performCampaignSend` resolves to the default topic.
|
|
2862
2883
|
*/ const topicId = String((_ref10 = (_req_body14 = req.body) == null ? void 0 : _req_body14.topicId) != null ? _ref10 : '');
|
|
2863
|
-
if (topicId && !
|
|
2884
|
+
if (topicId && !isSubscriptionTopicId(topicId)) {
|
|
2864
2885
|
return res.status(400).json({
|
|
2865
2886
|
error: 'Unknown topic'
|
|
2866
2887
|
});
|