Il feed: pipeline di dati tecnici per Google Shopping
Perché i feed Shopify predefiniti falliscono su larga scala. Una guida tecnica per creare pipeline XML ad alte prestazioni, utilizzando la Content API e ottimizzando le etichette personalizzate per il ROAS.
Se sei un marchio di moda, il tuo sito web è il tuo flagship store. Ma il tuo Feed prodotto è il tuo cartellone pubblicitario, il tuo catalogo e il tuo venditore, distribuito su tutta Internet. Per la maggior parte dei commercianti, il feed prodotto è un ripensamento. Installano un plug-in “Google Shopping”, fanno clic su “Sincronizza” e se ne dimenticano.
Ecco perché perdono.
Noi di Maison Code Paris trattiamo il feed prodotto come un prodotto dati. È un artefatto ingegneristico direttamente correlato al ritorno sulla spesa pubblicitaria (ROAS). Se il tuo feed è lento, impreciso o generico, stai pagando una “tassa pigra” a Google.
Questa guida esplora come riprogettare il feed da un file XML passivo in una pipeline dinamica e generatrice di entrate.
Perché Maison Code ne parla
In Maison Code Paris, agiamo come la coscienza architettonica dei nostri clienti. Spesso ereditiamo stack “moderni” costruiti senza una comprensione fondamentale della scala.
Discutiamo di questo argomento perché rappresenta un punto di svolta critico nella maturità ingegneristica. Implementarlo correttamente differenzia un MVP fragile da una piattaforma resiliente di livello aziendale.
Il problema con le sincronizzazioni “predefinite”.
Le piattaforme standard (Shopify, Magento, Salesforce) offrono integrazioni native. Questi falliscono su larga scala (GMV> 10 milioni di dollari) per tre motivi:
- Latenza: in genere si sincronizzano una volta ogni 24 ore. Se esaurisci uno SKU alle 10:00, continuerai a pagare per i clic fino alla successiva sincronizzazione alle 2:00. Questa è una spesa sprecata.
- Titoli generici: mappano il titolo CMS interno (“Crop Top”) direttamente su Google. Google vuole “Top corto in cotone da donna - Nero - Taglia M”`.
- Strategia Zero: compilano i campi obbligatori, ma ignorano
custom_labels. Non puoi fare offerte diverse per gli articoli con “margine elevato” e “svendita” perché i dati non sono presenti.
Architettura: la pipeline ibrida
Non facciamo affidamento sulle app. Costruiamo una pipeline personalizzata su AWS/Vercel. Usiamo un Approccio Ibrido:
- Bulk Sync (XML): una rigenerazione quotidiana dell’intero catalogo per i dati strutturali.
- Sincronizzazione incrementale (API): aggiornamenti in tempo reale per prezzo e disponibilità.
“sirena”. grafico TD CMS[CMS headless / Shopify] —>|Nightly Cron| Generatore[Generatore XML di Node.js] Generatore —>|Stream| S3[Secchio S3: feed.xml] S3 —>|Preleva| GMC[Google Merchant Center]
CMS -->|Webhook: PRICE_UPDATE| API[Funzione serverless]
API -->|Push| API dei contenuti[API dei contenuti di Google]
ContentAPI -->|Aggiornamento istantaneo| GMC
## Fase 1: generazione di XML ad alte prestazioni
Generare un file XML per 50.000 SKU è impegnativo. Se carichi tutti i prodotti in memoria, il processo Node.js si bloccherà (Heap Out of Memory).
Utilizziamo **Streams**.
### Il generatore di streaming
Recuperiamo i prodotti utilizzando l'impaginazione basata su cursore (GraphQL), li trasformiamo e inoltriamo il risultato direttamente al flusso di caricamento S3.
"dattiloscritto".
importa { Trasforma } da 'stream';
importa {creaGzip} da 'zlib';
importa { S3 } da '@aws-sdk/client-s3';
// 1. Trasforma il flusso: Prodotto JSON -> Stringa XML
const xmlTransform = nuova trasformazione({
scrivibileObjectMode: vero,
trasformazione(prodotto, codifica, callback) {
const xmlNode = `
<elemento>
<g:id>${prodotto.sku}</g:id>
<g:titolo><![CDATA[${optimizeTitle(prodotto)}]]></g:titolo>
<g:price>${product.price.amount} ${product.price.currency}</g:price>
<g:link>${product.onlineStoreUrl}</g:link>
<g:cogs>${product.cost}</g:cogs> <!-- Dati sui margini personalizzati -->
</item>
`;
callback(null, xmlNode);
}
});
// 2. La pipeline
funzione asincrona generateFeed() {
const s3Stream = nuovo PassThrough();
const caricamento = nuovo caricamento({
cliente: nuovo S3({}),
parametri: {Bucket: 'feed', Chiave: 'google.xml.gz', Corpo: s3Stream }
});
const productStream = getShopifyProductStream(); // Generatore personalizzato
prodottoStream
.pipe(xmlTransform)
.pipe(createGzip()) // Comprimi sempre
.pipe(s3Stream);
attendi upload.done();
}
Questa pipeline ci consente di generare feed distinti per regioni distinte (Stati Uniti, UE, Regno Unito) in parallelo con un ingombro di memoria minimo.
Fase 2: il livello logico (arricchimento dei dati)
È qui che l’ingegneria incontra il marketing. Non ci limitiamo a trasmettere dati; lo valorizziamo.
Ottimizzazione del titolo (SEO per gli annunci)
L’algoritmo abbina le query al tuo titolo.
- Errore: “Air Max 90” (nome CMS interno).
- Buono: “Scarpa da corsa Nike Air Max 90 da uomo - Bianco/Rosso - Taglia 10”.
Utilizziamo un motore di template: “Titolo = [Marchio] + [Sesso] + [Collezione] + [Tipo prodotto] + [Colore] + [Materiale]“
Etichette personalizzate per le offerte
Google consente 5 etichette personalizzate (da “custom_label_0” a “4”). Questa è la tua arma segreta. Li popoliamo a livello di codice in base alla logica aziendale:
- Etichetta 0 (Margine): Se
(Prezzo - Costo) > €50, imposta"Margine_alto". Fai un’offerta alta. - Etichetta 1 (Stagione): Se
tagscontiene “Summer25”, imposta"New_Arrival". - Etichetta 2 (Prestazioni): sincronizzazione con Google Analytics. Se
ConversionRate > 3%, imposta"Best_Seller". - Etichetta 3 (Stock): Se
inventario < 5, imposta"Low_Stock". Stop agli annunci generici, premi l’urgenza.
Fase 3: Content API (in tempo reale)
Per Prezzo e Azioni, XML è troppo lento. Utilizziamo la Google Content API per Shopping.
Quando avviene un acquisto nello store, viene attivato un webhook. “Creatoordine” -> “Livello inventario: 0”.
La nostra funzione serverless colpisce immediatamente Google:
“dattiloscritto”. importa { content_v2_1 } da ‘@googleapis/content’;
aggiornamento della funzione asincronaGoogleStock(sku: stringa, quantità: numero) { const auth = attendono getGoogleAuth(); const contenuto = nuovo contenuto_v2_1.Contenuto({ auth });
attendono content.inventory.set({
ID commerciante: ‘12345678’,
storeCode: ‘online’, // o codice negozio locale
productId: online:en:US:€{sku},
corpo richiesta: {
disponibilità: quantità > 0 ? ‘disponibile’: ‘non disponibile’,
// Possiamo anche aggiornare istantaneamente il prezzo di vendita qui
prezzo di vendita: {valore: ‘99,00’, valuta: ‘USD’ }
}
});
}
**Latenza**: < 2 minuti.
**Risultato**: non paghi mai per un clic su un articolo esaurito.
## Canali in espansione: Meta, Pinterest, TikTok
Una volta che hai questa pipeline di dati grezzi, non sei limitato a Google.
* **Meta (Facebook/Instagram)**: accetta un formato CSV simile. Eseguiamo il fork dello stream, mappiamo `g:id` su `fb:id` e carichiamo nel Gestore cataloghi.
* **TikTok**: richiede risorse video. Possiamo mappare `custom_label_4` a un URL di una risorsa video generata (vedi [AI Agents](/it/blog/tech-ai-agents-it)).
* **Annunci di inventario locale (LIA)**: se disponi di negozi fisici, generiamo un feed secondario che collega "store_code" (Paris Champs-Elysées) a "quantity". Quando un utente è vicino a Parigi, l'annuncio dice "Ritira oggi".
## Insidie comuni (l'incubo "disapprovato")
1. **Mancata corrispondenza GTIN**: Google controlla rigorosamente i codici a barre UPC/EAN. Se invii un GTIN falso, il prodotto viene bannato. Se non ne hai uno, invia `identifier_exists: no`.
2. **Sovrapposizioni di immagini**: Google richiede sfondi bianchi. Se la tua immagine principale ha la filigrana "Saldi", verrà rifiutata. La nostra pipeline controlla i metadati delle immagini o utilizza gli URL trasformati da Cloudinary per eliminare le sovrapposizioni.
3. **Mancata corrispondenza del prezzo**: se l'XML indica $ 100 e la pagina di destinazione indica $ 101 (a causa della conversione di valuta o di aggiornamenti), Google sospende l'account. Questo è il motivo per cui la **Content API** è obbligatoria per garantire la coerenza in tempo reale.
## 10. Regole del feed e modifica della fonte
Google Merchant Center consente le "Regole del feed".
"Se il titolo contiene 'Nike', aggiungi 'Sneakers'."
**Non utilizzarlo.**
La logica nascosta in GMC è invisibile ai tuoi sviluppatori.
Se modifichi il titolo nel codice e GMC lo modifica nuovamente, passerai settimane a eseguire il debug.
**Regola**: la logica appartiene alla pipeline di codice (sorgente), non all'interfaccia di destinazione.
## 11. Buffer di inventario (la rete di sicurezza)
La sincronizzazione del tuo magazzino non è immediata. Ci vogliono 10 minuti.
In quei 10 minuti potresti vendere la tua ultima unità su Amazon.
L'utente Google fa clic su... "Non disponibile".
Hai pagato per quel clic.
**La soluzione**:
se "quantità < 3", imposta "disponibilità: esaurito".
"Nascondiamo" intenzionalmente le ultime unità dalle reti pubblicitarie per evitare picchi di "frequenza di rimbalzo" e un'esperienza cliente negativa.
## 12. Nutrire la bestia: Performance Max (PMax)
Il nuovo tipo di campagna "Black Box" (PMax) di Google adora gli asset.
Non vuole solo un titolo.
Vuole:
* `lifestyle_images`: array di URL che mostrano il prodotto in uso.
* `short_description`: 150 caratteri.
* `product_highlight`: elenchi puntati.
La maggior parte dei connettori li elimina.
Mappiamo i nostri campi **Sanity CMS** a questi attributi estesi.
Maggiore è il contesto di PMax, più economico diventa il tuo CPC.
## 13. Titoli dei feed di test A/B
"Nike Air Max" fa clic meglio di "Scarpe da corsa da uomo"?
Non lo sai.
Dividiamo l'ID prodotto.
* `ID-123-A` -> Titolo A.
* `ID-123-B` -> Titolo B.
Inviamo entrambe le varianti a Google (come prodotti separati, ma condividendo lo stock tramite l'ID del gruppo di articoli).
Analizziamo il CTR.
Il vincitore prende tutto.
Questa è la **Sperimentazione sui feed**.
## 14. Conclusione
Il Product Feed è il sistema cardiovascolare dell'e-commerce. Pompa i prodotti nell'ecosistema di Internet.
Se i dati sono ricchi, puliti e veloci, gli annunci funzionano.
Se i dati sono scarsi, l’algoritmo muore di fame.
Non ci limitiamo a "sincronizzare" i prodotti. Progettiamo la visibilità.
<hr style="margin: 1rem 0" />
### Il tuo feed perde soldi?
Se visualizzi errori di "mancata corrispondenza del prezzo" o un ROAS basso.
**[Assumi i nostri architetti](/contact)**.