fix: sem identidade de Instagram, não usar posicionamentos de IG (1772103)
Quando não há instagram_actor_id (ex: página sem IG vinculado, comum ao republicar rascunho antigo que cai na 1a página da conta), a Meta recusa o anúncio com subcode 1772103 ao tentar entregar no Instagram. - rota: sem IG, restringe publisher_platforms a facebook/audience_network/ messenger (exclui Instagram) - placement customization: sem IG, regras não declaram instagram_positions Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
5dd4c675c4
commit
58d9825fa5
2 changed files with 28 additions and 19 deletions
|
|
@ -247,6 +247,19 @@ export async function POST(req: Request) {
|
||||||
// análise/entrega na Meta.
|
// análise/entrega na Meta.
|
||||||
const finalStatus = body.activate === true ? 'ACTIVE' : 'PAUSED';
|
const finalStatus = body.activate === true ? 'ACTIVE' : 'PAUSED';
|
||||||
|
|
||||||
|
const baseTargeting = targeting || { geo_locations: { countries: ['BR'] } };
|
||||||
|
const finalTargeting: Record<string, unknown> = {
|
||||||
|
...baseTargeting,
|
||||||
|
targeting_automation: { advantage_audience: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sem identidade de Instagram, o anúncio não pode rodar em posicionamentos
|
||||||
|
// do Instagram (a Meta recusa com subcode 1772103). Nesse caso restringimos
|
||||||
|
// aos posicionamentos que não exigem IG (Facebook/Audience Network/Messenger).
|
||||||
|
if (!instagram_actor_id && !(baseTargeting as any).publisher_platforms) {
|
||||||
|
finalTargeting.publisher_platforms = ['facebook', 'audience_network', 'messenger'];
|
||||||
|
}
|
||||||
|
|
||||||
const result = await createFullCampaign(mcpClient, {
|
const result = await createFullCampaign(mcpClient, {
|
||||||
campaign_name,
|
campaign_name,
|
||||||
objective: finalObjective,
|
objective: finalObjective,
|
||||||
|
|
@ -254,16 +267,7 @@ export async function POST(req: Request) {
|
||||||
status: finalStatus,
|
status: finalStatus,
|
||||||
bid_strategy: finalBidStrategy,
|
bid_strategy: finalBidStrategy,
|
||||||
bid_amount: finalBidStrategy === 'LOWEST_COST_WITHOUT_CAP' ? undefined : finalBidAmount,
|
bid_amount: finalBidStrategy === 'LOWEST_COST_WITHOUT_CAP' ? undefined : finalBidAmount,
|
||||||
targeting: {
|
targeting: finalTargeting,
|
||||||
...(targeting || {
|
|
||||||
geo_locations: {
|
|
||||||
countries: ['BR'],
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
targeting_automation: {
|
|
||||||
advantage_audience: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
page_id: finalPageId,
|
page_id: finalPageId,
|
||||||
instagram_actor_id: instagram_actor_id || undefined,
|
instagram_actor_id: instagram_actor_id || undefined,
|
||||||
image_urls,
|
image_urls,
|
||||||
|
|
|
||||||
|
|
@ -291,27 +291,32 @@ export async function callMetaTool(
|
||||||
// O branch garante que ao menos vertical/horizontal existe.
|
// O branch garante que ao menos vertical/horizontal existe.
|
||||||
const squareHash = (pi.square || pi.vertical || pi.horizontal) as string;
|
const squareHash = (pi.square || pi.vertical || pi.horizontal) as string;
|
||||||
|
|
||||||
|
// Sem IG, não declaramos posicionamentos de Instagram (a Meta exige
|
||||||
|
// identidade de IG pra eles — subcode 1772103).
|
||||||
|
const hasIg = !!args.instagram_actor_id;
|
||||||
|
const defaultPlatforms = hasIg
|
||||||
|
? ['facebook', 'instagram', 'audience_network', 'messenger']
|
||||||
|
: ['facebook', 'audience_network', 'messenger'];
|
||||||
|
|
||||||
const images: Array<{ hash: string; adlabels: Array<{ name: string }> }> = [
|
const images: Array<{ hash: string; adlabels: Array<{ name: string }> }> = [
|
||||||
{ hash: squareHash, adlabels: [{ name: 'sq' }] },
|
{ hash: squareHash, adlabels: [{ name: 'sq' }] },
|
||||||
];
|
];
|
||||||
const rules: Array<Record<string, unknown>> = [
|
const rules: Array<Record<string, unknown>> = [
|
||||||
// Regra padrão (mais ampla): cobre todos os posicionamentos.
|
// Regra padrão (mais ampla): cobre todos os posicionamentos.
|
||||||
{
|
{
|
||||||
customization_spec: { publisher_platforms: ['facebook', 'instagram', 'audience_network', 'messenger'] },
|
customization_spec: { publisher_platforms: defaultPlatforms },
|
||||||
image_label: { name: 'sq' },
|
image_label: { name: 'sq' },
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
if (pi.vertical && pi.vertical !== squareHash) {
|
if (pi.vertical && pi.vertical !== squareHash) {
|
||||||
images.push({ hash: pi.vertical, adlabels: [{ name: 'vt' }] });
|
images.push({ hash: pi.vertical, adlabels: [{ name: 'vt' }] });
|
||||||
rules.push({
|
const verticalSpec: Record<string, unknown> = {
|
||||||
customization_spec: {
|
publisher_platforms: hasIg ? ['facebook', 'instagram'] : ['facebook'],
|
||||||
publisher_platforms: ['facebook', 'instagram'],
|
facebook_positions: ['story', 'facebook_reels'],
|
||||||
facebook_positions: ['story', 'facebook_reels'],
|
};
|
||||||
instagram_positions: ['story', 'reels'],
|
if (hasIg) verticalSpec.instagram_positions = ['story', 'reels'];
|
||||||
},
|
rules.push({ customization_spec: verticalSpec, image_label: { name: 'vt' } });
|
||||||
image_label: { name: 'vt' },
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pi.horizontal && pi.horizontal !== squareHash) {
|
if (pi.horizontal && pi.horizontal !== squareHash) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue