Použijte tento vzor k udržení synchronizace Twenty s produktovými daty z vašeho datového skladu (např. Snowflake, BigQuery, PostgreSQL).
Struktura pracovního postupu
- Spouštěč: Podle plánu
- Code: Spusťte dotaz na svůj datový sklad
- Code (volitelné): Naformátujte data jako pole
- Iterator: Procházejte jednotlivé produkty
- Upsert Record: Vytvořte nebo aktualizujte záznam v Twenty
Krok 1: Naplánujte spouštěč
Nastavte pracovní postup tak, aby běžel s frekvencí odpovídající vašim požadavkům na aktuálnost dat:
- Každých 5 minut pro synchronizaci téměř v reálném čase
- Každou hodinu pro méně kritická data
- Denně pro dávkové aktualizace
Krok 2: Proveďte dotaz na svůj datový sklad
Přidejte akci Code pro načtení nejnovějších dat:
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 };
};
Filtrováním podle updated_at >= last X minutes získáte pouze nedávno změněné záznamy. Díky tomu zůstane synchronizace efektivní.
Pokud váš datový sklad vrací data ve formátu, který vyžaduje transformaci, přidejte další akci Code. Mezi běžné transformace patří převody typů, přejmenování polí a čištění dat.
Příklad: Uživatelská data s logickými a stavovými poli
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),
})),
};
};
Příklad: Produktová data s převody typů
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, " ")
}))
};
};
| Zdrojový formát | Cílový formát | Kód |
|---|
"true" / "false" | true / false | v === true || v === "true" |
"123.45" | 123.45 | parseFloat(value) |
"active" | "ACTIVE" | value.toUpperCase() |
1704067200 (Unix) | Datum ve formátu ISO | new Date(v * 1000).toISOString() |
"$1,234.56" | 1234.56 | parseFloat(v.replace(/[^0-9.-]/g, "")) |
null / undefined | "" | value || "" |
Krok 4: Projděte produkty
Přidejte akci Iterator:
Tímto projdete každý produkt v poli.
Krok 5: Proveďte upsert pro každý záznam
Uvnitř iterátoru přidejte akci Upsert Record:
| Nastavení | Hodnota |
|---|
| Objekt | Váš vlastní objekt Product |
| Shoda podle | Externí ID nebo SKU (jedinečný identifikátor) |
| Název | {{iterator.item.name}} |
| SKU | {{iterator.item.sku}} |
| Cena | {{iterator.item.price}} |
Použijte Upsert (aktualizace nebo vytvoření) místo vytváření samostatných větví pro vytvoření vs. aktualizaci. Je to rychlejší na vytvoření a snazší na ladění.
Příklady použití
| Zdroj | Data |
|---|
| ERP systém | Katalog produktů, ceny, skladové zásoby |
| E-commerce platforma | Objednávky, zákazníci, aktualizace produktů |
| Datový sklad | Agregované metriky, obohacená data |
| Skladový systém | Stavy zásob, upozornění na doobjednání |
Související