payload-plugin-newsletter 0.21.4 → 0.22.0

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 CHANGED
@@ -1,3 +1,17 @@
1
+ ## [0.22.0] - 2025-08-07
2
+
3
+ ### Changed
4
+ - **Improved Broadcast sync**: Now uses proper subscribe/unsubscribe endpoints
5
+ - Uses `/api/v1/subscribers/unsubscribe.json` for unsubscribing (sets `unsubscribed_at` timestamp)
6
+ - Uses `/api/v1/subscribers.json` for both new subscriptions and resubscriptions
7
+ - Removed language tagging as per user preference
8
+ - Simplified resubscription flow - no special error handling needed
9
+ - **Better compliance tracking**: Broadcast now properly tracks unsubscribe timestamps for compliance
10
+
11
+ ### Fixed
12
+ - Fixed Broadcast provider to properly handle subscription status changes
13
+ - Removed unnecessary contact existence checks (Broadcast API handles this gracefully)
14
+
1
15
  ## [0.21.4] - 2025-08-07
2
16
 
3
17
  ### Fixed
package/dist/server.js CHANGED
@@ -1240,13 +1240,11 @@ var BroadcastProvider = class {
1240
1240
  email: contact.email,
1241
1241
  first_name: firstName || void 0,
1242
1242
  last_name: lastName || void 0,
1243
- tags: [`lang:${contact.locale || "en"}`],
1244
- is_active: contact.subscriptionStatus === "active",
1245
1243
  source: contact.source
1246
1244
  }
1247
1245
  })
1248
1246
  });
1249
- if (!response.ok) {
1247
+ if (!response.ok && response.status !== 201) {
1250
1248
  const error = await response.text();
1251
1249
  throw new Error(`Broadcast API error: ${response.status} - ${error}`);
1252
1250
  }
@@ -1260,44 +1258,39 @@ var BroadcastProvider = class {
1260
1258
  }
1261
1259
  async updateContact(contact) {
1262
1260
  try {
1263
- const searchResponse = await fetch(
1264
- `${this.apiUrl}/api/v1/subscribers/find.json?email=${encodeURIComponent(contact.email)}`,
1265
- {
1261
+ const [firstName, ...lastNameParts] = (contact.name || "").split(" ");
1262
+ const lastName = lastNameParts.join(" ");
1263
+ if (contact.subscriptionStatus === "unsubscribed") {
1264
+ const response2 = await fetch(`${this.apiUrl}/api/v1/subscribers/unsubscribe.json`, {
1265
+ method: "POST",
1266
1266
  headers: {
1267
- "Authorization": `Bearer ${this.token}`
1268
- }
1267
+ "Authorization": `Bearer ${this.token}`,
1268
+ "Content-Type": "application/json"
1269
+ },
1270
+ body: JSON.stringify({ email: contact.email })
1271
+ });
1272
+ if (!response2.ok) {
1273
+ const error = await response2.text();
1274
+ throw new Error(`Broadcast API error: ${response2.status} - ${error}`);
1269
1275
  }
1270
- );
1271
- if (!searchResponse.ok) {
1272
- await this.addContact(contact);
1273
- return;
1274
- }
1275
- const existingContact = await searchResponse.json();
1276
- if (!existingContact || !existingContact.id) {
1277
- await this.addContact(contact);
1278
1276
  return;
1279
1277
  }
1280
- const [firstName, ...lastNameParts] = (contact.name || "").split(" ");
1281
- const lastName = lastNameParts.join(" ");
1282
1278
  const response = await fetch(`${this.apiUrl}/api/v1/subscribers.json`, {
1283
- method: "PATCH",
1279
+ method: "POST",
1284
1280
  headers: {
1285
1281
  "Authorization": `Bearer ${this.token}`,
1286
1282
  "Content-Type": "application/json"
1287
1283
  },
1288
1284
  body: JSON.stringify({
1289
- email: contact.email,
1290
- // Email at root level to identify the subscriber
1291
1285
  subscriber: {
1286
+ email: contact.email,
1292
1287
  first_name: firstName || void 0,
1293
1288
  last_name: lastName || void 0,
1294
- tags: [`lang:${contact.locale || "en"}`],
1295
- is_active: contact.subscriptionStatus === "active",
1296
1289
  source: contact.source
1297
1290
  }
1298
1291
  })
1299
1292
  });
1300
- if (!response.ok) {
1293
+ if (!response.ok && response.status !== 201) {
1301
1294
  const error = await response.text();
1302
1295
  throw new Error(`Broadcast API error: ${response.status} - ${error}`);
1303
1296
  }
@@ -1311,22 +1304,7 @@ var BroadcastProvider = class {
1311
1304
  }
1312
1305
  async removeContact(email) {
1313
1306
  try {
1314
- const searchResponse = await fetch(
1315
- `${this.apiUrl}/api/v1/subscribers/find.json?email=${encodeURIComponent(email)}`,
1316
- {
1317
- headers: {
1318
- "Authorization": `Bearer ${this.token}`
1319
- }
1320
- }
1321
- );
1322
- if (!searchResponse.ok) {
1323
- return;
1324
- }
1325
- const contact = await searchResponse.json();
1326
- if (!contact || !contact.id) {
1327
- return;
1328
- }
1329
- const response = await fetch(`${this.apiUrl}/api/v1/subscribers/deactivate.json`, {
1307
+ const response = await fetch(`${this.apiUrl}/api/v1/subscribers/unsubscribe.json`, {
1330
1308
  method: "POST",
1331
1309
  headers: {
1332
1310
  "Authorization": `Bearer ${this.token}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payload-plugin-newsletter",
3
- "version": "0.21.4",
3
+ "version": "0.22.0",
4
4
  "description": "Complete newsletter management plugin for Payload CMS with subscriber management, magic link authentication, and email service integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",