defineLogicFunction
Definujte logické funkce a jejich spouštěče
defineLogicFunction
Definujte logické funkce a jejich spouštěče
Každý soubor funkce používá Dostupné typy spouštěčů:Typ Ve vašem handleru k přeposlaným záhlavím přistupujte takto:Z bezpečnostních důvodů jsou hlavičky odpovědi omezeny na seznam povolených položek. Jakákoli hlavička, která není na seznamu (např. Endpoint je dostupný na:Identifikátor je Výzva dorazí v Smlouva resolveru. Typ Tělo zprávy obsahuje:Příklad události vytvoření:Příklad události aktualizace:Spouštění pouze při aktualizacích e‑mailu:Příklad události smazání:Oba vytvořte jednou v rozsahu modulu a každé místo volání pak podle volaného klienta určí, který přístup používá. Pomocné funkce SDK, které přistupují k vlastním prostředkům vaší aplikace, vždy používají její přístup a ignorují Hlavní body:Abyste deklarovali své parametry jen jednou a obsloužili obě rozhraní, definujte jedno JSON Schema (Jakmile je aplikace nainstalovaná, Enrich Company se zobrazí ve výběru akcí tvůrce workflow. Tvůrce zobrazí
defineLogicFunction() k exportu konfigurace s obslužnou funkcí (handlerem) a volitelnými spouštěči.src/logic-functions/createPostCard.logic-function.ts
- httpRoute: Zpřístupní vaši funkci na HTTP cestě a metodě. V kódu aplikace přidejte prefix
/s/k cestě routy při použitíRestApiClient; nasazená URL používá injektovanou základní adresuTWENTY_FUNCTIONS_URL(nebo\<server-url>/s, pokud není nastavena).
Chcete-li vyvolat logickou funkci spuštěnou trasou z (bezhlavé) front-endové komponenty, podívejte se na Volání logické funkce.
- cron: Spouští vaši funkci podle plánu pomocí výrazu CRON.
- databaseEvent: Spouští se při událostech životního cyklu objektů v pracovním prostoru. Když je operace události
updated, lze konkrétní sledovaná pole určit v poliupdatedFields. Pokud zůstane nedefinované nebo prázdné, spustí funkci jakákoli aktualizace.
např.person.updated,*.created,company.*
- serverRoute: Zpřístupňuje jednu registrací omezenou trasu HTTP. Funkce resolver (deklarovaná pomocí
serverRouteTriggerSettings) běží ve vlastnickém workspace a buď vrátí synchronníResponse, nebo cílový workspace a logickou funkci, která se má zařadit do fronty; v případě zařazení platforma potvrdí přijetí kódem202a spustí tuto cílovou funkci ve frontě workeru. Viz spouštěč serverové trasy.
Funkci můžete také spustit ručně pomocí CLI:Logy můžete sledovat pomocí:
Payload spouštěče trasy
Když spouštěč typu route vyvolá vaši logickou funkci, ta obdrží objektRoutePayload, který odpovídá
AWS HTTP API v2 formátu.
Importujte typ RoutePayload z twenty-sdk/logic-function:RoutePayload má následující strukturu:forwardedRequestHeaders
Ve výchozím nastavení se záhlaví HTTP z příchozích požadavků z bezpečnostních důvodů do vaší logické funkce ne předávají. Chcete-li zpřístupnit konkrétní záhlaví, výslovně je uveďte v poliforwardedRequestHeaders:Názvy záhlaví jsou normalizovány na malá písmena. Přistupujte k nim pomocí klíčů s malými písmeny (například
event.headers['content-type']).Vlastní odpověď HTTP
Ve výchozím nastavení vrácení prosté hodnoty z vašeho handleru odešle tuto hodnotu zpět jako odpověď200 (JSON pro objekty, text/plain pro řetězce). Pro kontrolu stavového kódu a hlaviček odpovědi vraťte Response z twenty-sdk/logic-function:Set-Cookie, CORS hlavičky jako Access-Control-Allow-Origin nebo vlastní hlavičky X-*), je tiše zahozena před odesláním odpovědi. Povolené hlavičky odpovědi jsou:content-typecontent-languagecontent-dispositioncache-controlretry-after
Stavový kód musí být platný stavový kód HTTP (mezi 100 a 599). Názvy hlaviček odpovědi se porovnávají bez rozlišení velikosti písmen.
Chybové odpovědi platformy
Kromě vlastních odpovědí vašeho handleru platforma v některých situacích odpovídá na volání rout přímo:404, když route nebo funkce neexistuje, 403, když je aplikace zastavena, 429, když je dosaženo limitu rychlosti vykonávání, a 422, když jsou produkční dependencies aplikace příliš velké na to, aby se nainstalovaly — viz dependencies size limits.Spouštěč serverové trasy
httpRouteTriggerSettings zpřístupňuje funkci pod /s/ a workspace určuje z hostitele požadavku — což funguje, když má každý workspace svou vlastní doménu. Poskytovatelé třetích stran však doručují události každého tenanta na jednu adresu URL. Pro tento případ použijte serverRouteTriggerSettings.Spouštěč má dvě části:-
Logická funkce resolveru — deklarovaná pomocí
serverRouteTriggerSettings— běží ve vašem vlastnickém workspace (workspace, který je vlastníkem registrace aplikace). Prozkoumá příchozí požadavek a vrátí buď:{ workspaceId, targetLogicFunctionUniversalIdentifier, payload? }— platforma zařadí tento cíl do fronty v určeném workspace a potvrdí přijetí s202 { queued: true }, neboResponseztwenty-sdk/logic-function— platforma tento HTTP response vrátí synchronně a cíl do fronty nezařadí (použijte pro ověřovací handshake, například Slackurl_verification).
rawBodya předaným hlavičkám a může request odmítnout, aniž by se vůbec dotkl cíle. - Cílová (target) logická funkce — běžná per-workspace logická funkce — pak běží v určeném workspace s payloadem vráceným resolverem (nebo s původním payloadem requestu, pokud jej resolver neupravil). Návratovou hodnotu volající HTTP nevidí, když resolver zvolí cestu zařazení do fronty.
src/logic-functions/resolve-server-route.logic-function.ts
src/logic-functions/handle-invoice-paid.logic-function.ts
universalIdentifier resolveru z vašeho manifestu. Zaregistrujte tuto adresu URL u poskytovatele.Odpověď na ověřovací požadavek GET. Někteří poskytovatelé ověřují koncový bod před doručováním tím, že na stejnou adresu URL, na kterou budou později pomocí POST odesílat události, zašlou požadavek GET s výzvou — jedním z nich je WhatsApp Cloud API od společnosti Meta. Trasa serveru odpovídá pouze na POST, pokud neuvedete jinak, proto deklarujte obě metody:event.queryStringParameters a vrácením objektu Response ji ve stejném požadavku odešlete zpět poskytovateli. Tělo řetězce se odesílá jako text/plain, což tito poskytovatelé očekávají:httpMethods nahrazuje výchozí nastavení, namísto aby je doplňovalo, takže samotné ['GET'] způsobí, že trasa odmítne POST. Podporovány jsou pouze GET a POST. Ponechte je nenastavené, pokud poskytovatel nepotřebuje druhé sloveso: trasa, která deklaruje GET, bude mít svůj resolver spuštěný jakýmkoli neověřeným volajícím, včetně crawlerů a nástrojů pro rozbalení odkazů, které bez vyžádání odesílají GET. Na cokoli, pro co platforma nemá metodu, se odpoví 405, aniž by se resolver kdy spustil.Aplikace musí být převzata do vlastnictví a nainstalována v pracovním prostoru vlastníka. Protože resolver běží v pracovním prostoru vlastníka (pracovní prostor, který vlastní registraci aplikace), spouštěč serverové trasy funguje pouze tehdy, když byla aplikace převzata do vlastnictví — tj. má pracovní prostor vlastníka — a tato aplikace je nainstalována v pracovním prostoru vlastníka. Dokud nejsou obě podmínky splněny, resolver nemá kde běžet, takže trasu nelze zpracovat. Aplikace, která zpřístupňuje logickou funkci
serverRouteTriggerSettings, proto nemůže být uvedena na Marketplace, dokud není převzata do vlastnictví a nainstalována v pracovním prostoru vlastníka.LogicFunctionConfig v SDK toto vynucuje v době kompilace: jakmile nastavíte serverRouteTriggerSettings, váš handler je omezen tak, aby vracel buď Response, nebo { workspaceId: string; targetLogicFunctionUniversalIdentifier: string; payload?: object } (nebo Promise jedné z těchto možností). Na dispatch cestě musí být workspaceId workspace, ve kterém je cílová funkce nainstalována, jinak je request odmítnut s chybou 404. Výsledek, který neodpovídá ani jedné z těchto struktur — včetně takového, jehož identifikátory nejsou UUID — je odmítnut s chybou 502.U podpisů requestů většina poskytovatelů podepisuje pomocí HMAC-SHA256; části, které se liší, jsou název hlavičky, kódování digestu a podepsaný řetězec payloadu. Několik příkladů:
Příklad resolveru výše už ukazuje GitHub HMAC-SHA256 flow — přizpůsobte název hlavičky, kódování digestu a podepsaný řetězec payloadu podle poskytovatele, se kterým se integrujete.
Když resolver vrátí dispatch objekt, route odpoví
202 { queued: true } a cíl běží ve frontě workeru — volající nikdy nevidí latenci cíle, výsledek ani chyby (ty jsou zaznamenané v logách běhu). Tím se zabrání tomu, aby opakované doručování na straně odesílatele znásobovalo zpomalení zpracování, což je přesně to, co chcete pro příjem webhooků.Když volající musí v rámci stejného requestu přečíst tělo odpovědi (challenge handshaky, interaktivní potvrzení), vraťte místo toho z resolveru Response. Platforma jej synchronně zopakuje a přeskočí frontu; jeho hlavičky procházejí stejným seznamem povolených položek jako odpovědi HTTP rout. Udržujte resolver rychlý — některým poskytovatelům (např. Slack) vyprší časový limit během několika sekund. Protože je resolver dostupný jako veřejný endpoint, chraňte ho omezením rychlosti (rate limiting) na své edge vrstvě.Payload spouštěče databázové události
Když spouštěč databázové události vyvolá vaši logickou funkci, obdrží jedenDatabaseEventPayload pro každý změněný záznam. Payload kombinuje metadata o zdrojovém pracovním prostoru a objektu s událostí na úrovni záznamu.U logických smazání má
.deleted podobu jako u aktualizace, protože se změní pole deletedAt záznamu.
Pro trvalá smazání použijte .destroyed.databaseEventTriggerSettings.updatedFields filtruje, které události aktualizace spustí funkci.
event.properties.updatedFields říká, která pole se v aktuální události skutečně změnila.Kontext provádění
Každá obslužná funkce obdrží druhý argument popisující samotný běh bez ohledu na to, co jej spustilo. Zatímco tvar prvního argumentu se liší podle spouštěče, tento se nemění:userWorkspaceId a workspaceMemberId mají hodnotu null, když běh nikdo nespustil: plány cron, hooky instalace a neověřené webhooky za sebou nemají žádnou osobu. Hodnotu null mají také tehdy, když osoba nemá záznam člena pracovního prostoru nebo když byl její záznam odstraněn.Kontext vám sdělí, kdo běh spustil. To, co běh smí dělat, je samostatná deklarace uvedená níže.
Čí přístup volání používá
Každý klient —CoreApiClient, MetadataApiClient a RestApiClient — jedná jako osoba, která běh spustila: její role se protíná s rolí vaší aplikace, takže volání nikdy nemůže udělat více, než může kterýkoli z vás. Toto je výchozí chování a znamená, že osoba nikdy nemůže použít vaši aplikaci k překročení vlastních oprávnění.Když běh nikdo nespustil, není žádná osoba, za kterou by bylo možné jednat, takže stejný klient přejde na vlastní přístup vaší aplikace: plány cron, hooky instalace a neověřené webhooky nevyžadují zvláštní zpracování.Některá volání oprávněně potřebují vlastní přístup aplikace, i když za během je osoba — například pro čtení konfiguračních záznamů vaší aplikace nebo provádění práce, kterou by tato osoba sama nemohla vykonat. Pro tyto případy vytvořte druhého klienta:RestApiClient přijímá stejnou možnost:Běh, který nikdo nespustil, jedná jako vaše aplikace. Plány cron, hooky instalace a neověřené webhooky za sebou nemají žádnou osobu, takže výchozí klient přejde na vlastní přístup vaší aplikace a nadále funguje.
runAs: 'application' je potřeba jen tehdy, když tento přístup chcete při běhu, který osoba skutečně spustila.Když se funkce chová odlišně podle toho, zda za ní někdo stojí, zkontrolujte context.workspaceMemberId, například pro přiřazení záznamu.runAs: úložiště klíč-hodnota, připojení, runAgent, getPublicAssetUrl a účtování kreditů.Zpřístupnění funkce jako nástroje AI nebo akce pracovního postupu
Logické funkce lze zpřístupnit na dvou rozhraních, z nichž každé má vlastní spouštěč:toolTriggerSettings— zpřístupní funkci AI funkcím Twenty (chat, MCP, volání funkcí). Používá standardní JSON Schema, formát, kterému modely LLM nativně rozumějí.workflowActionTriggerSettings— zobrazí funkci jako krok ve vizuálním builderu workflow. Používá bohatéInputSchemaod Twenty, aby builder mohl vykreslit správné editory polí, voliče proměnných a štítky.
cronTriggerSettings, databaseEventTriggerSettings a httpRouteTriggerSettings — stejný vzor, stejná struktura.Vztah k akci Code ve workflow. Vestavěná akce Code v tvůrci workflow je sama o sobě logická funkce — Twenty pro každý krok Code vytvoří jednu a její editor zpřístupní inline.
workflowActionTriggerSettings je způsob, jak z jednorázového inline kódu udělat znovupoužitelnou akci: funkci v aplikaci nadefinujete jednou a potom je možné ji vybrat v libovolném workflow, místo aby se kopírovala do každého kroku Code. Pro pohled koncového uživatele se podívejte na akci Code v uživatelské příručce.src/logic-functions/enrich-company.logic-function.ts
- Funkce může míchat rozhraní — deklarujte jak
toolTriggerSettings, takworkflowActionTriggerSettings, abyste ji zpřístupnili v chatu i ve workflow builderu. toolTriggerSettings.inputSchemaaworkflowActionTriggerSettings.inputSchemajsou obě volitelné. Pokud jsou vynechány, sestavovač manifestu je odvodí ze zdrojového kódu handleru (JSON Schema pro nástroj AI,InputSchemaod Twenty pro akci workflow). Uveďte jej explicitně, když chcete bohatší typování — například u polí s podporouFieldMetadataType, jakoCURRENCYneboRELATIONpro workflow builder, nebo s polidescription, která si AI agent může přečíst:
InputJsonSchema) a převeďte jej pro akci pracovního postupu pomocí jsonSchemaToInputSchema z twenty-sdk/logic-function. toolTriggerSettings.inputSchema přebírá JSON Schema přímo, zatímco workflowActionTriggerSettings.inputSchema očekává InputSchema od Twenty:Kompletní příklad akce workflow
workflowActionTriggerSettings přijímá čtyři pole:Dohromady — funkce zpřístupněná jako akce workflow s deklarovaným výstupem, aby se na
taskId mohly odkazovat pozdější kroky:src/logic-functions/enrich-company.logic-function.ts
companyName a domain jako vstupní pole (každé z nich může získávat hodnoty z předchozích kroků) a následující kroky se mohou odkazovat na výstupy kroku taskId a enriched.Napište kvalitní
description. Agenti AI se spoléhají na pole funkce description při rozhodování, kdy nástroj použít. Buďte konkrétní ohledně toho, co nástroj dělá a kdy se má volat.Pomocné nástroje za běhu.
twenty-sdk/utils znovu exportuje malé pomocné nástroje pro běh, takže handlery nikdy neimportují přímo z twenty-shared. Například isDefined(value) vrací false jak pro null, tak pro undefined — použijte jej k bezpečnému zúžení volitelných vstupů handleru, které mohou za běhu dorazit jako null, i když jsou typované jako T | undefined:Instalační hooky — předinstalační, poinstalační a odinstalační handlery — sdílejí toto běhové prostředí, ale deklarují se vlastními funkcemi
define a nepřebírají nastavení spouštěče (triggeru). Viz Instalační hooky pro definePreInstallLogicFunction, definePostInstallLogicFunction a defineUninstallLogicFunction.Vytvoření aktivity časové osy.
PomocícreateTimelineActivity() publikujte explicitní doménovou událost z logické funkce. Nejprve definujte událost jako typ aktivity časové osy a poté typ a objekty adresujte pomocí jejich stabilních univerzálních identifikátorů:
timelineActivityTypeUniversalIdentifier, targetObjectUniversalIdentifier a targetRecordId. Můžete také zadat happensAt, properties a workspaceMemberId. happensAt určuje pozici události a zobrazený čas na časové ose; výchozí hodnotou je čas vytvoření.
Chcete-li k události přidružit jiný záznam, zadejte společně linkedRecordId a linkedObjectMetadataUniversalIdentifier. Jako záložní možnost historického zobrazení můžete navíc zadat linkedRecordCachedName:
timelineActivity. Explicitní typy událostí ponechte nevázané na action; typ vázaný na akci již automaticky přijímá události auditu a jinak by vytvářel duplicitní řádky.
Typovaní klienti API (twenty-client-sdk)
Balíčektwenty-client-sdk poskytuje dva typované klienty GraphQL pro práci s Twenty API z vašich logických funkcí a frontendových komponent.
CoreApiClient
Dotazování a změny dat pracovního prostoru (záznamy, objekty)
CoreApiClient
Dotazování a změny dat pracovního prostoru (záznamy, objekty)
CoreApiClient je hlavní klient pro dotazování a mutace dat pracovního prostoru. Generuje se z vašeho schématu pracovního prostoru během yarn twenty dev nebo yarn twenty dev:build, takže je plně typovaný tak, aby odpovídal vašim objektům a polím.true zahrnete pole, pro argumenty použijte __args a pro relace vnořujte objekty. Získáte plné automatické doplňování a kontrolu typů založené na schématu vašeho pracovního prostoru.CoreApiClient je generován při vývoji/sestavení. Pokud jej použijete bez předchozího spuštění
yarn twenty dev nebo yarn twenty dev:build, vyvolá chybu. Generování probíhá automaticky — CLI prozkoumá GraphQL schéma vašeho pracovního prostoru a vygeneruje typovaného klienta pomocí @genql/cli.Použití CoreSchema pro anotace typů
CoreSchema poskytuje typy TypeScriptu odpovídající objektům vašeho pracovního prostoru — hodí se pro typování stavu komponent nebo parametrů funkcí:MetadataApiClient
Konfigurace pracovního prostoru, aplikace a nahrávání souborů
MetadataApiClient
Konfigurace pracovního prostoru, aplikace a nahrávání souborů
MetadataApiClient je dodáván předem sestavený v rámci SDK (není vyžadováno žádné generování). Odesílá dotazy na endpoint /metadata pro konfiguraci pracovního prostoru, aplikace a nahrávání souborů. Přijímá stejnou možnost runAs jako CoreApiClient — viz Čí přístup volání používá.Nahrávání souborů
MetadataApiClient obsahuje metodu uploadFile pro připojování souborů k polím typu souboru:Hlavní body:
- Používá
universalIdentifierpole (nikoli jeho ID specifické pro pracovní prostor), takže váš kód pro nahrávání funguje v jakémkoli pracovním prostoru, kde je vaše aplikace nainstalována. - Vrácená hodnota
urlje podepsaná adresa URL, kterou můžete použít k přístupu k nahranému souboru.
Když váš kód běží na Twenty (logické funkce nebo frontendové komponenty), platforma vloží přihlašovací údaje jako proměnné prostředí:
TWENTY_API_URL— Základní URL Twenty APITWENTY_APP_ACCESS_TOKEN— krátkodobý klíč pro výchozí přístup: roli osoby, když někdo stojí za během, protíná role vaší aplikace; když nikdo nestojí za během, používá se vlastní role vaší aplikace. Osobou je kdokoli, kdo spustil běh v logické funkci, nebo kdokoli, kdo si prohlíží stránku ve frontové komponentě.TWENTY_APP_APPLICATION_ACCESS_TOKEN— krátkodobý klíč s rozsahem omezeným pouze na vlastní roli vaší aplikace. Pouze pro logické funkce, vždy se do nich vkládá a používá jejrunAs: 'application'.
process.env a Čí přístup volání používá popisuje volbu mezi nimi. Vlastní oprávnění vaší aplikace jsou určena rolí deklarovanou pomocí defineApplicationRole() (nebo odkazovanou prostřednictvím defaultRoleUniversalIdentifier v application-config.ts); běh jednající jako osoba nikdy nemůže překročit ani tuto roli, ani roli této osoby.