payload-plugin-newsletter 0.15.1 → 0.16.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/CHANGELOG.md +52 -0
- package/README.md +44 -0
- package/dist/collections.cjs +52 -13
- package/dist/collections.cjs.map +1 -1
- package/dist/collections.js +52 -13
- package/dist/collections.js.map +1 -1
- package/dist/components.cjs +0 -438
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +1 -3
- package/dist/components.d.ts +1 -3
- package/dist/components.js +0 -437
- package/dist/components.js.map +1 -1
- package/dist/index.cjs +52 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +52 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,55 @@
|
|
|
1
|
+
## [0.16.1] - 2025-07-27
|
|
2
|
+
|
|
3
|
+
### Fixed
|
|
4
|
+
- **Critical Bug Fix** - Fixed afterChange hook placement for sending broadcasts
|
|
5
|
+
- The send hook was incorrectly placed in the `afterDelete` array instead of `afterChange`
|
|
6
|
+
- This prevented broadcasts from being sent when published
|
|
7
|
+
- Publishing broadcasts now correctly triggers the send functionality
|
|
8
|
+
|
|
9
|
+
## [0.16.0] - 2025-07-27
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- **Send = Publish Workflow** - Simplified broadcast sending to use Payload's native draft/publish system
|
|
13
|
+
- Publishing a broadcast now automatically sends it via the configured email provider
|
|
14
|
+
- Removed custom Send/Schedule modal in favor of Payload's built-in UI
|
|
15
|
+
- Scheduled publishing supported via Payload's Jobs Queue system
|
|
16
|
+
- Breaking: Removed `SendBroadcastModal` and `ActionsCell` components
|
|
17
|
+
- **Streamlined UI** - Removed custom action buttons from broadcasts list view
|
|
18
|
+
- Users now use standard Payload publish/schedule functionality
|
|
19
|
+
- Cleaner interface that follows Payload's patterns
|
|
20
|
+
- Less code to maintain while providing better integration
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- **Automatic Send on Publish** - New `afterChange` hook that sends broadcasts when published
|
|
24
|
+
- Checks if broadcast is transitioning to published status
|
|
25
|
+
- Automatically calls provider's send method
|
|
26
|
+
- Updates broadcast status to "sending" after successful send
|
|
27
|
+
- Handles failures gracefully with status update to "failed"
|
|
28
|
+
- **Jobs Queue Documentation** - Added comprehensive setup instructions for scheduled publishing
|
|
29
|
+
- Vercel Cron configuration example
|
|
30
|
+
- Security setup with CRON_SECRET
|
|
31
|
+
- Step-by-step guide for enabling scheduled broadcasts
|
|
32
|
+
|
|
33
|
+
### Removed
|
|
34
|
+
- **Custom UI Components** (Breaking Change)
|
|
35
|
+
- `SendBroadcastModal` - Custom send/schedule modal
|
|
36
|
+
- `ActionsCell` - Custom action buttons in list view
|
|
37
|
+
- `actions` field from Broadcasts collection
|
|
38
|
+
- These are replaced by Payload's native publish/schedule functionality
|
|
39
|
+
|
|
40
|
+
### Technical
|
|
41
|
+
- Enabled `versions` configuration on Broadcasts collection with drafts and scheduled publishing
|
|
42
|
+
- Updated default columns to show both `_status` (Draft/Published) and `status` (send status)
|
|
43
|
+
- Improved TypeScript exports by removing deleted component references
|
|
44
|
+
- All tests passing with minor version upgrade
|
|
45
|
+
|
|
46
|
+
### Migration Guide
|
|
47
|
+
If you were using the custom Send/Schedule modal:
|
|
48
|
+
1. The functionality is now built into Payload's publish system
|
|
49
|
+
2. To send immediately: Click "Publish"
|
|
50
|
+
3. To schedule: Click "Schedule" (requires Jobs Queue setup)
|
|
51
|
+
4. Remove any imports of `SendBroadcastModal` or `ActionsCell` from your code
|
|
52
|
+
|
|
1
53
|
## [0.15.1] - 2025-07-27
|
|
2
54
|
|
|
3
55
|
### Fixed
|
package/README.md
CHANGED
|
@@ -241,6 +241,50 @@ This adds a `broadcasts` collection with:
|
|
|
241
241
|
- Custom email blocks (buttons, dividers)
|
|
242
242
|
- Inline email preview with React Email
|
|
243
243
|
- Automatic sync with your email provider
|
|
244
|
+
- Draft/publish system with scheduled publishing support
|
|
245
|
+
|
|
246
|
+
### Send = Publish Workflow
|
|
247
|
+
|
|
248
|
+
The plugin integrates seamlessly with Payload's draft/publish system:
|
|
249
|
+
|
|
250
|
+
- **Draft**: Create and edit broadcasts without sending
|
|
251
|
+
- **Publish**: Publishing a broadcast automatically sends it via your configured email provider
|
|
252
|
+
- **Schedule**: Use Payload's scheduled publishing to send broadcasts at a future time
|
|
253
|
+
|
|
254
|
+
**How it works:**
|
|
255
|
+
1. Create a broadcast and save as draft
|
|
256
|
+
2. When ready, click "Publish" to send immediately
|
|
257
|
+
3. Or use "Schedule" to publish (and send) at a specific date/time
|
|
258
|
+
|
|
259
|
+
**Important**: Scheduled publishing requires configuring Payload's Jobs Queue. For Vercel deployments, add this to your `vercel.json`:
|
|
260
|
+
|
|
261
|
+
```json
|
|
262
|
+
{
|
|
263
|
+
"crons": [
|
|
264
|
+
{
|
|
265
|
+
"path": "/api/payload-jobs/run",
|
|
266
|
+
"schedule": "*/5 * * * *"
|
|
267
|
+
}
|
|
268
|
+
]
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
And secure the endpoint in your `payload.config.ts`:
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
export default buildConfig({
|
|
276
|
+
// ... other config
|
|
277
|
+
jobs: {
|
|
278
|
+
access: {
|
|
279
|
+
run: ({ req }) => {
|
|
280
|
+
if (req.user) return true
|
|
281
|
+
const authHeader = req.headers.get('authorization')
|
|
282
|
+
return authHeader === `Bearer ${process.env.CRON_SECRET}`
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
})
|
|
287
|
+
```
|
|
244
288
|
|
|
245
289
|
### Custom Email Templates (v0.12.0+)
|
|
246
290
|
|
package/dist/collections.cjs
CHANGED
|
@@ -1168,6 +1168,12 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1168
1168
|
const customizations = pluginConfig.customizations?.broadcasts;
|
|
1169
1169
|
return {
|
|
1170
1170
|
slug: "broadcasts",
|
|
1171
|
+
versions: {
|
|
1172
|
+
drafts: {
|
|
1173
|
+
autosave: true,
|
|
1174
|
+
schedulePublish: true
|
|
1175
|
+
}
|
|
1176
|
+
},
|
|
1171
1177
|
labels: {
|
|
1172
1178
|
singular: "Broadcast",
|
|
1173
1179
|
plural: "Broadcasts"
|
|
@@ -1175,7 +1181,7 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1175
1181
|
admin: {
|
|
1176
1182
|
useAsTitle: "subject",
|
|
1177
1183
|
description: "Individual email campaigns sent to subscribers",
|
|
1178
|
-
defaultColumns: ["subject", "
|
|
1184
|
+
defaultColumns: ["subject", "_status", "status", "sentAt", "recipientCount"]
|
|
1179
1185
|
},
|
|
1180
1186
|
fields: [
|
|
1181
1187
|
{
|
|
@@ -1388,18 +1394,6 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1388
1394
|
condition: () => false
|
|
1389
1395
|
// Hidden by default
|
|
1390
1396
|
}
|
|
1391
|
-
},
|
|
1392
|
-
// UI Field for custom actions in list view
|
|
1393
|
-
{
|
|
1394
|
-
name: "actions",
|
|
1395
|
-
type: "ui",
|
|
1396
|
-
admin: {
|
|
1397
|
-
components: {
|
|
1398
|
-
Cell: "payload-plugin-newsletter/components#ActionsCell",
|
|
1399
|
-
Field: "payload-plugin-newsletter/components#EmptyField"
|
|
1400
|
-
},
|
|
1401
|
-
disableListColumn: false
|
|
1402
|
-
}
|
|
1403
1397
|
}
|
|
1404
1398
|
],
|
|
1405
1399
|
hooks: {
|
|
@@ -1445,6 +1439,51 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1445
1439
|
req.payload.logger.error("Failed to create broadcast in provider:", error);
|
|
1446
1440
|
return doc;
|
|
1447
1441
|
}
|
|
1442
|
+
},
|
|
1443
|
+
// Hook to send when published
|
|
1444
|
+
async ({ doc, operation, previousDoc, req }) => {
|
|
1445
|
+
if (operation !== "update") return doc;
|
|
1446
|
+
const wasUnpublished = !previousDoc?._status || previousDoc._status === "draft";
|
|
1447
|
+
const isNowPublished = doc._status === "published";
|
|
1448
|
+
if (wasUnpublished && isNowPublished && doc.providerId) {
|
|
1449
|
+
if (doc.status === "sent" || doc.status === "sending") {
|
|
1450
|
+
return doc;
|
|
1451
|
+
}
|
|
1452
|
+
try {
|
|
1453
|
+
const broadcastConfig = pluginConfig.providers?.broadcast;
|
|
1454
|
+
const resendConfig = pluginConfig.providers?.resend;
|
|
1455
|
+
if (!broadcastConfig && !resendConfig) {
|
|
1456
|
+
req.payload.logger.error("No provider configured for sending");
|
|
1457
|
+
return doc;
|
|
1458
|
+
}
|
|
1459
|
+
if (broadcastConfig) {
|
|
1460
|
+
const { BroadcastApiProvider: BroadcastApiProvider2 } = await Promise.resolve().then(() => (init_broadcast2(), broadcast_exports));
|
|
1461
|
+
const provider = new BroadcastApiProvider2(broadcastConfig);
|
|
1462
|
+
await provider.send(doc.providerId);
|
|
1463
|
+
}
|
|
1464
|
+
await req.payload.update({
|
|
1465
|
+
collection: "broadcasts",
|
|
1466
|
+
id: doc.id,
|
|
1467
|
+
data: {
|
|
1468
|
+
status: "sending" /* SENDING */,
|
|
1469
|
+
sentAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1470
|
+
},
|
|
1471
|
+
req
|
|
1472
|
+
});
|
|
1473
|
+
req.payload.logger.info(`Broadcast ${doc.id} sent successfully`);
|
|
1474
|
+
} catch (error) {
|
|
1475
|
+
req.payload.logger.error(`Failed to send broadcast ${doc.id}:`, error);
|
|
1476
|
+
await req.payload.update({
|
|
1477
|
+
collection: "broadcasts",
|
|
1478
|
+
id: doc.id,
|
|
1479
|
+
data: {
|
|
1480
|
+
status: "failed" /* FAILED */
|
|
1481
|
+
},
|
|
1482
|
+
req
|
|
1483
|
+
});
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
return doc;
|
|
1448
1487
|
}
|
|
1449
1488
|
],
|
|
1450
1489
|
// Sync updates with provider
|