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,117 @@
1
+ export interface CreateCampaignInput {
2
+ account_id: string;
3
+ name: string;
4
+ objective: string;
5
+ status?: 'PAUSED' | 'ACTIVE';
6
+ special_ad_categories?: string[];
7
+ buying_type?: 'AUCTION' | 'RESERVED';
8
+ daily_budget?: number;
9
+ lifetime_budget?: number;
10
+ }
11
+ export interface CreateCampaignResult {
12
+ campaign_id: string;
13
+ account_id: string;
14
+ name: string;
15
+ status: string;
16
+ }
17
+ export declare function createCampaign(input: CreateCampaignInput, accessToken: string): Promise<CreateCampaignResult>;
18
+ export interface CreateAdSetInput {
19
+ account_id: string;
20
+ campaign_id: string;
21
+ name: string;
22
+ optimization_goal: string;
23
+ billing_event: 'IMPRESSIONS' | 'LINK_CLICKS' | 'POST_ENGAGEMENT' | 'THRUPLAY';
24
+ bid_strategy?: 'LOWEST_COST_WITHOUT_CAP' | 'LOWEST_COST_WITH_BID_CAP' | 'COST_CAP';
25
+ bid_amount?: number;
26
+ targeting: Record<string, unknown>;
27
+ status?: 'PAUSED' | 'ACTIVE';
28
+ daily_budget?: number;
29
+ lifetime_budget?: number;
30
+ promoted_object?: Record<string, unknown>;
31
+ destination_type?: string;
32
+ attribution_spec?: Array<{
33
+ event_type: string;
34
+ window_days: number;
35
+ }>;
36
+ is_incremental_attribution_enabled?: boolean;
37
+ start_time?: string;
38
+ end_time?: string;
39
+ }
40
+ export interface CreateAdSetResult {
41
+ adset_id: string;
42
+ account_id: string;
43
+ campaign_id: string;
44
+ name: string;
45
+ status: string;
46
+ }
47
+ export declare function createAdSet(input: CreateAdSetInput, accessToken: string): Promise<CreateAdSetResult>;
48
+ export interface CallToAction {
49
+ type: string;
50
+ value?: {
51
+ link?: string;
52
+ lead_gen_form_id?: string;
53
+ };
54
+ }
55
+ export interface CreateAdCreativeInput {
56
+ account_id: string;
57
+ name: string;
58
+ page_id: string;
59
+ image_hash?: string;
60
+ link: string;
61
+ /** Single primary text. Mutually exclusive with `messages`. */
62
+ message?: string;
63
+ /** Up to 5 primary texts (Flexible Ads / asset_feed_spec). */
64
+ messages?: string[];
65
+ /** Single headline. Mutually exclusive with `headlines`. */
66
+ headline?: string;
67
+ /** Up to 5 headlines. */
68
+ headlines?: string[];
69
+ /** Single description. Mutually exclusive with `descriptions`. */
70
+ description?: string;
71
+ /** Up to 5 descriptions. */
72
+ descriptions?: string[];
73
+ call_to_action?: CallToAction;
74
+ /** Shortcut: builds call_to_action={type:'SIGN_UP', value:{lead_gen_form_id}}. */
75
+ lead_gen_form_id?: string;
76
+ url_tags?: string;
77
+ /** Optional Instagram business account id for cross-posting. */
78
+ instagram_actor_id?: string;
79
+ }
80
+ export interface CreateAdCreativeResult {
81
+ creative_id: string;
82
+ account_id: string;
83
+ name: string;
84
+ /** Whether the creative used asset_feed_spec (multi-variant) or legacy object_story_spec. */
85
+ mode: 'asset_feed_spec' | 'object_story_spec';
86
+ }
87
+ export declare function createAdCreative(input: CreateAdCreativeInput, accessToken: string): Promise<CreateAdCreativeResult>;
88
+ export interface CreateAdInput {
89
+ account_id: string;
90
+ name: string;
91
+ adset_id: string;
92
+ creative_id: string;
93
+ status?: 'PAUSED' | 'ACTIVE';
94
+ }
95
+ export interface CreateAdResult {
96
+ ad_id: string;
97
+ account_id: string;
98
+ adset_id: string;
99
+ creative_id: string;
100
+ name: string;
101
+ status: string;
102
+ }
103
+ export declare function createAd(input: CreateAdInput, accessToken: string): Promise<CreateAdResult>;
104
+ export interface UploadImageInput {
105
+ account_id: string;
106
+ /** Base64-encoded image bytes. Prefer for tests / when caller already has bytes. */
107
+ image_bytes?: string;
108
+ /** Local file path. If provided, the file is read and base64-encoded. */
109
+ image_path?: string;
110
+ }
111
+ export interface UploadImageResult {
112
+ image_hash: string;
113
+ url: string;
114
+ account_id: string;
115
+ }
116
+ export declare function uploadImage(input: UploadImageInput, accessToken: string): Promise<UploadImageResult>;
117
+ //# sourceMappingURL=campaign-build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"campaign-build.d.ts","sourceRoot":"","sources":["../../src/tools/campaign-build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Tier 1 write tools: campaign / ad set / ad creative / ad / image upload.
3
+ *
4
+ * Defaults to PAUSED status on every object so MCP callers can build a full
5
+ * campaign hierarchy without accidentally going live. Callers must explicitly
6
+ * flip status=ACTIVE (today via meta_ads_update_object_status, or directly in
7
+ * Ads Manager) after review.
8
+ *
9
+ * Image uploads use Meta's `bytes` form field (base64-encoded image data) —
10
+ * keeps everything on the standard form-urlencoded POST shape used by lib/graph.
11
+ */
12
+ import { graphPost } from '../lib/graph.js';
13
+ function normalizeAccountId(accountId) {
14
+ return accountId.startsWith('act_') ? accountId : `act_${accountId}`;
15
+ }
16
+ export async function createCampaign(input, accessToken) {
17
+ const account = normalizeAccountId(input.account_id);
18
+ const status = input.status ?? 'PAUSED';
19
+ const body = {
20
+ name: input.name,
21
+ objective: input.objective,
22
+ status,
23
+ special_ad_categories: JSON.stringify(input.special_ad_categories ?? []),
24
+ buying_type: input.buying_type ?? 'AUCTION',
25
+ };
26
+ if (input.daily_budget !== undefined)
27
+ body.daily_budget = String(input.daily_budget);
28
+ if (input.lifetime_budget !== undefined)
29
+ body.lifetime_budget = String(input.lifetime_budget);
30
+ const res = await graphPost(`${account}/campaigns`, accessToken, body);
31
+ return { campaign_id: res.id, account_id: account, name: input.name, status };
32
+ }
33
+ export async function createAdSet(input, accessToken) {
34
+ if (input.daily_budget !== undefined && input.lifetime_budget !== undefined) {
35
+ throw new Error('createAdSet: pass daily_budget OR lifetime_budget, not both.');
36
+ }
37
+ if (input.daily_budget === undefined && input.lifetime_budget === undefined) {
38
+ throw new Error('createAdSet: budget required. Pass daily_budget or lifetime_budget, or set the budget on the parent campaign (CBO).');
39
+ }
40
+ const account = normalizeAccountId(input.account_id);
41
+ const status = input.status ?? 'PAUSED';
42
+ const body = {
43
+ name: input.name,
44
+ campaign_id: input.campaign_id,
45
+ optimization_goal: input.optimization_goal,
46
+ billing_event: input.billing_event,
47
+ bid_strategy: input.bid_strategy ?? 'LOWEST_COST_WITHOUT_CAP',
48
+ targeting: JSON.stringify(input.targeting),
49
+ status,
50
+ };
51
+ if (input.daily_budget !== undefined)
52
+ body.daily_budget = String(input.daily_budget);
53
+ if (input.lifetime_budget !== undefined)
54
+ body.lifetime_budget = String(input.lifetime_budget);
55
+ if (input.bid_amount !== undefined)
56
+ body.bid_amount = String(input.bid_amount);
57
+ if (input.promoted_object)
58
+ body.promoted_object = JSON.stringify(input.promoted_object);
59
+ if (input.destination_type)
60
+ body.destination_type = input.destination_type;
61
+ if (input.attribution_spec)
62
+ body.attribution_spec = JSON.stringify(input.attribution_spec);
63
+ if (input.is_incremental_attribution_enabled !== undefined) {
64
+ body.is_incremental_attribution_enabled = String(input.is_incremental_attribution_enabled);
65
+ }
66
+ if (input.start_time)
67
+ body.start_time = input.start_time;
68
+ if (input.end_time)
69
+ body.end_time = input.end_time;
70
+ const res = await graphPost(`${account}/adsets`, accessToken, body);
71
+ return {
72
+ adset_id: res.id,
73
+ account_id: account,
74
+ campaign_id: input.campaign_id,
75
+ name: input.name,
76
+ status,
77
+ };
78
+ }
79
+ function collectVariants(single, multi) {
80
+ const out = [];
81
+ if (multi && multi.length)
82
+ out.push(...multi);
83
+ else if (single)
84
+ out.push(single);
85
+ return out;
86
+ }
87
+ export async function createAdCreative(input, accessToken) {
88
+ const account = normalizeAccountId(input.account_id);
89
+ const messages = collectVariants(input.message, input.messages);
90
+ const headlines = collectVariants(input.headline, input.headlines);
91
+ const descriptions = collectVariants(input.description, input.descriptions);
92
+ if (messages.length === 0) {
93
+ throw new Error('createAdCreative: provide message or messages[].');
94
+ }
95
+ if (messages.length > 5 || headlines.length > 5 || descriptions.length > 5) {
96
+ throw new Error('createAdCreative: Meta caps primary texts / headlines / descriptions at 5 each.');
97
+ }
98
+ const callToAction = input.call_to_action ??
99
+ (input.lead_gen_form_id
100
+ ? { type: 'SIGN_UP', value: { lead_gen_form_id: input.lead_gen_form_id } }
101
+ : undefined);
102
+ const useAssetFeedSpec = messages.length > 1 || headlines.length > 1 || descriptions.length > 1;
103
+ const body = { name: input.name };
104
+ if (input.url_tags)
105
+ body.url_tags = input.url_tags;
106
+ if (useAssetFeedSpec) {
107
+ // Meta "Flexible Ads" / multi-variant mode (optimization_type=DEGREES_OF_FREEDOM).
108
+ // Shape learned from a UI-built ad on 2026-05-14:
109
+ // - image_hash + CTA + link live in object_story_spec.link_data (NOT in asset_feed_spec)
110
+ // - asset_feed_spec contains ONLY bodies/titles/descriptions + optimization_type
111
+ // - No images[], link_urls, call_to_action_types, call_to_actions, ad_formats in asset_feed_spec
112
+ if (!input.image_hash) {
113
+ throw new Error('createAdCreative: asset_feed_spec (multi-variant) mode requires image_hash.');
114
+ }
115
+ const linkData = {
116
+ link: input.link,
117
+ image_hash: input.image_hash,
118
+ };
119
+ if (callToAction)
120
+ linkData.call_to_action = callToAction;
121
+ const objectStorySpec = {
122
+ page_id: input.page_id,
123
+ link_data: linkData,
124
+ };
125
+ if (input.instagram_actor_id)
126
+ objectStorySpec.instagram_actor_id = input.instagram_actor_id;
127
+ const assetFeedSpec = {
128
+ bodies: messages.map((text) => ({ text })),
129
+ optimization_type: 'DEGREES_OF_FREEDOM',
130
+ };
131
+ if (headlines.length)
132
+ assetFeedSpec.titles = headlines.map((text) => ({ text }));
133
+ if (descriptions.length)
134
+ assetFeedSpec.descriptions = descriptions.map((text) => ({ text }));
135
+ body.object_story_spec = JSON.stringify(objectStorySpec);
136
+ body.asset_feed_spec = JSON.stringify(assetFeedSpec);
137
+ }
138
+ else {
139
+ const linkData = {
140
+ link: input.link,
141
+ message: messages[0],
142
+ };
143
+ if (input.image_hash)
144
+ linkData.image_hash = input.image_hash;
145
+ if (headlines.length)
146
+ linkData.name = headlines[0];
147
+ if (descriptions.length)
148
+ linkData.description = descriptions[0];
149
+ if (callToAction)
150
+ linkData.call_to_action = callToAction;
151
+ const objectStorySpec = {
152
+ page_id: input.page_id,
153
+ link_data: linkData,
154
+ };
155
+ if (input.instagram_actor_id)
156
+ objectStorySpec.instagram_actor_id = input.instagram_actor_id;
157
+ body.object_story_spec = JSON.stringify(objectStorySpec);
158
+ }
159
+ const res = await graphPost(`${account}/adcreatives`, accessToken, body);
160
+ return {
161
+ creative_id: res.id,
162
+ account_id: account,
163
+ name: input.name,
164
+ mode: useAssetFeedSpec ? 'asset_feed_spec' : 'object_story_spec',
165
+ };
166
+ }
167
+ export async function createAd(input, accessToken) {
168
+ const account = normalizeAccountId(input.account_id);
169
+ const status = input.status ?? 'PAUSED';
170
+ const body = {
171
+ name: input.name,
172
+ adset_id: input.adset_id,
173
+ creative: JSON.stringify({ creative_id: input.creative_id }),
174
+ status,
175
+ };
176
+ const res = await graphPost(`${account}/ads`, accessToken, body);
177
+ return {
178
+ ad_id: res.id,
179
+ account_id: account,
180
+ adset_id: input.adset_id,
181
+ creative_id: input.creative_id,
182
+ name: input.name,
183
+ status,
184
+ };
185
+ }
186
+ export async function uploadImage(input, accessToken) {
187
+ let bytes = input.image_bytes;
188
+ if (!bytes && input.image_path) {
189
+ const { readFileSync } = await import('node:fs');
190
+ bytes = readFileSync(input.image_path).toString('base64');
191
+ }
192
+ if (!bytes) {
193
+ throw new Error('uploadImage: provide image_bytes (base64) or image_path.');
194
+ }
195
+ const account = normalizeAccountId(input.account_id);
196
+ const res = await graphPost(`${account}/adimages`, accessToken, {
197
+ bytes,
198
+ });
199
+ const first = res.images ? Object.values(res.images)[0] : undefined;
200
+ if (!first) {
201
+ throw new Error('uploadImage: response missing images.bytes — Graph returned no hash.');
202
+ }
203
+ return { image_hash: first.hash, url: first.url, account_id: account };
204
+ }
205
+ //# sourceMappingURL=campaign-build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"campaign-build.js","sourceRoot":"","sources":["../../src/tools/campaign-build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ export type ObjectStatus = 'PAUSED' | 'ACTIVE' | 'ARCHIVED' | 'DELETED';
2
+ export interface UpdateObjectStatusInput {
3
+ object_id: string;
4
+ status: ObjectStatus;
5
+ }
6
+ export interface UpdateObjectStatusResult {
7
+ object_id: string;
8
+ status: ObjectStatus;
9
+ success: boolean;
10
+ }
11
+ export declare function updateObjectStatus(input: UpdateObjectStatusInput, accessToken: string): Promise<UpdateObjectStatusResult>;
12
+ export interface UpdateBudgetInput {
13
+ object_id: string;
14
+ daily_budget?: number;
15
+ lifetime_budget?: number;
16
+ }
17
+ export interface UpdateBudgetResult {
18
+ object_id: string;
19
+ daily_budget: number | null;
20
+ lifetime_budget: number | null;
21
+ success: boolean;
22
+ }
23
+ export declare function updateBudget(input: UpdateBudgetInput, accessToken: string): Promise<UpdateBudgetResult>;
24
+ export interface DeleteObjectInput {
25
+ object_id: string;
26
+ }
27
+ export interface DeleteObjectResult {
28
+ object_id: string;
29
+ success: boolean;
30
+ }
31
+ export declare function deleteObject(input: DeleteObjectInput, accessToken: string): Promise<DeleteObjectResult>;
32
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/tools/lifecycle.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAMxE,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB;AAOD,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,uBAAuB,EAC9B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,wBAAwB,CAAC,CASnC;AAMD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,YAAY,CAChC,KAAK,EAAE,iBAAiB,EACxB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC,CAmB7B;AAMD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,YAAY,CAChC,KAAK,EAAE,iBAAiB,EACxB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC,CAG7B"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Tier 3 + 4 lifecycle tools: status toggle, budget update, delete.
3
+ *
4
+ * Meta uses the same POST /{id} endpoint for any object (campaign, ad set, ad)
5
+ * with `status` or budget fields, and DELETE /{id} for removal. This module
6
+ * exposes one tool per concern; callers pass an object_id of any type.
7
+ */
8
+ import { graphDelete, graphPost } from '../lib/graph.js';
9
+ export async function updateObjectStatus(input, accessToken) {
10
+ const res = await graphPost(input.object_id, accessToken, {
11
+ status: input.status,
12
+ });
13
+ return {
14
+ object_id: input.object_id,
15
+ status: input.status,
16
+ success: res.success ?? false,
17
+ };
18
+ }
19
+ export async function updateBudget(input, accessToken) {
20
+ if (input.daily_budget === undefined && input.lifetime_budget === undefined) {
21
+ throw new Error('updateBudget: pass daily_budget or lifetime_budget.');
22
+ }
23
+ if (input.daily_budget !== undefined && input.lifetime_budget !== undefined) {
24
+ throw new Error('updateBudget: pass daily_budget OR lifetime_budget, not both.');
25
+ }
26
+ const body = {};
27
+ if (input.daily_budget !== undefined)
28
+ body.daily_budget = String(input.daily_budget);
29
+ if (input.lifetime_budget !== undefined)
30
+ body.lifetime_budget = String(input.lifetime_budget);
31
+ const res = await graphPost(input.object_id, accessToken, body);
32
+ return {
33
+ object_id: input.object_id,
34
+ daily_budget: input.daily_budget ?? null,
35
+ lifetime_budget: input.lifetime_budget ?? null,
36
+ success: res.success ?? false,
37
+ };
38
+ }
39
+ export async function deleteObject(input, accessToken) {
40
+ const res = await graphDelete(input.object_id, accessToken);
41
+ return { object_id: input.object_id, success: res.success ?? false };
42
+ }
43
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/tools/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAwBzD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAA8B,EAC9B,WAAmB;IAEnB,MAAM,GAAG,GAAG,MAAM,SAAS,CAAuB,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE;QAC9E,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC;IACH,OAAO;QACL,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,KAAK;KAC9B,CAAC;AACJ,CAAC;AAmBD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAwB,EACxB,WAAmB;IAEnB,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,IAAI,KAAK,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QAC5E,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,IAAI,KAAK,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QAC5E,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IAED,MAAM,IAAI,GAA2B,EAAE,CAAC;IACxC,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS;QAAE,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACrF,IAAI,KAAK,CAAC,eAAe,KAAK,SAAS;QAAE,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAE9F,MAAM,GAAG,GAAG,MAAM,SAAS,CAAuB,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IACtF,OAAO;QACL,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,IAAI;QACxC,eAAe,EAAE,KAAK,CAAC,eAAe,IAAI,IAAI;QAC9C,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,KAAK;KAC9B,CAAC;AACJ,CAAC;AAeD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAwB,EACxB,WAAmB;IAEnB,MAAM,GAAG,GAAG,MAAM,WAAW,CAAuB,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAClF,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,KAAK,EAAE,CAAC;AACvE,CAAC"}
@@ -0,0 +1,145 @@
1
+ export interface AdSummary {
2
+ id: string;
3
+ name: string;
4
+ status: string;
5
+ effective_status?: string;
6
+ campaign_id: string;
7
+ creative_id: string;
8
+ }
9
+ export declare function listAdsInCampaign(campaignId: string, accessToken: string): Promise<AdSummary[]>;
10
+ export interface LearningStageInfo {
11
+ status: string | null;
12
+ last_significant_edit_ts: number | null;
13
+ }
14
+ export interface AdUrlTagsInfo {
15
+ ad_id: string;
16
+ ad_name: string;
17
+ account_id: string;
18
+ campaign_id: string;
19
+ campaign_name: string;
20
+ creative_id: string;
21
+ object_story_id: string | null;
22
+ url_tags: string | null;
23
+ link: string | null;
24
+ learning_stage_info: LearningStageInfo | null;
25
+ }
26
+ export declare function getAdUrlTags(adId: string, accessToken: string): Promise<AdUrlTagsInfo>;
27
+ export interface UpdateAdUrlTagsResult {
28
+ ad_id: string;
29
+ ad_name: string;
30
+ previous_url_tags: string | null;
31
+ new_url_tags: string;
32
+ previous_creative_id: string;
33
+ new_creative_id: string;
34
+ changed: boolean;
35
+ learning_before: LearningStageInfo | null;
36
+ learning_after: LearningStageInfo | null;
37
+ significant_edit_triggered: boolean | null;
38
+ }
39
+ /**
40
+ * Update url_tags via create-then-rebind WITH social-feedback preservation.
41
+ *
42
+ * The Meta UI itself forks a new creative when url_tags changes (verified by
43
+ * inspecting Ads Manager network calls 2026-05-05 — the internal payload
44
+ * shows action_metadata.type=DUPLICATION_UPGRADE and
45
+ * enable_social_feedback_preservation=true). Meta's relearning trigger is
46
+ * field-aware: changes to url_tags alone are documented as not resetting
47
+ * learning, when social-feedback preservation carries forward.
48
+ *
49
+ * This implementation replicates that behavior on the public Marketing API:
50
+ * 1. Read current creative → get object_story_id, account_id, learning_stage_info.
51
+ * 2. POST /act_X/adcreatives with {object_story_id, url_tags,
52
+ * object_story_spec.use_page_actor_override flag implicit} — same
53
+ * Page-post reference, only url_tags differs.
54
+ * 3. POST /{ad-id} with creative_id=<new>.
55
+ * 4. Re-read learning_stage_info; compare last_significant_edit_ts.
56
+ *
57
+ * If last_significant_edit_ts is unchanged, Meta did not consider the edit
58
+ * significant — confirming learning is preserved. If it advanced to roughly
59
+ * the time of our write, Meta did trigger a relearning event and the writer
60
+ * should be considered unsafe for active ads.
61
+ */
62
+ export declare function updateAdUrlTags(adId: string, newUrlTags: string, accessToken: string, dryRun: boolean): Promise<UpdateAdUrlTagsResult>;
63
+ export interface SwapAdLeadFormResult {
64
+ ad_id: string;
65
+ ad_name: string;
66
+ previous_creative_id: string;
67
+ new_creative_id: string;
68
+ previous_form_id: string | null;
69
+ new_form_id: string;
70
+ mode: 'asset_feed_spec' | 'object_story_spec';
71
+ changed: boolean;
72
+ }
73
+ /**
74
+ * Swap the lead form on an ad by rebuilding its creative with a new form_id.
75
+ *
76
+ * Meta creatives are immutable, so we create-then-rebind:
77
+ * 1. Read the ad's current creative (full spec — handles both legacy
78
+ * object_story_spec and modern asset_feed_spec creatives).
79
+ * 2. POST /act_X/adcreatives with the same image/text spec but new
80
+ * lead_gen_form_id inside the SIGN_UP CTA.
81
+ * 3. POST /{ad-id} with creative_id=<new> to rebind.
82
+ *
83
+ * The ad-id is unchanged. Meta may briefly re-review.
84
+ */
85
+ export declare function swapAdLeadForm(adId: string, newFormId: string, accessToken: string, dryRun: boolean, ctaTypeOverride?: string): Promise<SwapAdLeadFormResult>;
86
+ export interface RebindAdCreativeResult {
87
+ ad_id: string;
88
+ ad_name: string;
89
+ previous_creative_id: string;
90
+ new_creative_id: string;
91
+ changed: boolean;
92
+ customization_rules_preserved: boolean | null;
93
+ }
94
+ /**
95
+ * Rebind an ad to a different creative_id. Atomic. ad_id stays stable.
96
+ * Use with createAdCreative to do full ad rebuilds (e.g. swap form + rebuild
97
+ * text content) without touching the ad_id.
98
+ *
99
+ * Safety check: if the OLD creative has `asset_customization_rules` (per-placement
100
+ * image rules set in Ads Manager UI) and the NEW creative does not carry them
101
+ * forward, the rebind is REFUSED. This catches the 2026-05-14 RDR class of bug
102
+ * where multi-variant headline writes silently flattened custom placements by image.
103
+ * Pass `force=true` to override (e.g. when the new creative deliberately replaces
104
+ * the placement rules).
105
+ */
106
+ export declare function rebindAdCreative(adId: string, newCreativeId: string, accessToken: string, dryRun: boolean, force?: boolean): Promise<RebindAdCreativeResult>;
107
+ export interface EditCreativeTextEdits {
108
+ messages?: string[];
109
+ headlines?: string[];
110
+ descriptions?: string[];
111
+ }
112
+ export interface EditCreativeTextResult {
113
+ ad_id: string;
114
+ ad_name: string;
115
+ previous_creative_id: string;
116
+ new_creative_id: string;
117
+ mode: 'asset_feed_spec' | 'object_story_spec';
118
+ changed_fields: string[];
119
+ customization_rules_preserved: number;
120
+ }
121
+ /**
122
+ * Edit text fields (primary texts / headlines / descriptions) on an ad's creative
123
+ * while PRESERVING images, videos, asset_customization_rules (per-placement image
124
+ * rules set in Ads Manager UI), call_to_actions, and link_urls.
125
+ *
126
+ * For asset_feed_spec ads: replaces only the specified text arrays. Refuses the
127
+ * edit if the existing asset_customization_rules reference per-text labels
128
+ * (body_label / title_label / description_label) and the new text count differs
129
+ * from the old — pass force=true to override (rules may end up referencing
130
+ * orphaned labels and break the placement targeting).
131
+ *
132
+ * For object_story_spec (legacy single-variant) ads: replaces link_data.message
133
+ * (single primary text), link_data.name (single headline), link_data.description.
134
+ * The messages/headlines/descriptions arrays must each have length ≤ 1 in that
135
+ * mode.
136
+ */
137
+ export declare function editCreativeText(adId: string, edits: EditCreativeTextEdits, accessToken: string, dryRun: boolean, force?: boolean): Promise<EditCreativeTextResult>;
138
+ export interface RenameAdResult {
139
+ ad_id: string;
140
+ previous_name: string;
141
+ new_name: string;
142
+ changed: boolean;
143
+ }
144
+ export declare function renameAd(adId: string, newName: string, accessToken: string, dryRun: boolean): Promise<RenameAdResult>;
145
+ //# sourceMappingURL=url-tags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-tags.d.ts","sourceRoot":"","sources":["../../src/tools/url-tags.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAcD,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,SAAS,EAAE,CAAC,CAuBtB;AAMD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,mBAAmB,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAC/C;AA0CD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAqB5F;AAMD,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC1C,cAAc,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACzC,0BAA0B,EAAE,OAAO,GAAG,IAAI,CAAC;CAC5C;AAWD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,qBAAqB,CAAC,CA2EhC;AAMD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,iBAAiB,GAAG,mBAAmB,CAAC;IAC9C,OAAO,EAAE,OAAO,CAAC;CAClB;AA8DD;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,OAAO,EACf,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,oBAAoB,CAAC,CAuH/B;AAMD,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,6BAA6B,EAAE,OAAO,GAAG,IAAI,CAAC;CAC/C;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,OAAO,EACf,KAAK,GAAE,OAAe,GACrB,OAAO,CAAC,sBAAsB,CAAC,CA+CjC;AAMD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,iBAAiB,GAAG,mBAAmB,CAAC;IAC9C,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,6BAA6B,EAAE,MAAM,CAAC;CACvC;AAwCD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,qBAAqB,EAC5B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,OAAO,EACf,KAAK,GAAE,OAAe,GACrB,OAAO,CAAC,sBAAsB,CAAC,CA6NjC;AAMD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,cAAc,CAAC,CAsBzB"}