payload-plugin-newsletter 0.16.2 → 0.16.5
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/CHANGELOG.md +50 -0
- package/dist/collections.cjs +90 -18
- package/dist/collections.cjs.map +1 -1
- package/dist/collections.js +90 -18
- package/dist/collections.js.map +1 -1
- package/dist/index.cjs +94 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +94 -22
- package/dist/index.js.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/plugin-api-key-recommendations.md +117 -0
package/dist/collections.js
CHANGED
|
@@ -269,9 +269,9 @@ var init_broadcast2 = __esm({
|
|
|
269
269
|
async update(id, data) {
|
|
270
270
|
try {
|
|
271
271
|
const existing = await this.get(id);
|
|
272
|
-
if (!this.canEditInStatus(existing.
|
|
272
|
+
if (!this.canEditInStatus(existing.sendStatus)) {
|
|
273
273
|
throw new BroadcastProviderError(
|
|
274
|
-
`Cannot update broadcast in status: ${existing.
|
|
274
|
+
`Cannot update broadcast in status: ${existing.sendStatus}`,
|
|
275
275
|
"INVALID_STATUS" /* INVALID_STATUS */,
|
|
276
276
|
this.name
|
|
277
277
|
);
|
|
@@ -314,9 +314,9 @@ var init_broadcast2 = __esm({
|
|
|
314
314
|
async delete(id) {
|
|
315
315
|
try {
|
|
316
316
|
const existing = await this.get(id);
|
|
317
|
-
if (!this.canEditInStatus(existing.
|
|
317
|
+
if (!this.canEditInStatus(existing.sendStatus)) {
|
|
318
318
|
throw new BroadcastProviderError(
|
|
319
|
-
`Cannot delete broadcast in status: ${existing.
|
|
319
|
+
`Cannot delete broadcast in status: ${existing.sendStatus}`,
|
|
320
320
|
"INVALID_STATUS" /* INVALID_STATUS */,
|
|
321
321
|
this.name
|
|
322
322
|
);
|
|
@@ -475,7 +475,7 @@ var init_broadcast2 = __esm({
|
|
|
475
475
|
subject: broadcast.subject,
|
|
476
476
|
preheader: broadcast.preheader,
|
|
477
477
|
content: broadcast.body,
|
|
478
|
-
|
|
478
|
+
sendStatus: this.mapBroadcastStatus(broadcast.status),
|
|
479
479
|
trackOpens: broadcast.track_opens,
|
|
480
480
|
trackClicks: broadcast.track_clicks,
|
|
481
481
|
replyTo: broadcast.reply_to,
|
|
@@ -1178,6 +1178,19 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1178
1178
|
const customizations = pluginConfig.customizations?.broadcasts;
|
|
1179
1179
|
return {
|
|
1180
1180
|
slug: "broadcasts",
|
|
1181
|
+
access: {
|
|
1182
|
+
read: () => true,
|
|
1183
|
+
// Public read access
|
|
1184
|
+
create: ({ req: { user } }) => {
|
|
1185
|
+
return Boolean(user);
|
|
1186
|
+
},
|
|
1187
|
+
update: ({ req: { user } }) => {
|
|
1188
|
+
return Boolean(user);
|
|
1189
|
+
},
|
|
1190
|
+
delete: ({ req: { user } }) => {
|
|
1191
|
+
return Boolean(user);
|
|
1192
|
+
}
|
|
1193
|
+
},
|
|
1181
1194
|
versions: {
|
|
1182
1195
|
drafts: {
|
|
1183
1196
|
autosave: true,
|
|
@@ -1191,7 +1204,7 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1191
1204
|
admin: {
|
|
1192
1205
|
useAsTitle: "subject",
|
|
1193
1206
|
description: "Individual email campaigns sent to subscribers",
|
|
1194
|
-
defaultColumns: ["subject", "_status", "
|
|
1207
|
+
defaultColumns: ["subject", "_status", "sendStatus", "sentAt", "recipientCount"]
|
|
1195
1208
|
},
|
|
1196
1209
|
fields: [
|
|
1197
1210
|
{
|
|
@@ -1251,8 +1264,9 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1251
1264
|
]
|
|
1252
1265
|
},
|
|
1253
1266
|
{
|
|
1254
|
-
name: "
|
|
1267
|
+
name: "sendStatus",
|
|
1255
1268
|
type: "select",
|
|
1269
|
+
label: "Send Status",
|
|
1256
1270
|
required: true,
|
|
1257
1271
|
defaultValue: "draft" /* DRAFT */,
|
|
1258
1272
|
options: [
|
|
@@ -1266,6 +1280,7 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1266
1280
|
],
|
|
1267
1281
|
admin: {
|
|
1268
1282
|
readOnly: true,
|
|
1283
|
+
description: "The status of the email send operation",
|
|
1269
1284
|
components: {
|
|
1270
1285
|
Cell: "payload-plugin-newsletter/components#StatusBadge"
|
|
1271
1286
|
}
|
|
@@ -1322,7 +1337,7 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1322
1337
|
type: "group",
|
|
1323
1338
|
admin: {
|
|
1324
1339
|
readOnly: true,
|
|
1325
|
-
condition: (data) => data?.
|
|
1340
|
+
condition: (data) => data?.sendStatus === "sent" /* SENT */
|
|
1326
1341
|
},
|
|
1327
1342
|
fields: [
|
|
1328
1343
|
{
|
|
@@ -1381,7 +1396,7 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1381
1396
|
name: "scheduledAt",
|
|
1382
1397
|
type: "date",
|
|
1383
1398
|
admin: {
|
|
1384
|
-
condition: (data) => data?.
|
|
1399
|
+
condition: (data) => data?.sendStatus === "scheduled" /* SCHEDULED */,
|
|
1385
1400
|
date: {
|
|
1386
1401
|
displayFormat: "MMM d, yyyy h:mm a"
|
|
1387
1402
|
}
|
|
@@ -1446,7 +1461,17 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1446
1461
|
providerData: providerBroadcast.providerData
|
|
1447
1462
|
};
|
|
1448
1463
|
} catch (error) {
|
|
1449
|
-
|
|
1464
|
+
if (error instanceof Error) {
|
|
1465
|
+
req.payload.logger.error("Failed to create broadcast in provider:", {
|
|
1466
|
+
message: error.message,
|
|
1467
|
+
stack: error.stack,
|
|
1468
|
+
name: error.name,
|
|
1469
|
+
// If it's a BroadcastProviderError, it might have additional details
|
|
1470
|
+
...error.details
|
|
1471
|
+
});
|
|
1472
|
+
} else {
|
|
1473
|
+
req.payload.logger.error("Failed to create broadcast in provider:", error);
|
|
1474
|
+
}
|
|
1450
1475
|
return doc;
|
|
1451
1476
|
}
|
|
1452
1477
|
},
|
|
@@ -1456,7 +1481,7 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1456
1481
|
const wasUnpublished = !previousDoc?._status || previousDoc._status === "draft";
|
|
1457
1482
|
const isNowPublished = doc._status === "published";
|
|
1458
1483
|
if (wasUnpublished && isNowPublished && doc.providerId) {
|
|
1459
|
-
if (doc.
|
|
1484
|
+
if (doc.sendStatus === "sent" /* SENT */ || doc.sendStatus === "sending" /* SENDING */) {
|
|
1460
1485
|
return doc;
|
|
1461
1486
|
}
|
|
1462
1487
|
try {
|
|
@@ -1475,19 +1500,29 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1475
1500
|
collection: "broadcasts",
|
|
1476
1501
|
id: doc.id,
|
|
1477
1502
|
data: {
|
|
1478
|
-
|
|
1503
|
+
sendStatus: "sending" /* SENDING */,
|
|
1479
1504
|
sentAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1480
1505
|
},
|
|
1481
1506
|
req
|
|
1482
1507
|
});
|
|
1483
1508
|
req.payload.logger.info(`Broadcast ${doc.id} sent successfully`);
|
|
1484
1509
|
} catch (error) {
|
|
1485
|
-
|
|
1510
|
+
if (error instanceof Error) {
|
|
1511
|
+
req.payload.logger.error(`Failed to send broadcast ${doc.id}:`, {
|
|
1512
|
+
message: error.message,
|
|
1513
|
+
stack: error.stack,
|
|
1514
|
+
name: error.name,
|
|
1515
|
+
// If it's a BroadcastProviderError, it might have additional details
|
|
1516
|
+
...error.details
|
|
1517
|
+
});
|
|
1518
|
+
} else {
|
|
1519
|
+
req.payload.logger.error(`Failed to send broadcast ${doc.id}:`, error);
|
|
1520
|
+
}
|
|
1486
1521
|
await req.payload.update({
|
|
1487
1522
|
collection: "broadcasts",
|
|
1488
1523
|
id: doc.id,
|
|
1489
1524
|
data: {
|
|
1490
|
-
|
|
1525
|
+
sendStatus: "failed" /* FAILED */
|
|
1491
1526
|
},
|
|
1492
1527
|
req
|
|
1493
1528
|
});
|
|
@@ -1500,6 +1535,14 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1500
1535
|
beforeChange: [
|
|
1501
1536
|
async ({ data, originalDoc, operation, req }) => {
|
|
1502
1537
|
if (!hasProviders || !originalDoc?.providerId || operation !== "update") return data;
|
|
1538
|
+
req.payload.logger.info("Broadcast beforeChange update hook triggered", {
|
|
1539
|
+
operation,
|
|
1540
|
+
hasProviderId: !!originalDoc?.providerId,
|
|
1541
|
+
originalSendStatus: originalDoc?.sendStatus,
|
|
1542
|
+
originalPublishStatus: originalDoc?._status,
|
|
1543
|
+
newSendStatus: data?.sendStatus,
|
|
1544
|
+
newPublishStatus: data?._status
|
|
1545
|
+
});
|
|
1503
1546
|
try {
|
|
1504
1547
|
const providerConfig = await getBroadcastConfig(req, pluginConfig);
|
|
1505
1548
|
if (!providerConfig || !providerConfig.token) {
|
|
@@ -1509,7 +1552,9 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1509
1552
|
const { BroadcastApiProvider: BroadcastApiProvider2 } = await Promise.resolve().then(() => (init_broadcast2(), broadcast_exports));
|
|
1510
1553
|
const provider = new BroadcastApiProvider2(providerConfig);
|
|
1511
1554
|
const capabilities = provider.getCapabilities();
|
|
1512
|
-
|
|
1555
|
+
const sendStatus = originalDoc.sendStatus || "draft" /* DRAFT */;
|
|
1556
|
+
if (!capabilities.editableStatuses.includes(sendStatus)) {
|
|
1557
|
+
req.payload.logger.info(`Skipping sync for broadcast in status: ${sendStatus}`);
|
|
1513
1558
|
return data;
|
|
1514
1559
|
}
|
|
1515
1560
|
const updates = {};
|
|
@@ -1534,10 +1579,27 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1534
1579
|
updates.audienceIds = data.audienceIds?.map((a) => a.audienceId);
|
|
1535
1580
|
}
|
|
1536
1581
|
if (Object.keys(updates).length > 0) {
|
|
1582
|
+
req.payload.logger.info("Syncing broadcast updates to provider", {
|
|
1583
|
+
providerId: originalDoc.providerId,
|
|
1584
|
+
updates
|
|
1585
|
+
});
|
|
1537
1586
|
await provider.update(originalDoc.providerId, updates);
|
|
1587
|
+
req.payload.logger.info("Successfully synced broadcast updates to provider");
|
|
1588
|
+
} else {
|
|
1589
|
+
req.payload.logger.info("No broadcast updates to sync to provider");
|
|
1538
1590
|
}
|
|
1539
1591
|
} catch (error) {
|
|
1540
|
-
|
|
1592
|
+
if (error instanceof Error) {
|
|
1593
|
+
req.payload.logger.error("Failed to update broadcast in provider:", {
|
|
1594
|
+
message: error.message,
|
|
1595
|
+
stack: error.stack,
|
|
1596
|
+
name: error.name,
|
|
1597
|
+
// If it's a BroadcastProviderError, it might have additional details
|
|
1598
|
+
...error.details
|
|
1599
|
+
});
|
|
1600
|
+
} else {
|
|
1601
|
+
req.payload.logger.error("Failed to update broadcast in provider:", error);
|
|
1602
|
+
}
|
|
1541
1603
|
}
|
|
1542
1604
|
return data;
|
|
1543
1605
|
}
|
|
@@ -1555,11 +1617,21 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1555
1617
|
const { BroadcastApiProvider: BroadcastApiProvider2 } = await Promise.resolve().then(() => (init_broadcast2(), broadcast_exports));
|
|
1556
1618
|
const provider = new BroadcastApiProvider2(providerConfig);
|
|
1557
1619
|
const capabilities = provider.getCapabilities();
|
|
1558
|
-
if (capabilities.editableStatuses.includes(doc.
|
|
1620
|
+
if (capabilities.editableStatuses.includes(doc.sendStatus)) {
|
|
1559
1621
|
await provider.delete(doc.providerId);
|
|
1560
1622
|
}
|
|
1561
1623
|
} catch (error) {
|
|
1562
|
-
|
|
1624
|
+
if (error instanceof Error) {
|
|
1625
|
+
req.payload.logger.error("Failed to delete broadcast from provider:", {
|
|
1626
|
+
message: error.message,
|
|
1627
|
+
stack: error.stack,
|
|
1628
|
+
name: error.name,
|
|
1629
|
+
// If it's a BroadcastProviderError, it might have additional details
|
|
1630
|
+
...error.details
|
|
1631
|
+
});
|
|
1632
|
+
} else {
|
|
1633
|
+
req.payload.logger.error("Failed to delete broadcast from provider:", error);
|
|
1634
|
+
}
|
|
1563
1635
|
}
|
|
1564
1636
|
return doc;
|
|
1565
1637
|
}
|