backend-manager 5.0.159 → 5.0.160
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
|
@@ -14,6 +14,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
14
14
|
- `Fixed` for any bug fixes.
|
|
15
15
|
- `Security` in case of vulnerabilities.
|
|
16
16
|
|
|
17
|
+
# [5.0.160] - 2026-03-18
|
|
18
|
+
### Added
|
|
19
|
+
- Beehiiv `resolveSegmentIds()` — fetches segments from API, builds name→ID cache (same pattern as SendGrid)
|
|
20
|
+
- Beehiiv segment resolution in `sendCampaign()` — SSOT keys auto-translate to Beehiiv segment IDs
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- Beehiiv `createPost()` now receives resolved segment IDs instead of raw SSOT keys
|
|
24
|
+
|
|
17
25
|
# [5.0.159] - 2026-03-18
|
|
18
26
|
### Added
|
|
19
27
|
- Audience-specific email discount codes: `UPGRADE15`, `COMEBACK20`, `MISSYOU25`, `TRYAGAIN10` with eligibility validation per user
|
package/package.json
CHANGED
|
@@ -11,6 +11,12 @@ class ServeCommand extends BaseCommand {
|
|
|
11
11
|
const port = self.argv.port || self.argv?._?.[1] || '5000';
|
|
12
12
|
const projectDir = self.firebaseProjectPath;
|
|
13
13
|
|
|
14
|
+
// Check for port conflicts before starting server
|
|
15
|
+
const canProceed = await this.checkAndKillBlockingProcesses({ serving: parseInt(port, 10) });
|
|
16
|
+
if (!canProceed) {
|
|
17
|
+
throw new Error('Port conflicts could not be resolved');
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
// Start BEM watcher in background
|
|
15
21
|
const watcher = new WatchCommand(self);
|
|
16
22
|
watcher.startBackground();
|
|
@@ -317,7 +317,14 @@ Marketing.prototype.sendCampaign = async function (settings) {
|
|
|
317
317
|
};
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
-
|
|
320
|
+
if (useProviders.includes('beehiiv') && self.providers.beehiiv) {
|
|
321
|
+
const segmentIdMap = await beehiivProvider.resolveSegmentIds();
|
|
322
|
+
|
|
323
|
+
resolvedSegments.beehiiv = {
|
|
324
|
+
segments: (resolvedSettings.segments || []).map(key => segmentIdMap[key] || key).filter(Boolean),
|
|
325
|
+
excludeSegments: (resolvedSettings.excludeSegments || []).map(key => segmentIdMap[key] || key).filter(Boolean),
|
|
326
|
+
};
|
|
327
|
+
}
|
|
321
328
|
|
|
322
329
|
assistant.log('Marketing.sendCampaign():', {
|
|
323
330
|
name: resolvedSettings.name,
|
|
@@ -349,8 +356,8 @@ Marketing.prototype.sendCampaign = async function (settings) {
|
|
|
349
356
|
preheader: resolvedSettings.preheader,
|
|
350
357
|
content: contentHtml,
|
|
351
358
|
sendAt: settings.sendAt,
|
|
352
|
-
segments:
|
|
353
|
-
excludeSegments:
|
|
359
|
+
segments: resolvedSegments.beehiiv?.segments || [],
|
|
360
|
+
excludeSegments: resolvedSegments.beehiiv?.excludeSegments || [],
|
|
354
361
|
})
|
|
355
362
|
.then((r) => { results.beehiiv = r; })
|
|
356
363
|
.catch((e) => { results.beehiiv = { success: false, error: e.message }; })
|
|
@@ -274,6 +274,47 @@ function buildFields(userDoc) {
|
|
|
274
274
|
return fields;
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
+
// Cached segment name → Beehiiv segment ID map
|
|
278
|
+
let _segmentIdCache = null;
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Fetch segment definitions from Beehiiv and build a name → id map.
|
|
282
|
+
* Segments are created by OMEGA with names matching the SSOT keys in constants.js.
|
|
283
|
+
* Cached in memory for the lifetime of the process.
|
|
284
|
+
*
|
|
285
|
+
* @returns {object} Map of segment name → Beehiiv segment ID
|
|
286
|
+
*/
|
|
287
|
+
async function resolveSegmentIds() {
|
|
288
|
+
if (_segmentIdCache) {
|
|
289
|
+
return _segmentIdCache;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const publicationId = await getPublicationId();
|
|
293
|
+
|
|
294
|
+
if (!publicationId) {
|
|
295
|
+
return {};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
try {
|
|
299
|
+
const data = await fetch(`${BASE_URL}/publications/${publicationId}/segments?limit=100`, {
|
|
300
|
+
response: 'json',
|
|
301
|
+
headers: headers(),
|
|
302
|
+
timeout: 10000,
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
_segmentIdCache = {};
|
|
306
|
+
|
|
307
|
+
for (const segment of (data.data || [])) {
|
|
308
|
+
_segmentIdCache[segment.name] = segment.id;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return _segmentIdCache;
|
|
312
|
+
} catch (e) {
|
|
313
|
+
console.error('Beehiiv resolveSegmentIds error:', e);
|
|
314
|
+
return {};
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
277
318
|
// --- Campaigns (Posts) ---
|
|
278
319
|
|
|
279
320
|
/**
|
|
@@ -362,6 +403,9 @@ async function createPost(options) {
|
|
|
362
403
|
}
|
|
363
404
|
|
|
364
405
|
module.exports = {
|
|
406
|
+
// Resolution
|
|
407
|
+
resolveSegmentIds,
|
|
408
|
+
|
|
365
409
|
// Contacts
|
|
366
410
|
addContact,
|
|
367
411
|
removeContact,
|