Documentazione

Configurazione degli annunci

Riferimento completo del CLI

Questo è il riferimento completo del CLI di Ads Uploader. Per un'introduzione e una guida per iniziare, consulta Configurazione tramite CLI.

Comandi

Autenticazione

ComandoCosa fa
ads loginEsegue l'autenticazione tramite browser (apre il browser predefinito)
ads logoutCancella le credenziali memorizzate
ads whoamiMostra l'utente attualmente connesso
ads configMostra la configurazione (account, URL API, percorso delle credenziali)
ComandoCosa fa
ads accountsElenca tutti gli account pubblicitari collegati al tuo account Meta
ads account <id>Imposta un account pubblicitario predefinito per i comandi futuri
ads pagesElenca le Pagine Facebook con cui puoi fare pubblicità, incluso eventuale account Instagram collegato, da usare con le sostituzioni di profilo
ads campaignsElenca le campagne attive
ads campaigns --status allInclude le campagne in pausa e archiviate
ads campaigns --search "text"Filtra le campagne per nome
ads campaign <id>Mostra i gruppi di inserzioni all'interno di una campagna
ads adsets --campaign <id>Elenca i gruppi di inserzioni in una campagna (supporta --search, --status)
ads adset <id>Mostra gli annunci all'interno di un gruppo di inserzioni
ads ad <id>Visualizza i dettagli completi dell'annuncio, incluse le impostazioni del creativo
ads presetsElenca i tuoi preset API salvati
ads presets <id>Mostra i dettagli di un preset specifico
ads presets:save --from-ad <adId> --name "Preset Name"Salva un annuncio esistente come preset API
ads text-presetsElenca i tuoi preset di testo salvati
ads text-presets <id>Mostra i dettagli di un preset di testo specifico
ads uploadsElenca i caricamenti recenti
ads uploads <batchId>Mostra i dettagli del caricamento (file, varianti, hash)

Caricamento media

ComandoCosa fa
ads upload <files...>Carica immagini e video sul tuo account pubblicitario
ads upload ./directory/Carica un'intera directory

I file vengono caricati in parallelo e i guasti di rete transitori vengono riprovati automaticamente con backoff. Raramente è necessario modificarli, ma sono disponibili:

Flag di caricamentoDescrizione
--concurrency <n>Numero di file caricati in parallelo, 1-6 (predefinito: 4). I video di grandi dimensioni vengono limitati automaticamente per rimanere entro la memoria.
--upload-timeout <ms>Timeout di caricamento per file (predefinito: 120000)
--api-timeout <ms>Timeout della richiesta API in millisecondi (predefinito: 60000)

Creazione annunci

ComandoCosa fa
ads create spec.jsonCrea annunci da un file di specifica
ads create:preview spec.jsonEsecuzione di prova che mostra cosa verrebbe creato
ads create:interactiveProcedura guidata (accetta tutti i flag di creazione)

Gestione job

ComandoCosa fa
ads jobs <jobId>Controlla lo stato di un job
ads jobs <jobId> --followMostra in tempo reale gli aggiornamenti di avanzamento
ads jobs cancel <jobId>Annulla un job in esecuzione

Flag di creazione

Questi flag si applicano a ads create, ads create:preview e ads create:interactive. Possono essere usati al posto di un file di specifica o insieme a esso.

FlagDescrizione
--account <id>Sostituisce l'account pubblicitario predefinito
--preset <id>Usa un preset API salvato (alternativa al file di specifica)
--text-preset <id>Carica un preset di testo salvato
--copy-from <adId>Copia le impostazioni da un annuncio esistente
--upload <batchId>Specifica l'ID del caricamento
--status <PAUSED|ACTIVE>Imposta lo stato dell'annuncio (predefinito: ACTIVE)
--pause-at <level>Livello di pausa: ad (predefinito), adSet o campaign
--daily-budget <amount>Sostituisce il budget giornaliero per gruppo di inserzioni (unità di valuta, es. 50 per 50 $)
--bid-amount <amount>Sostituisce l'offerta/limite di costo per gruppo di inserzioni (unità di valuta)
--page <id>Usa questa Pagina Facebook invece di quella del template (vedi Opzioni di profilo)
--instagram <id>Usa questo account Instagram invece di quello del template
--threads <id>Usa questo profilo Threads invece di quello del template
--text-file <path>Carica la configurazione del testo da un file JSON
--expandedMostra i valori completi di titolo, testo principale e descrizione nelle anteprime

Flag di navigazione

Questi flag sono disponibili su campaigns, adsets, adset e campaign:

FlagDescrizione
--status <status>active (predefinito) o all
--inactiveAbbreviazione di --status all (su campaigns)
--search <text>Filtra per nome (su campaigns, adsets)

Flag di dettaglio

Questi flag sono disponibili su ad:

FlagDescrizione
--expandedMostra i valori completi di titolo, testo principale e descrizione

Flag comuni

FlagDescrizione
--account <id>Sostituisce l'account pubblicitario predefinito per qualsiasi comando
--jsonRestituisce JSON grezzo (disponibile sulla maggior parte dei comandi, pensato per lo scripting)

Formato del file di specifica

Il file di specifica JSON controlla ogni aspetto della creazione degli annunci. Solo due campi sono obbligatori: una sorgente template (adPresetId o copyFromAd) e uploadId.

Specifica minima

{
  "adPresetId": "your_preset_id",
  "uploadId": "batch_abc123"
}

Esempio completo

{
  "adPresetId": "preset_id_here",
  "uploadId": "batch_abc123",
  "adSet": {
    "name": "My New Ad Set",
    "dailyBudget": 50
  },
  "adNamePattern": "{filename}",
  "texts": {
    "perAd": {
      "hero.jpg": {
        "headlines": ["Main Headline"],
        "bodies": ["Ad copy here."],
        "descriptions": ["Short description"],
        "cta": "SHOP_NOW",
        "link": "https://example.com/landing"
      }
    }
  },
  "creativeEnhancements": "none",
  "options": {
    "status": "PAUSED",
    "pauseAt": "adSet"
  }
}

Sorgente template

Ti serve una di queste per indicare al CLI quale configurazione dell'annuncio usare come base.

CampoDescrizione
adPresetIdL'ID di un preset API salvato. Blocca la campagna, il gruppo di inserzioni e la configurazione dell'annuncio.
copyFromAdUn ID annuncio Facebook da cui copiare le impostazioni.

Quando usi copyFromAd, fornisci il caricamento e, facoltativamente, la campagna e il gruppo di inserzioni:

{
  "copyFromAd": "120233848667930472",
  "uploadId": "batch_abc123",
  "campaign": { "id": "120233848666410472" },
  "adSet": { "id": "120233848666620472" }
}

Per trovare l'ID annuncio giusto, naviga nel tuo account: ads campaigns poi ads campaign <id> poi ads adset <id> poi ads ad <id>.

Opzioni di profilo

Per impostazione predefinita, i nuovi annunci ereditano la Pagina Facebook, l'account Instagram e il profilo Threads dall'annuncio template o dal preset. È lo stesso controllo Opzioni di profilo disponibile tramite il pannello Predefiniti nell'applicazione web. Sostituisci ognuno di essi con un blocco profile (o con i flag --page / --instagram / --threads, che hanno precedenza sul file di specifica):

{
  "copyFromAd": "120233848667930472",
  "uploadId": "batch_abc123",
  "profile": {
    "pageId": "123456789012345",
    "instagramId": "17841400000000000",
    "threadsId": "987654321098765"
  }
}

Esegui ads pages per elencare gli ID delle Pagine che puoi usare, insieme all'account Instagram collegato a ciascuna Pagina.

Importante: se sostituisci solo la pagina, i profili Instagram e Threads vengono reimpostati (appartenevano alla vecchia pagina), non vengono mantenuti. Per spostare la pagina e mantenere un profilo Instagram o Threads specifico, impostali esplicitamente. Puoi anche cambiare solo il profilo Instagram o Threads senza toccare la pagina, impostando solo quei campi.

I profili per campagna per i lanci multi-campagna non sono ancora supportati nelle specifiche del CLI.

Struttura della campagna

Per impostazione predefinita, gli annunci vanno nella campagna dell'annuncio template. Puoi creare una nuova campagna fornendo campaign.name.

Per le modalità multi-campagna, usa campaign.mode con un array campaigns:

{
  "campaign": {
    "mode": "duplicate",
    "campaigns": [
      { "name": "Campaign A" },
      { "name": "Campaign B" }
    ]
  }
}
ModalitàComportamento
"single"Predefinita. Una sola campagna.
"duplicate"Tutti i media vengono duplicati in ogni campagna.
"split"I media vengono divisi equamente tra le campagne.

Modalità dei gruppi di inserzioni

Per impostazione predefinita, gli annunci vanno nel gruppo di inserzioni esistente dell'annuncio template. Le seguenti modalità ti danno il controllo su come gli annunci vengono distribuiti tra i gruppi di inserzioni.

Crea un nuovo gruppo di inserzioni:

{ "adSet": { "name": "My Ad Set" } }

Usa un gruppo di inserzioni esistente tramite ID:

{ "adSet": { "id": "120233848666620472" } }

Un gruppo di inserzioni per ogni file caricato:

{ "adSet": { "mode": "perUpload" } }

Raggruppamento automatico in gruppi di inserzioni di dimensione fissa:

{ "adSet": { "mode": "autoGroup", "adsPerAdSet": 5 } }

Gruppi personalizzati con pieno controllo su quali file vanno dove:

{
  "adSet": {
    "groups": [
      { "name": "Images - April 10", "media": ["hero.jpg", "banner.jpg"] },
      { "name": "Videos - April 10", "media": ["promo.mp4"] }
    ]
  }
}

Pattern di denominazione dei gruppi di inserzioni per le modalità multi-gruppo:

{ "adSet": { "mode": "perUpload", "namePattern": "Ad Set {index:01}" } }

Il raggruppamento per varianti raggruppa gli annunci per identificatore di variazione nello stesso gruppo di inserzioni:

{ "adSet": { "mode": "autoGroup", "groupVariations": true, "variationIdentifier": "-" } }

Sostituzione di budget e offerta

Sostituisci il budget giornaliero e/o l'importo dell'offerta sui nuovi gruppi di inserzioni. I valori sono nelle unità di valuta del tuo account (es. 50 per 50 $ o 50 euro).

dailyBudget e bidAmount sono campi Meta indipendenti:

  • Campagne ABO (il budget è sul gruppo di inserzioni): puoi impostare dailyBudget, bidAmount o entrambi. Le strategie con limite di offerta come COST_CAP, LOWEST_COST_WITH_BID_CAP e TARGET_COST richiedono un bidAmount insieme al budget.
  • Campagne CBO (il budget è sulla campagna): non impostare dailyBudget sul gruppo di inserzioni, Meta lo rifiuta perché il budget proviene già dalla campagna. Per le strategie con limite di offerta, imposta solo bidAmount.
{ "adSet": { "dailyBudget": 50 } }
{ "adSet": { "bidAmount": 5 } }
{ "adSet": { "dailyBudget": 50, "bidAmount": 5 } }

Disponibili anche come flag del CLI: --daily-budget 50, --bid-amount 5 o entrambi.

Configurazione del testo

Il testo comune applica la stessa copia a tutti gli annunci:

{
  "texts": {
    "common": {
      "headlines": ["Headline 1", "Headline 2"],
      "bodies": ["Primary text"],
      "descriptions": ["Description"]
    },
    "strategy": "flexible"
  }
}

Il testo per annuncio ti permette di impostare una copia unica per ogni file:

{
  "texts": {
    "perAd": {
      "hero.jpg": {
        "headlines": ["Hero Headline"],
        "bodies": ["Hero copy"],
        "descriptions": ["Hero desc"],
        "cta": "LEARN_MORE",
        "link": "https://example.com/hero",
        "urlTags": "utm_content=hero"
      },
      "banner.jpg": {
        "headlines": ["Banner Headline"],
        "bodies": ["Banner copy"]
      }
    }
  }
}

Le chiavi per annuncio sono nomi di file (non percorsi completi). Ogni voce supporta: headlines, bodies, descriptions, cta, link, displayUrl, urlTags. I campi che non specifichi ereditano dall'annuncio template.

I preset di testo ti permettono di caricare una configurazione di testo salvata:

{ "textPresetId": "preset_id_here" }

Non puoi combinare textPresetId con texts.

Le opzioni di strategia controllano come vengono gestite più variazioni di testo:

  • "flexible" (predefinita) lascia che Meta ottimizzi tra le tue variazioni di testo. Più titoli e testi diventano opzioni che Facebook combina liberamente.
  • "separate" crea un annuncio separato per ogni combinazione di testo.

Una CTA di primo livello si applica a tutti gli annunci. Le CTA per annuncio in texts.perAd la sostituiscono.

{
  "cta": {
    "type": "SHOP_NOW",
    "link": "https://example.com",
    "displayUrl": "example.com"
  },
  "urlTags": "utm_source=facebook&utm_medium=paid"
}

Tipi di CTA standard: LEARN_MORE, SHOP_NOW, SIGN_UP, SUBSCRIBE, GET_OFFER, CONTACT_US, DOWNLOAD, ORDER_NOW, BUY_NOW, BOOK_NOW, APPLY_NOW, GET_QUOTE, GET_IN_TOUCH, WATCH_MORE

Le CTA specifiche dell'obiettivo vengono ereditate dall'annuncio template e non dovrebbero essere impostate manualmente. Impostarle sul tipo di campagna sbagliato causerà un errore dell'API di Facebook.

CTAObiettivo di campagna richiesto
MESSAGE_PAGEDestinazione Messenger
WHATSAPP_MESSAGEDestinazione WhatsApp
INSTAGRAM_MESSAGEDestinazione DM di Instagram
CALL_NOWCampagna di chiamata

Split-test degli URL (destinazione divisa)

Fornisci da 2 a 5 URL di destinazione sotto texts.urlVariants e ogni gruppo di inserzioni generato viene duplicato una volta per URL, così Meta ottimizza ogni combinazione di annuncio e landing page in modo indipendente.

{
  "texts": {
    "common": { "headlines": ["Hero"], "bodies": ["Copy"] },
    "urlVariants": [
      { "link": "https://example.com/homepage", "label": "homepage" },
      { "link": "https://example.com/quiz", "label": "quiz-v2" }
    ]
  }
}
  • label è facoltativo. Quando omesso, viene usato l'ultimo slug del percorso dell'URL (/quiz-v2quiz-v2), con fallback al nome host per gli URL radice.
  • In modalità a gruppo di inserzioni singolo, l'etichetta di ogni variante diventa il nome completo del gruppo di inserzioni.
  • Nelle modalità perUpload e autoGroup, il nome di ogni gruppo di inserzioni duplicato aggiunge _{label} al pattern (o sostituisce un token {destination} se ne includi uno).
  • Il token {date} in un'etichetta si risolve nella data odierna (es. launch-{date}launch-2026-04-27).
  • Ogni URL di destinazione deve essere unico. URL identici (o varianti con barra finale / maiuscole-minuscole dello stesso URL) si uniscono in un'unica voce, quindi assicurati di avere almeno 2 destinazioni distinte.
  • Il budget del tuo gruppo di inserzioni viene moltiplicato per il numero di varianti, poiché ogni duplicato è un proprio gruppo di inserzioni.
  • Non compatibile con annunci sorgente a destinazione speciale (modulo per i contatti, Messenger, WhatsApp, DM di Instagram, chiamata). Il CLI rifiuta questa combinazione con un errore chiaro, quei formati non passano attraverso cta.link.
  • Le sostituzioni di link per annuncio in texts.perAd perdono contro l'URL della variante quando sono impostate entrambe.

Miglioramenti creativi

Controlla i miglioramenti creativi di Advantage+:

{ "creativeEnhancements": "none" }
ValoreEffetto
omessoTutte le funzioni disattivate
"metaDefaults"Alias deprecato per "none"
"all"Tutte le funzioni attivate
"none"Tutte le funzioni disattivate
["feature1", "feature2"]Solo le funzioni elencate attivate, il resto disattivato

Funzioni disponibili: text_translation, inline_comment, enhance_cta, text_optimizations, reveal_details_over_time, image_brightness_and_contrast, image_touchups, video_auto_crop, video_filtering, image_animation, image_templates, adapt_to_placement, product_extensions, description_automation, add_text_overlay, music, carousel_to_video, carousel_dynamic_description, multi_share_end_card, multi_share_optimized

Quando selezioni singole funzioni, elenca solo quelle pertinenti al tipo di media. Le funzioni video (video_auto_crop, video_filtering) si applicano solo agli annunci video. Le funzioni carosello (carousel_to_video, carousel_dynamic_description, multi_share_end_card, multi_share_optimized) si applicano solo agli annunci carosello.

Annunci carosello

Raggruppa i file caricati in annunci carosello con testo per scheda e testo complessivo del carosello facoltativo. cardTexts controlla le singole schede. Il testo complessivo del carosello può essere collocato nell'oggetto carosello o impostato in texts.perAd usando il name del carosello; i campi collocati vincono quando entrambi sono presenti.

{
  "carousel": [
    {
      "name": "My Carousel",
      "cards": ["slide1.jpg", "slide2.jpg", "slide3.jpg"],
      "headlines": ["Overall Carousel Headline"],
      "bodies": ["Overall primary text"],
      "descriptions": ["Overall description"],
      "cta": "SHOP_NOW",
      "link": "https://example.com/carousel",
      "urlTags": "utm_content=my_carousel",
      "cardTexts": [
        { "headline": "Slide 1", "description": "First card", "link": "https://example.com/1" },
        { "headline": "Slide 2", "description": "Second card", "link": "https://example.com/2" }
      ]
    }
  ]
}

Forma alternativa per il testo complessivo:

{
  "texts": {
    "perAd": {
      "My Carousel": {
        "headlines": ["Overall Carousel Headline"],
        "bodies": ["Overall primary text"],
        "descriptions": ["Overall description"],
        "cta": "SHOP_NOW",
        "link": "https://example.com/carousel",
        "urlTags": "utm_content=my_carousel"
      }
    }
  },
  "carousel": [
    {
      "name": "My Carousel",
      "cards": ["slide1.jpg", "slide2.jpg", "slide3.jpg"]
    }
  ]
}

Le schede devono fare riferimento a nomi di file del caricamento. Minimo 2 schede per carosello. I file rivendicati da un carosello vengono rimossi dall'elenco degli annunci standard.

Annunci flessibili

Raggruppa più asset in un unico annuncio flessibile in cui Meta sceglie l'asset migliore per posizionamento:

{
  "flexible": [
    {
      "name": "Multi-Asset Ad",
      "assets": ["hero.jpg", "promo.mp4", "banner.jpg"]
    }
  ]
}

Minimo 2 asset per gruppo. I file rivendicati da un gruppo flessibile vengono rimossi dall'elenco degli annunci standard.

Annunci multimediali

Raggruppa da 2 a 10 immagini o video caricati in un annuncio Multi Media di Meta:

{
  "multimedia": [
    {
      "name": "Mixed Media Ad",
      "assets": ["hero.jpg", "promo.mp4", "banner.jpg"],
      "assetTexts": [
        {
          "headline": "Hero headline",
          "primaryText": "Hero primary text",
          "description": "Hero description",
          "link": "https://example.com/hero",
          "displayUrl": "example.com/hero"
        }
      ]
    }
  ]
}

Gli asset devono fare riferimento a nomi di file del caricamento. assetTexts è facoltativo e si allinea ad assets per indice; ogni campo è una singola sostituzione per quell'asset e i campi vuoti ricadono sul testo principale e sugli URL dell'annuncio. L'asset principale renderizzato usa il testo e l'URL principali dell'annuncio, e qualsiasi sostituzione del testo dell'asset principale diventa la prima opzione di testo principale. I video necessitano di un URL di miniatura pubblico memorizzato in cache derivante dall'elaborazione del caricamento. I file rivendicati da un gruppo Multi Media vengono rimossi dall'elenco degli annunci standard.

Denominazione degli annunci

Personalizza come vengono denominati i tuoi annunci:

{ "adNamePattern": "{filename} - {date}" }
SegnapostoCosa inserisce
{filename}Nome del file originale senza estensione
{index:01}Indice con zeri iniziali (01, 02, 03...)
{variation}Identificatore di variazione se il raggruppamento per varianti è attivo
{campaign}Nome della campagna
{date}Data corrente (AAAA-MM-GG)
{date:short}Data breve (MM-GG)
{timestamp}Timestamp Unix

Opzioni

{
  "options": {
    "status": "PAUSED",
    "pauseAt": "adSet",
    "schedule": {
      "startTime": "2026-04-01T09:00:00",
      "endTime": "2026-04-30T23:59:59"
    }
  }
}
CampoValoriDescrizione
status"PAUSED", "ACTIVE"Stato di lancio dell'annuncio (predefinito: ACTIVE)
pauseAt"ad", "adSet", "campaign"A quale livello mettere in pausa (predefinito: ad)
schedule.startTimeStringa ISO 8601Ora di inizio programmata (usa il fuso orario dell'account pubblicitario)
schedule.endTimeStringa ISO 8601Ora di fine programmata (facoltativa)

Caricamento e rilevamento delle varianti

I gruppi di varianti vengono rilevati automaticamente dalle convenzioni sui nomi dei file, proprio come nell'applicazione web. Consulta Variazioni del formato immagine per tutti i dettagli sulle convenzioni di denominazione.

Suffissi di rapporto: hero_1x1.jpg + hero_4x5.jpg + hero_9x16.jpg + hero_16x9.jpg + hero_1.91x1.jpg vengono raggruppati come un unico annuncio a varianti. Fino a 5 rapporti per gruppo.

Posizione del token: il token di rapporto può apparire alla fine (hero_4x5.jpg), in mezzo (hero_4x5_v2.jpg) o all'inizio (4x5_hero.jpg).

Suffissi di parole legacy: hero.jpg + hero_vertical.jpg + hero_horizontal.jpg funzionano ancora e si mappano su 9x16 e 16x9.

Il delimitatore predefinito è _. Puoi cambiarlo (o accettarne più di uno) in Account > Predefiniti > Posizionamenti > Separatore nome file.

Pattern comuni

Carica e crea con un preset

ads upload ./creatives/hero.jpg ./creatives/banner.jpg
ads create:preview spec.json
ads create spec.json

Dove spec.json contiene:

{ "adPresetId": "PRESET_ID", "uploadId": "BATCH_ID" }

Copia le impostazioni da un annuncio esistente

Naviga nel tuo account per trovare l'annuncio:

ads campaigns
ads campaign 120233848666410472
ads adset 120233848666620472
ads ad 120233848667930472

Poi crea una specifica che vi fa riferimento:

{
  "copyFromAd": "120233848667930472",
  "uploadId": "BATCH_ID"
}

L'annuncio sorgente deve avere impostazioni del creativo inline. Se è stato costruito da un post di Pagina esistente, il CLI lo rifiuterà prima di inviare una richiesta di creazione.

Salva un preset API da un annuncio esistente

ads presets:save --from-ad 120233848667930472 --name "Spring Purchase Template"
ads create --preset PRESET_ID --upload BATCH_ID

Questo salva la stessa forma di preset API usata dall'applicazione web. L'annuncio sorgente deve avere impostazioni del creativo inline; gli annunci basati su post di Pagina non possono essere salvati come preset API.

Testo per annuncio con copia unica per file

{
  "adPresetId": "PRESET_ID",
  "uploadId": "BATCH_ID",
  "texts": {
    "perAd": {
      "hero.jpg": {
        "headlines": ["Summer Sale Now On"],
        "bodies": ["Save up to 50% on all items"],
        "cta": "SHOP_NOW",
        "link": "https://example.com/summer"
      },
      "banner.jpg": {
        "headlines": ["New Collection Available"],
        "bodies": ["Browse our latest styles"],
        "cta": "LEARN_MORE",
        "link": "https://example.com/new"
      }
    }
  }
}

Raggruppamento automatico in più gruppi di inserzioni

{
  "adPresetId": "PRESET_ID",
  "uploadId": "BATCH_ID",
  "adSet": { "mode": "autoGroup", "adsPerAdSet": 3 }
}

Note importanti

  1. Visualizza sempre l'anteprima prima. create:preview rileva gli errori di configurazione prima di toccare Facebook.
  2. Gli annunci sono attivi per impostazione predefinita. Usa --status PAUSED o "status": "PAUSED" nella specifica per crearli in pausa.
  3. uploadId proviene dall'output del caricamento. È l'ID del caricamento restituito da ads upload.
  4. I caricamenti sono legati a un account pubblicitario. I file vengono caricati direttamente nella libreria multimediale Facebook dell'account selezionato. L'ID del caricamento può essere usato solo con lo stesso account.
  5. copyFromAd necessita di uploadId. Devi fornire il caricamento. Facoltativamente, fornisci campaign.id e adSet.id per controllare il posizionamento.
  6. Le chiavi di testo per annuncio sono nomi di file. Usa "hero.jpg", non "/path/to/hero.jpg".
  7. textPresetId e texts si escludono a vicenda. Usa l'uno o l'altro, non entrambi.
  8. Le CTA specifiche dell'obiettivo vengono ereditate dal template. Non impostare MESSAGE_PAGE, WHATSAPP_MESSAGE, ecc. manualmente.