Usa questo modello per mantenere Twenty sincronizzato con i dati di prodotto dal tuo data warehouse (ad esempio, Snowflake, BigQuery, PostgreSQL).
Struttura del flusso di lavoro
- Trigger: In base a una pianificazione
- Code: Interroga il tuo data warehouse
- Code (opzionale): Formatta i dati come array
- Iterator: Itera su ciascun prodotto
- Upsert Record: Crea o aggiorna in Twenty
Passaggio 1: Pianifica il trigger
Imposta il flusso di lavoro per l’esecuzione con una frequenza che corrisponda alle tue esigenze di aggiornamento dei dati:
- Ogni 5 minuti per una sincronizzazione quasi in tempo reale
- Ogni ora per i dati meno critici
- Ogni giorno per aggiornamenti in batch
Passaggio 2: Interroga il tuo data warehouse
Aggiungi un’azione Code per recuperare i dati recenti:
export const main = async () => {
const intervalMinutes = 10; // Match your schedule frequency
const cutoffTime = new Date(Date.now() - intervalMinutes * 60 * 1000).toISOString();
// Replace with your actual data warehouse connection
const response = await fetch("https://your-warehouse-api.com/query", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
query: `
SELECT id, name, sku, price, stock_quantity, updated_at
FROM products
WHERE updated_at >= '${cutoffTime}'
`
})
});
const data = await response.json();
return { products: data.results };
};
Filtra per updated_at >= last X minutes per recuperare solo i record modificati di recente. Questo mantiene efficiente la sincronizzazione.
Se il tuo data warehouse restituisce dati in un formato che richiede una trasformazione, aggiungi un’altra azione Code. Le trasformazioni comuni includono conversioni di tipo, ridenominazione dei campi e pulizia dei dati.
Esempio: Dati utente con campi booleani e di stato
export const main = async (params: {
users: any;
}): Promise<object> => {
const { users } = params;
const usersFormatted = typeof users === "string" ? JSON.parse(users) : users;
// Convert string "true"/"false" to actual booleans
const toBool = (v: any) => v === true || v === "true";
return {
users: usersFormatted.map((user) => ({
...user,
activityStatus: String(user.activityStatus).toUpperCase(),
isActiveLast30d: toBool(user.isActiveLast30d),
isActiveLast7d: toBool(user.isActiveLast7d),
isActiveLast24h: toBool(user.isActiveLast24h),
isTwenty: toBool(user.isTwenty),
})),
};
};
Esempio: Dati di prodotto con conversioni di tipo
export const main = async (params: { products: any }) => {
const products = typeof params.products === "string"
? JSON.parse(params.products)
: params.products;
return {
products: products.map(product => ({
externalId: product.id,
name: product.name,
sku: product.sku,
price: parseFloat(product.price), // String → Number
stockQuantity: parseInt(product.stock_quantity),
isActive: product.status === "active" // String → Boolean
}))
};
};
export const main = async (params: { deals: any }) => {
const deals = typeof params.deals === "string"
? JSON.parse(params.deals)
: params.deals;
return {
deals: deals.map(deal => ({
...deal,
// Convert Unix timestamp to ISO date
closedAt: deal.closed_timestamp
? new Date(deal.closed_timestamp * 1000).toISOString()
: null,
// Ensure amount is a number (remove currency symbols)
amount: parseFloat(String(deal.amount).replace(/[^0-9.-]/g, "")),
// Normalize stage names
stage: deal.stage?.toLowerCase().replace(/_/g, " ")
}))
};
};
| Formato di origine | Formato di destinazione | Codice |
|---|
"true" / "false" | true / false | v === true || v === "true" |
"123.45" | 123.45 | parseFloat(value) |
"active" | "ACTIVE" | value.toUpperCase() |
1704067200 (Unix) | Data ISO | new Date(v * 1000).toISOString() |
"$1,234.56" | 1234.56 | parseFloat(v.replace(/[^0-9.-]/g, "")) |
null / undefined | "" | value || "" |
Passaggio 4: Itera sui prodotti
Aggiungi un’azione Iterator:
Questo esegue un ciclo su ogni prodotto nell’array.
Passaggio 5: Esegui l’upsert di ogni record
All’interno dell’Iterator, aggiungi un’azione Upsert Record:
| Impostazione | Valore |
|---|
| Oggetto | Il tuo oggetto Prodotto personalizzato |
| Corrispondenza per | ID esterno o SKU (identificatore univoco) |
| Nome | {{iterator.item.name}} |
| SKU | {{iterator.item.sku}} |
| Prezzo | {{iterator.item.price}} |
Usa Upsert (aggiornare o creare) invece di creare rami separati per creazione e aggiornamento. È più veloce da costruire e più facile da eseguire il debug.
Esempi di casi d’uso
| Fonte | Dati |
|---|
| Sistema ERP | Catalogo prodotti, prezzi, inventario |
| Piattaforma e-commerce | Ordini, clienti, aggiornamenti dei prodotti |
| Data warehouse | Metriche aggregate, dati arricchiti |
| Sistema di inventario | Livelli di stock, avvisi di riordino |
Correlati