Passa al contenuto principale

Creare un flusso di integrazione tra Akeneo PIM e Shopify

1. Introduzione

Questo tutorial spiega come automatizzare il trasferimento dei dati prodotto da Akeneo PIM a Shopify usando la piattaforma di integrazione Flowlyze. Collegando questi sistemi si elimina l'inserimento manuale dei dati, assicurando che lo storefront mostri sempre informazioni prodotto accurate e correttamente formattate.

Video tutorial

💡 Suggerimento: Guarda il video qui sotto per vedere il flusso passo passo.

2. Prerequisiti

  • Un account Akeneo PIM attivo con accesso alle API (Client ID, Secret, Username, Password).
  • Uno store Shopify con un Admin API Access Token.
  • Un account Flowlyze attivo.
  • Familiarità di base con le strutture JSON e con la sintassi C# per le action di formattazione dati.

3. Architettura dell'integrazione

Il flusso dati segue un'architettura a pipeline lineare:

  • Trigger: Flowlyze si connette ad Akeneo e recupera i dati grezzi dei prodotti.
  • Trasformazione: La Mapping Action allinea gli attributi Akeneo allo schema di Shopify. Successivamente, la Data Formatting Action usa script C# leggeri per pulire e strutturare i dati.
  • Destinazione Shopify: Il payload elaborato viene inviato tramite l'adapter nativo Shopify. Per il tracciato di anagrafica prodotti consulta la documentazione Shopify.

4. Implementazione passo passo

Passo 4.1: Configurare il trigger su Akeneo

Per prima cosa, stabilisci una connessione sicura alla sorgente dati:

  1. Nell'area di lavoro di Flowlyze, aggiungi un nuovo nodo Source e seleziona Akeneo.
  2. Completa l'autenticazione inserendo le credenziali API di Akeneo (Client ID, Secret, Username e Password).
  3. Configura l'evento di trigger per recuperare i cataloghi prodotto con una schedulazione definita o tramite esecuzione manuale.

Passo 4.2: Trasformazione e mapping dei dati (Flowlyze)

Qui risiede la logica principale:

  1. Mapping Action: Aggiungi un nodo Mapping. Collega i campi in arrivo da Akeneo ai corrispondenti campi di destinazione. Ad esempio, mappa identifier di Akeneo su SKU di Shopify.
  2. Data Formatting Action: Aggiungi un nodo Formatting subito dopo il nodo di mapping. Utilizza l'ambiente di Flowlyze per scrivere brevi script C# di formattazione. Ad esempio, puoi analizzare il testo per formattare correttamente i titoli o rimuovere simboli di valuta indesiderati dai campi prezzo numerici prima che arrivino a Shopify.
using System;
using System.Collections.Generic;

var finalOutput = new Dictionary<string, object>();
// ==========================================
// --- 1. FORMATTAZIONE SKU E VARIANTI ---
// ==========================================
var skuValue = Data.GetString("sku");
string formattedSku = string.IsNullOrEmpty(skuValue) ? string.Empty : skuValue.Replace(" ", "-").ToUpperInvariant();

// PARTE MANCANTE DA AGGIUNGERE
finalOutput["sku"] = formattedSku;
finalOutput["options"] = new List<string> { "Title" };

finalOutput["variants"] = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
{ "sku", formattedSku },
{
"optionValues", new Dictionary<string, string>
{
{ "Title", "Default Title" }
}
}
}
};

// ==========================================
// --- 2. MAPPATURA CATEGORIE ---
// ==========================================
var categoryValue = Data.GetString("category");

if (!string.IsNullOrEmpty(categoryValue))
{
var categoryMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "drones", "gid://shopify/TaxonomyCategory/tg-5-12-2" },
{ "industrial_tools", "gid://shopify/TaxonomyCategory/ha-14-9" },
{ "three_d_printers", "gid://shopify/TaxonomyCategory/el-13-2" },
{ "robotics", "gid://shopify/TaxonomyCategory/el" },
{ "sensors", "gid://shopify/TaxonomyCategory/el-5-7" }
};

if (categoryMap.TryGetValue(categoryValue, out string shopifyGid))
{
finalOutput["category"] = shopifyGid;
}
else
{
finalOutput["category"] = categoryValue;
}
}

finalOutput["title"] = Data.GetString("title");
finalOutput["description"] = Data.GetString("description");
finalOutput["vendor"] = Data.GetString("vendor");
finalOutput["status"] = Data.GetString("status");

// ==========================================
// --- 3. REPERIMENTO MEDIA DA AKENEO (CON UN SOLO TOKEN) ---
// ==========================================
var shopifyMediaList = new List<Dictionary<string, string>>();
var assetCodesRaw = Data.GetListString("akeneo_asset_codes");

if (!string.IsNullOrEmpty(skuValue) && assetCodesRaw != null && assetCodesRaw.Count > 0)
{
string akeneoDomain = "{{Your_akeneoDomain}}";
string validToken = "";

string clientId = "{{Your_clientId}}";
string clientSecret = "{{Your_clientSecret}}";
string myUsername = "{{Your_username}}";
string myPassword = "{{Your_password}}";

// Per performance, il token viene richiesto una sola volta
var tokenRequest = new CustomHttpRequest
{
Url = $"{akeneoDomain}/api/oauth/v1/token",
Method = "POST",
Post = new Dictionary<string, string>
{
{ "grant_type", "password" },
{ "username", myUsername },
{ "password", myPassword },
{ "client_id", clientId },
{ "client_secret", clientSecret }
}
};

try
{
var tokenResponse = Http.ExecuteRest(tokenRequest);
validToken = tokenResponse.GetString("access_token");
}
catch (Exception ex)
{
Logger.Log("Errore token: " + ex.Message);
}

if (!string.IsNullOrEmpty(validToken))
{
string assetFamily = "imported_assets";
int index = 1;

foreach (var assetCode in assetCodesRaw)
{
if (string.IsNullOrWhiteSpace(assetCode)) continue;

var assetInfoRequest = new CustomHttpRequest
{
Url = $"{akeneoDomain}/api/rest/v1/asset-families/{assetFamily}/assets/{assetCode}",
Method = "GET",
Headers = new Dictionary<string, string>
{
{ "Authorization", $"Bearer {validToken}" },
{ "Accept", "application/json" }
}
};

try
{
var assetResponse = Http.ExecuteRest(assetInfoRequest);
string publicUrl = assetResponse.GetString("values.media_link[0].data");

if (!string.IsNullOrEmpty(publicUrl))
{
shopifyMediaList.Add(new Dictionary<string, string>
{
{ "url", publicUrl },
{ "alternativeText", $"{formattedSku} image {index}" }
});
}
}
catch (Exception ex)
{
Logger.Log("Eccezione nel recupero dell'asset ({0}): {1}", assetCode, ex.Message);
}
index++;
}
}
}

if (shopifyMediaList.Count > 0)
{
finalOutput["media"] = shopifyMediaList;
}

return finalOutput;

Passo 4.3: Configurare l'action su Shopify

Ora instrada i dati preparati verso lo storefront:

  1. Aggiungi un nodo Destination alla fine della pipeline e seleziona Shopify.
  2. Autentica la connessione usando lo Shopify Admin API Access Token.
  3. Imposta l'operazione su sincronizzazione prodotti. Seleziona le caselle Active product e Publish product per assicurarti che il prodotto sia marcato come attivo e visibile sui canali dello storefront, quindi mappa il payload finalizzato.

5. Test e pubblicazione

Per verificare che la pipeline funzioni come previsto:

  1. Esegui un test in Flowlyze con il payload di un singolo prodotto da Akeneo.
  2. Controlla i log della Execution History di Flowlyze per assicurarti che sia la Mapping Action sia la Formatting Action abbiano elaborato i dati correttamente.
  3. Quando i log mostrano un'esecuzione riuscita, abilita il flusso per la sincronizzazione automatica.
  4. Dopo l'attivazione del flusso, accedi al pannello Shopify Admin e verifica che i prodotti compaiano con lo SKU corretto e i prezzi precisi.

6. Gestione errori e troubleshooting

  • Errori di autenticazione: Ricontrolla gli API Access Token. I token potrebbero scadere o non avere i permessi di lettura/scrittura necessari.
  • Errori di mapping: Se un campo obbligatorio di Shopify manca nel payload Akeneo, l'API rifiuterà la richiesta. Assicurati di assegnare valori di fallback nello step di formattazione C#.
  • Incongruenze di tipo: Assicurati che i campi prezzo vengano inviati come numeri o stringhe formattate correttamente, come richiesto da Shopify. Usa l'action C# per convertire i tipi di dato se necessario.

7. Conclusioni e prossimi passi

Hai costruito con successo un'integrazione automatizzata end-to-end tra Akeneo e Shopify. Come passo successivo, valuta di estendere la logica di formattazione C# per gestire in modo efficiente le varianti prodotto.