mcp-meta-ads-incrementality 0.2.1 → 0.2.2

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.
@@ -0,0 +1,616 @@
1
+ /**
2
+ * URL-tags tools — read and update the `url_tags` query-string fragment that
3
+ * Meta appends to ad clickthrough URLs.
4
+ *
5
+ * Why a thin Graph-API client instead of the SDK: the SDK adapter in this repo
6
+ * is shaped around insights cursors. URL-tags reads/writes are simple REST
7
+ * calls, so we hit the Graph API directly via fetch.
8
+ *
9
+ * Update strategy: create-then-rebind. We tried `POST /{ad-id}` with an
10
+ * inline creative override (`creative={creative_id, url_tags}`) — Meta returns
11
+ * success but silently no-ops, leaving the ad on the original creative.
12
+ * Verified empirically on ad 120243275305000447 (2026-05-05): POST returned
13
+ * success, read-back showed url_tags unchanged. Meta creatives are effectively
14
+ * immutable, so the working pattern is:
15
+ * 1. Read the existing creative's object_story_id (Page-post reference).
16
+ * 2. POST /act_X/adcreatives with same object_story_id + new url_tags →
17
+ * yields a new creative_id.
18
+ * 3. POST /{ad-id} with creative_id=<new> to rebind.
19
+ * The ad-id is unchanged. Meta may briefly re-review the ad.
20
+ */
21
+ import { graphGet, graphPost } from '../lib/graph.js';
22
+ export async function listAdsInCampaign(campaignId, accessToken) {
23
+ const all = [];
24
+ let after;
25
+ do {
26
+ const params = {
27
+ fields: 'id,name,status,effective_status,campaign_id,creative{id}',
28
+ limit: '100',
29
+ };
30
+ if (after)
31
+ params.after = after;
32
+ const page = await graphGet(`${campaignId}/ads`, accessToken, params);
33
+ for (const ad of page.data) {
34
+ all.push({
35
+ id: ad.id,
36
+ name: ad.name,
37
+ status: ad.status,
38
+ effective_status: ad.effective_status,
39
+ campaign_id: ad.campaign_id,
40
+ creative_id: ad.creative?.id ?? '',
41
+ });
42
+ }
43
+ after = page.paging?.next ? page.paging.cursors?.after : undefined;
44
+ } while (after);
45
+ return all;
46
+ }
47
+ async function fetchAdsetLearningStage(adsetId, accessToken) {
48
+ if (!adsetId)
49
+ return null;
50
+ try {
51
+ const r = await graphGet(adsetId, accessToken, { fields: 'learning_stage_info' });
52
+ if (!r.learning_stage_info)
53
+ return null;
54
+ return {
55
+ status: r.learning_stage_info.status ?? null,
56
+ last_significant_edit_ts: r.learning_stage_info.last_significant_edit_ts ?? null,
57
+ };
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ }
63
+ export async function getAdUrlTags(adId, accessToken) {
64
+ const ad = await graphGet(adId, accessToken, {
65
+ fields: 'id,name,account_id,campaign_id,adset_id,campaign{id,name},creative{id,url_tags,object_story_id,effective_object_story_id,object_story_spec{link_data{link},video_data{call_to_action}}}',
66
+ });
67
+ const link = ad.creative?.object_story_spec?.link_data?.link ??
68
+ ad.creative?.object_story_spec?.video_data?.call_to_action?.value?.link ??
69
+ null;
70
+ const learning = await fetchAdsetLearningStage(ad.adset_id ?? null, accessToken);
71
+ return {
72
+ ad_id: ad.id,
73
+ ad_name: ad.name,
74
+ account_id: ad.account_id ?? '',
75
+ campaign_id: ad.campaign_id,
76
+ campaign_name: ad.campaign?.name ?? '',
77
+ creative_id: ad.creative?.id ?? '',
78
+ object_story_id: ad.creative?.object_story_id ?? ad.creative?.effective_object_story_id ?? null,
79
+ url_tags: ad.creative?.url_tags ?? null,
80
+ link,
81
+ learning_stage_info: learning,
82
+ };
83
+ }
84
+ /**
85
+ * Update url_tags via create-then-rebind WITH social-feedback preservation.
86
+ *
87
+ * The Meta UI itself forks a new creative when url_tags changes (verified by
88
+ * inspecting Ads Manager network calls 2026-05-05 — the internal payload
89
+ * shows action_metadata.type=DUPLICATION_UPGRADE and
90
+ * enable_social_feedback_preservation=true). Meta's relearning trigger is
91
+ * field-aware: changes to url_tags alone are documented as not resetting
92
+ * learning, when social-feedback preservation carries forward.
93
+ *
94
+ * This implementation replicates that behavior on the public Marketing API:
95
+ * 1. Read current creative → get object_story_id, account_id, learning_stage_info.
96
+ * 2. POST /act_X/adcreatives with {object_story_id, url_tags,
97
+ * object_story_spec.use_page_actor_override flag implicit} — same
98
+ * Page-post reference, only url_tags differs.
99
+ * 3. POST /{ad-id} with creative_id=<new>.
100
+ * 4. Re-read learning_stage_info; compare last_significant_edit_ts.
101
+ *
102
+ * If last_significant_edit_ts is unchanged, Meta did not consider the edit
103
+ * significant — confirming learning is preserved. If it advanced to roughly
104
+ * the time of our write, Meta did trigger a relearning event and the writer
105
+ * should be considered unsafe for active ads.
106
+ */
107
+ export async function updateAdUrlTags(adId, newUrlTags, accessToken, dryRun) {
108
+ const before = await getAdUrlTags(adId, accessToken);
109
+ if (dryRun) {
110
+ return {
111
+ ad_id: before.ad_id,
112
+ ad_name: before.ad_name,
113
+ previous_url_tags: before.url_tags,
114
+ new_url_tags: newUrlTags,
115
+ previous_creative_id: before.creative_id,
116
+ new_creative_id: '',
117
+ changed: before.url_tags !== newUrlTags,
118
+ learning_before: before.learning_stage_info,
119
+ learning_after: null,
120
+ significant_edit_triggered: null,
121
+ };
122
+ }
123
+ if (before.url_tags === newUrlTags) {
124
+ return {
125
+ ad_id: before.ad_id,
126
+ ad_name: before.ad_name,
127
+ previous_url_tags: before.url_tags,
128
+ new_url_tags: newUrlTags,
129
+ previous_creative_id: before.creative_id,
130
+ new_creative_id: before.creative_id,
131
+ changed: false,
132
+ learning_before: before.learning_stage_info,
133
+ learning_after: before.learning_stage_info,
134
+ significant_edit_triggered: false,
135
+ };
136
+ }
137
+ if (!before.object_story_id) {
138
+ throw new Error(`Ad ${adId} creative ${before.creative_id} has no object_story_id; ` +
139
+ `create-then-rebind path requires a Page-post-backed creative.`);
140
+ }
141
+ if (!before.account_id) {
142
+ throw new Error(`Ad ${adId} did not return account_id.`);
143
+ }
144
+ const created = await graphPost(`act_${before.account_id}/adcreatives`, accessToken, {
145
+ object_story_id: before.object_story_id,
146
+ url_tags: newUrlTags,
147
+ name: `${before.ad_name} — url_tags ${new Date().toISOString().slice(0, 10)}`,
148
+ });
149
+ await graphPost(adId, accessToken, {
150
+ creative: JSON.stringify({ creative_id: created.id }),
151
+ });
152
+ const after = await getAdUrlTags(adId, accessToken);
153
+ const beforeTs = before.learning_stage_info?.last_significant_edit_ts ?? null;
154
+ const afterTs = after.learning_stage_info?.last_significant_edit_ts ?? null;
155
+ const significantEditTriggered = beforeTs !== null && afterTs !== null ? afterTs > beforeTs : null;
156
+ return {
157
+ ad_id: after.ad_id,
158
+ ad_name: after.ad_name,
159
+ previous_url_tags: before.url_tags,
160
+ new_url_tags: after.url_tags ?? newUrlTags,
161
+ previous_creative_id: before.creative_id,
162
+ new_creative_id: after.creative_id,
163
+ changed: before.creative_id !== after.creative_id || before.url_tags !== after.url_tags,
164
+ learning_before: before.learning_stage_info,
165
+ learning_after: after.learning_stage_info,
166
+ significant_edit_triggered: significantEditTriggered,
167
+ };
168
+ }
169
+ /**
170
+ * Fetch asset_customization_rules for a creative. Returns the raw array (may be
171
+ * empty/undefined). Used by the rebind safety check — these are the per-placement
172
+ * image rules that get silently dropped if the create-then-rebind path doesn't
173
+ * carry them through.
174
+ */
175
+ async function fetchCustomizationRules(creativeId, accessToken) {
176
+ try {
177
+ const r = await graphGet(creativeId, accessToken, { fields: 'asset_feed_spec{asset_customization_rules}' });
178
+ return r.asset_feed_spec?.asset_customization_rules ?? [];
179
+ }
180
+ catch {
181
+ return [];
182
+ }
183
+ }
184
+ /**
185
+ * Swap the lead form on an ad by rebuilding its creative with a new form_id.
186
+ *
187
+ * Meta creatives are immutable, so we create-then-rebind:
188
+ * 1. Read the ad's current creative (full spec — handles both legacy
189
+ * object_story_spec and modern asset_feed_spec creatives).
190
+ * 2. POST /act_X/adcreatives with the same image/text spec but new
191
+ * lead_gen_form_id inside the SIGN_UP CTA.
192
+ * 3. POST /{ad-id} with creative_id=<new> to rebind.
193
+ *
194
+ * The ad-id is unchanged. Meta may briefly re-review.
195
+ */
196
+ export async function swapAdLeadForm(adId, newFormId, accessToken, dryRun, ctaTypeOverride) {
197
+ const fields = 'id,name,account_id,creative{' +
198
+ 'id,name,url_tags,object_story_id,effective_object_story_id,' +
199
+ 'object_story_spec{page_id,link_data{link,message,name,description,image_hash,call_to_action}},' +
200
+ 'asset_feed_spec{images,bodies,titles,descriptions,link_urls,call_to_action_types,call_to_actions,ad_formats,asset_customization_rules}' +
201
+ '}';
202
+ const ad = await graphGet(adId, accessToken, { fields });
203
+ const creative = ad.creative;
204
+ if (!creative)
205
+ throw new Error(`Ad ${adId}: no creative attached.`);
206
+ if (!ad.account_id)
207
+ throw new Error(`Ad ${adId}: response missing account_id.`);
208
+ const previousFormId = creative.object_story_spec?.link_data?.call_to_action?.value?.lead_gen_form_id ??
209
+ creative.asset_feed_spec?.call_to_actions?.[0]?.value?.lead_gen_form_id ??
210
+ null;
211
+ const existingCtaType = creative.object_story_spec?.link_data?.call_to_action?.type ??
212
+ creative.asset_feed_spec?.call_to_actions?.[0]?.type ??
213
+ null;
214
+ const ctaType = ctaTypeOverride ?? existingCtaType ?? 'SIGN_UP';
215
+ const isAssetFeed = !!creative.asset_feed_spec && (creative.asset_feed_spec.bodies?.length ?? 0) > 0;
216
+ const mode = isAssetFeed ? 'asset_feed_spec' : 'object_story_spec';
217
+ if (dryRun) {
218
+ return {
219
+ ad_id: ad.id,
220
+ ad_name: ad.name,
221
+ previous_creative_id: creative.id,
222
+ new_creative_id: '',
223
+ previous_form_id: previousFormId,
224
+ new_form_id: newFormId,
225
+ mode,
226
+ changed: previousFormId !== newFormId,
227
+ };
228
+ }
229
+ if (previousFormId === newFormId) {
230
+ return {
231
+ ad_id: ad.id,
232
+ ad_name: ad.name,
233
+ previous_creative_id: creative.id,
234
+ new_creative_id: creative.id,
235
+ previous_form_id: previousFormId,
236
+ new_form_id: newFormId,
237
+ mode,
238
+ changed: false,
239
+ };
240
+ }
241
+ const acct = ad.account_id.startsWith('act_') ? ad.account_id : `act_${ad.account_id}`;
242
+ const newCta = { type: ctaType, value: { lead_gen_form_id: newFormId } };
243
+ const body = {
244
+ name: `${creative.name ?? ad.name} — form-swap ${new Date().toISOString().slice(0, 10)}`,
245
+ };
246
+ if (creative.url_tags)
247
+ body.url_tags = creative.url_tags;
248
+ if (isAssetFeed) {
249
+ const afs = creative.asset_feed_spec;
250
+ const rebuilt = {
251
+ images: afs.images ?? [],
252
+ bodies: afs.bodies ?? [],
253
+ link_urls: afs.link_urls ?? [],
254
+ ad_formats: afs.ad_formats ?? ['SINGLE_IMAGE'],
255
+ call_to_action_types: [ctaType],
256
+ call_to_actions: [newCta],
257
+ };
258
+ if (afs.titles?.length)
259
+ rebuilt.titles = afs.titles;
260
+ if (afs.descriptions?.length)
261
+ rebuilt.descriptions = afs.descriptions;
262
+ if (afs.asset_customization_rules?.length) {
263
+ rebuilt.asset_customization_rules = afs.asset_customization_rules;
264
+ }
265
+ const oss = creative.object_story_spec;
266
+ const ossOut = { page_id: oss?.page_id };
267
+ if (oss?.instagram_actor_id)
268
+ ossOut.instagram_actor_id = oss.instagram_actor_id;
269
+ body.object_story_spec = JSON.stringify(ossOut);
270
+ body.asset_feed_spec = JSON.stringify(rebuilt);
271
+ }
272
+ else {
273
+ const oss = creative.object_story_spec;
274
+ const ld = oss?.link_data;
275
+ if (!oss?.page_id || !ld?.link || !ld?.message) {
276
+ throw new Error(`Ad ${adId} creative ${creative.id}: legacy creative missing page_id/link/message — cannot rebuild for form swap.`);
277
+ }
278
+ const linkData = {
279
+ link: ld.link,
280
+ message: ld.message,
281
+ call_to_action: newCta,
282
+ };
283
+ if (ld.image_hash)
284
+ linkData.image_hash = ld.image_hash;
285
+ if (ld.name)
286
+ linkData.name = ld.name;
287
+ if (ld.description)
288
+ linkData.description = ld.description;
289
+ const ossOut = { page_id: oss.page_id, link_data: linkData };
290
+ if (oss.instagram_actor_id)
291
+ ossOut.instagram_actor_id = oss.instagram_actor_id;
292
+ body.object_story_spec = JSON.stringify(ossOut);
293
+ }
294
+ const created = await graphPost(`${acct}/adcreatives`, accessToken, body);
295
+ await graphPost(adId, accessToken, {
296
+ creative: JSON.stringify({ creative_id: created.id }),
297
+ });
298
+ return {
299
+ ad_id: ad.id,
300
+ ad_name: ad.name,
301
+ previous_creative_id: creative.id,
302
+ new_creative_id: created.id,
303
+ previous_form_id: previousFormId,
304
+ new_form_id: newFormId,
305
+ mode,
306
+ changed: true,
307
+ };
308
+ }
309
+ /**
310
+ * Rebind an ad to a different creative_id. Atomic. ad_id stays stable.
311
+ * Use with createAdCreative to do full ad rebuilds (e.g. swap form + rebuild
312
+ * text content) without touching the ad_id.
313
+ *
314
+ * Safety check: if the OLD creative has `asset_customization_rules` (per-placement
315
+ * image rules set in Ads Manager UI) and the NEW creative does not carry them
316
+ * forward, the rebind is REFUSED. This catches the 2026-05-14 RDR class of bug
317
+ * where multi-variant headline writes silently flattened custom placements by image.
318
+ * Pass `force=true` to override (e.g. when the new creative deliberately replaces
319
+ * the placement rules).
320
+ */
321
+ export async function rebindAdCreative(adId, newCreativeId, accessToken, dryRun, force = false) {
322
+ const before = await graphGet(adId, accessToken, { fields: 'id,name,creative{id}' });
323
+ const previousId = before.creative?.id ?? '';
324
+ if (dryRun || previousId === newCreativeId) {
325
+ return {
326
+ ad_id: before.id,
327
+ ad_name: before.name,
328
+ previous_creative_id: previousId,
329
+ new_creative_id: newCreativeId,
330
+ changed: previousId !== newCreativeId && !dryRun,
331
+ customization_rules_preserved: null,
332
+ };
333
+ }
334
+ let preserved = null;
335
+ if (previousId && !force) {
336
+ const [oldRules, newRules] = await Promise.all([
337
+ fetchCustomizationRules(previousId, accessToken),
338
+ fetchCustomizationRules(newCreativeId, accessToken),
339
+ ]);
340
+ if (oldRules.length > 0 && newRules.length === 0) {
341
+ throw new Error(`Refusing to rebind ad ${adId}: previous creative ${previousId} has ${oldRules.length} ` +
342
+ `asset_customization_rules (per-placement image rules set in Ads Manager UI), but new ` +
343
+ `creative ${newCreativeId} has none. Rebinding would silently drop custom placements ` +
344
+ `by image. Either (a) include asset_customization_rules in the new creative, or ` +
345
+ `(b) pass force=true if this drop is intentional.`);
346
+ }
347
+ preserved = oldRules.length === 0 ? null : newRules.length >= oldRules.length;
348
+ }
349
+ await graphPost(adId, accessToken, {
350
+ creative: JSON.stringify({ creative_id: newCreativeId }),
351
+ });
352
+ return {
353
+ ad_id: before.id,
354
+ ad_name: before.name,
355
+ previous_creative_id: previousId,
356
+ new_creative_id: newCreativeId,
357
+ changed: true,
358
+ customization_rules_preserved: preserved,
359
+ };
360
+ }
361
+ /**
362
+ * Edit text fields (primary texts / headlines / descriptions) on an ad's creative
363
+ * while PRESERVING images, videos, asset_customization_rules (per-placement image
364
+ * rules set in Ads Manager UI), call_to_actions, and link_urls.
365
+ *
366
+ * For asset_feed_spec ads: replaces only the specified text arrays. Refuses the
367
+ * edit if the existing asset_customization_rules reference per-text labels
368
+ * (body_label / title_label / description_label) and the new text count differs
369
+ * from the old — pass force=true to override (rules may end up referencing
370
+ * orphaned labels and break the placement targeting).
371
+ *
372
+ * For object_story_spec (legacy single-variant) ads: replaces link_data.message
373
+ * (single primary text), link_data.name (single headline), link_data.description.
374
+ * The messages/headlines/descriptions arrays must each have length ≤ 1 in that
375
+ * mode.
376
+ */
377
+ export async function editCreativeText(adId, edits, accessToken, dryRun, force = false) {
378
+ if (!edits.messages && !edits.headlines && !edits.descriptions) {
379
+ throw new Error('editCreativeText: provide at least one of messages, headlines, descriptions.');
380
+ }
381
+ // Note: Meta caps multi-variant asset_feed_spec at 5 entries per field, but DCO
382
+ // creatives with per-placement label customization can legitimately exceed this.
383
+ // We don't pre-validate the count — Meta will reject on POST if invalid.
384
+ // instagram_actor_id deprecated for reads in v22+. call_to_actions returns
385
+ // permission-denied on DCO-style creatives — fetch it best-effort, fall back
386
+ // to call_to_action_types on the rebuild.
387
+ const baseFields = 'id,name,account_id,creative{' +
388
+ 'id,name,url_tags,instagram_user_id,' +
389
+ 'object_story_spec{page_id,link_data{link,message,name,description,image_hash,call_to_action}},' +
390
+ 'asset_feed_spec{' +
391
+ 'images{hash,adlabels},videos{video_id,thumbnail_url,adlabels},' +
392
+ 'bodies{text,adlabels},titles{text,adlabels},descriptions{text,adlabels},' +
393
+ 'link_urls{website_url,adlabels},call_to_action_types,' +
394
+ 'ad_formats,optimization_type,asset_customization_rules' +
395
+ '}' +
396
+ '}';
397
+ let ad = await graphGet(adId, accessToken, { fields: baseFields });
398
+ // Try to also fetch call_to_actions; if denied, proceed without them.
399
+ try {
400
+ const withCtas = await graphGet(adId, accessToken, {
401
+ fields: 'creative{asset_feed_spec{call_to_actions}}',
402
+ });
403
+ const ctas = withCtas.creative?.asset_feed_spec?.call_to_actions;
404
+ if (ad.creative?.asset_feed_spec && ctas?.length) {
405
+ ad.creative.asset_feed_spec.call_to_actions = ctas;
406
+ }
407
+ }
408
+ catch {
409
+ // call_to_actions inaccessible (typical on DCO creatives) — skip.
410
+ }
411
+ const creative = ad.creative;
412
+ if (!creative)
413
+ throw new Error(`Ad ${adId}: no creative attached.`);
414
+ if (!ad.account_id)
415
+ throw new Error(`Ad ${adId}: response missing account_id.`);
416
+ const isAssetFeed = !!creative.asset_feed_spec && (creative.asset_feed_spec.bodies?.length ?? 0) > 0;
417
+ const mode = isAssetFeed ? 'asset_feed_spec' : 'object_story_spec';
418
+ const changedFields = [];
419
+ const acct = ad.account_id.startsWith('act_') ? ad.account_id : `act_${ad.account_id}`;
420
+ const body = {
421
+ name: `${creative.name ?? ad.name} — text-edit ${new Date().toISOString().slice(0, 10)}`,
422
+ };
423
+ if (creative.url_tags)
424
+ body.url_tags = creative.url_tags;
425
+ if (creative.instagram_user_id)
426
+ body.instagram_user_id = creative.instagram_user_id;
427
+ let rulesCount = 0;
428
+ if (isAssetFeed) {
429
+ const afs = creative.asset_feed_spec;
430
+ rulesCount = afs.asset_customization_rules?.length ?? 0;
431
+ // Refuse if rules reference labels we'd be replacing AND the new array length differs.
432
+ const rulesRefs = JSON.stringify(afs.asset_customization_rules ?? []);
433
+ const refsBody = rulesRefs.includes('"body_label"');
434
+ const refsTitle = rulesRefs.includes('"title_label"');
435
+ const refsDesc = rulesRefs.includes('"description_label"');
436
+ if (!force) {
437
+ if (edits.messages && refsBody && edits.messages.length !== (afs.bodies?.length ?? 0)) {
438
+ throw new Error(`Refusing to edit messages on ad ${adId}: asset_customization_rules reference body_label ` +
439
+ `and new length (${edits.messages.length}) differs from existing (${afs.bodies?.length ?? 0}). ` +
440
+ `Replacing would orphan label references. Pass force=true to override.`);
441
+ }
442
+ if (edits.headlines && refsTitle && edits.headlines.length !== (afs.titles?.length ?? 0)) {
443
+ throw new Error(`Refusing to edit headlines on ad ${adId}: asset_customization_rules reference title_label ` +
444
+ `and new length (${edits.headlines.length}) differs from existing (${afs.titles?.length ?? 0}). ` +
445
+ `Pass force=true to override.`);
446
+ }
447
+ if (edits.descriptions && refsDesc && edits.descriptions.length !== (afs.descriptions?.length ?? 0)) {
448
+ throw new Error(`Refusing to edit descriptions on ad ${adId}: asset_customization_rules reference ` +
449
+ `description_label and new length (${edits.descriptions.length}) differs from existing ` +
450
+ `(${afs.descriptions?.length ?? 0}). Pass force=true to override.`);
451
+ }
452
+ }
453
+ // Build replacement text arrays: keep adlabels[i] when present, swap text[i].
454
+ const swapText = (existing, newTexts, fieldName) => {
455
+ if (!newTexts)
456
+ return existing;
457
+ changedFields.push(fieldName);
458
+ return newTexts.map((text, i) => {
459
+ const out = { text };
460
+ const lbl = existing?.[i]?.adlabels;
461
+ if (lbl && Array.isArray(lbl) && lbl.length)
462
+ out.adlabels = lbl;
463
+ return out;
464
+ });
465
+ };
466
+ // Meta returns one entry per (asset, adlabel) pair, but rejects POSTs with
467
+ // duplicate asset values (subcode 1815629). Group by asset key and merge
468
+ // adlabels so the rebuilt spec has unique assets with multi-label arrays.
469
+ const dedupeAssets = (arr, keyFn) => {
470
+ if (!arr?.length)
471
+ return arr;
472
+ const byKey = new Map();
473
+ for (const a of arr) {
474
+ const k = keyFn(a);
475
+ if (!k)
476
+ continue;
477
+ const existing = byKey.get(k);
478
+ const labels = Array.isArray(a.adlabels) ? a.adlabels : [];
479
+ if (existing) {
480
+ const seen = new Set(existing.adlabels.map((l) => JSON.stringify(l)));
481
+ for (const l of labels) {
482
+ const s = JSON.stringify(l);
483
+ if (!seen.has(s)) {
484
+ existing.adlabels.push(l);
485
+ seen.add(s);
486
+ }
487
+ }
488
+ }
489
+ else {
490
+ byKey.set(k, { ...a, adlabels: [...labels] });
491
+ }
492
+ }
493
+ return Array.from(byKey.values());
494
+ };
495
+ const rebuilt = {};
496
+ const dedupedImages = dedupeAssets(afs.images, (a) => a.hash ?? '');
497
+ const dedupedVideos = dedupeAssets(afs.videos, (a) => a.video_id ?? '');
498
+ if (dedupedImages?.length)
499
+ rebuilt.images = dedupedImages;
500
+ if (dedupedVideos?.length)
501
+ rebuilt.videos = dedupedVideos;
502
+ if (afs.link_urls?.length)
503
+ rebuilt.link_urls = afs.link_urls;
504
+ if (afs.call_to_action_types?.length)
505
+ rebuilt.call_to_action_types = afs.call_to_action_types;
506
+ if (afs.call_to_actions?.length)
507
+ rebuilt.call_to_actions = afs.call_to_actions;
508
+ if (afs.ad_formats?.length)
509
+ rebuilt.ad_formats = afs.ad_formats;
510
+ if (afs.optimization_type)
511
+ rebuilt.optimization_type = afs.optimization_type;
512
+ const newBodies = swapText(afs.bodies, edits.messages, 'messages');
513
+ const newTitles = swapText(afs.titles, edits.headlines, 'headlines');
514
+ const newDescriptions = swapText(afs.descriptions, edits.descriptions, 'descriptions');
515
+ if (newBodies?.length)
516
+ rebuilt.bodies = newBodies;
517
+ if (newTitles?.length)
518
+ rebuilt.titles = newTitles;
519
+ if (newDescriptions?.length)
520
+ rebuilt.descriptions = newDescriptions;
521
+ if (afs.asset_customization_rules?.length) {
522
+ rebuilt.asset_customization_rules = afs.asset_customization_rules;
523
+ }
524
+ const oss = creative.object_story_spec;
525
+ const ossOut = { page_id: oss?.page_id };
526
+ if (oss?.link_data)
527
+ ossOut.link_data = oss.link_data;
528
+ body.object_story_spec = JSON.stringify(ossOut);
529
+ body.asset_feed_spec = JSON.stringify(rebuilt);
530
+ }
531
+ else {
532
+ // Legacy single-variant. Caller may pass 0 or 1 entry per field.
533
+ const oss = creative.object_story_spec;
534
+ const ld = oss?.link_data;
535
+ if (!oss?.page_id || !ld) {
536
+ throw new Error(`Ad ${adId} creative ${creative.id}: legacy creative missing page_id/link_data.`);
537
+ }
538
+ const linkData = { ...ld };
539
+ const setOne = (newArr, key, label) => {
540
+ if (!newArr)
541
+ return;
542
+ if (newArr.length > 1) {
543
+ throw new Error(`editCreativeText: ad ${adId} is single-variant (object_story_spec mode); ${label} ` +
544
+ `must have ≤1 entry (got ${newArr.length}). Use a multi-variant ad to mix headlines.`);
545
+ }
546
+ if (newArr.length === 1) {
547
+ linkData[key] = newArr[0];
548
+ changedFields.push(label);
549
+ }
550
+ };
551
+ setOne(edits.messages, 'message', 'messages');
552
+ setOne(edits.headlines, 'name', 'headlines');
553
+ setOne(edits.descriptions, 'description', 'descriptions');
554
+ const ossOut = { page_id: oss.page_id, link_data: linkData };
555
+ body.object_story_spec = JSON.stringify(ossOut);
556
+ }
557
+ if (changedFields.length === 0) {
558
+ return {
559
+ ad_id: ad.id,
560
+ ad_name: ad.name,
561
+ previous_creative_id: creative.id,
562
+ new_creative_id: creative.id,
563
+ mode,
564
+ changed_fields: [],
565
+ customization_rules_preserved: rulesCount,
566
+ };
567
+ }
568
+ if (dryRun) {
569
+ return {
570
+ ad_id: ad.id,
571
+ ad_name: ad.name,
572
+ previous_creative_id: creative.id,
573
+ new_creative_id: '',
574
+ mode,
575
+ changed_fields: changedFields,
576
+ customization_rules_preserved: rulesCount,
577
+ };
578
+ }
579
+ const created = await graphPost(`${acct}/adcreatives`, accessToken, body);
580
+ // Rebind WITHOUT force — relies on our own preservation; the safety check
581
+ // will catch any regression where we accidentally dropped customization rules.
582
+ await rebindAdCreative(adId, created.id, accessToken, false, false);
583
+ return {
584
+ ad_id: ad.id,
585
+ ad_name: ad.name,
586
+ previous_creative_id: creative.id,
587
+ new_creative_id: created.id,
588
+ mode,
589
+ changed_fields: changedFields,
590
+ customization_rules_preserved: rulesCount,
591
+ };
592
+ }
593
+ export async function renameAd(adId, newName, accessToken, dryRun) {
594
+ const before = await graphGet(adId, accessToken, {
595
+ fields: 'id,name',
596
+ });
597
+ if (dryRun || before.name === newName) {
598
+ return {
599
+ ad_id: before.id,
600
+ previous_name: before.name,
601
+ new_name: newName,
602
+ changed: !dryRun ? false : before.name !== newName,
603
+ };
604
+ }
605
+ await graphPost(adId, accessToken, { name: newName });
606
+ const after = await graphGet(adId, accessToken, {
607
+ fields: 'id,name',
608
+ });
609
+ return {
610
+ ad_id: after.id,
611
+ previous_name: before.name,
612
+ new_name: after.name,
613
+ changed: before.name !== after.name,
614
+ };
615
+ }
616
+ //# sourceMappingURL=url-tags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-tags.js","sourceRoot":"","sources":["../../src/tools/url-tags.ts"],"names":[],"mappings":"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"}