Skip to main content
Mantık işlevleri, Twenty platformunda çalışan sunucu tarafı TypeScript işlevleridir. HTTP istekleri, cron zamanlamaları veya veritabanı olayları tarafından tetiklenebilirler — ve ayrıca yapay zekâ ajanları için araçlar olarak sunulabilirler.
Her işlev dosyası, bir işleyici ve isteğe bağlı tetikleyiciler içeren bir yapılandırmayı dışa aktarmak için defineLogicFunction() kullanır.
src/logic-functions/createPostCard.logic-function.ts
Kullanılabilir tetikleyici türleri:
  • httpRoute: İşlevinizi bir HTTP yolu ve yöntemiyle kullanıma sunar. Uygulama kodunda, RestApiClient kullanırken rota yolunun başına /s/ önekini ekleyin; dağıtılan URL, enjekte edilen TWENTY_FUNCTIONS_URL temel URL’sini (veya bu ayarlı değilse \<server-url>/s) kullanır.
Arayüzsüz bir ön uç bileşeninden rota tarafından tetiklenen mantık fonksiyonunu çağırmak için bkz. Mantık fonksiyonu çağırma.
  • cron: Bir CRON ifadesi kullanarak işlevinizi bir zamanlamayla çalıştırır.
  • databaseEvent: Çalışma alanı nesnesi yaşam döngüsü olaylarında çalışır. Olay işlemi updated olduğunda, dinlenecek belirli alanlar updatedFields dizisinde belirtilebilir. Tanımsız veya boş bırakılırsa, herhangi bir güncelleme işlevi tetikler.
örn. person.updated, *.created, company.*
  • serverRoute: Kayıt kapsamına sahip tek bir HTTP rotasını erişime açar. Bir resolver fonksiyonu (serverRouteTriggerSettings ile tanımlanır) sahip çalışma alanında çalışır ve ya senkron bir Response ya da kuyruğa eklenecek hedef çalışma alanını VE mantık fonksiyonunu döndürür; kuyruğa ekleme yolunda platform 202 ile onay verir ve bu hedefi worker kuyruğunda çalıştırır. Sunucu rota tetikleyicisine bakın.
Bir işlevi CLI kullanarak manuel olarak da çalıştırabilirsiniz:
Günlükleri şu şekilde izleyebilirsiniz:

Rota tetikleyicisi yükü

Bir rota tetikleyicisi mantık fonksiyonunuzu çağırdığında, AWS HTTP API v2 formatını izleyen bir RoutePayload nesnesi alır. RoutePayload türünü twenty-sdk/logic-function içinden içe aktarın:
RoutePayload türünün yapısı şu şekildedir:

forwardedRequestHeaders

Varsayılan olarak, güvenlik nedenleriyle gelen isteklerden HTTP başlıkları mantık fonksiyonunuza aktarılmaz. Belirli başlıklara erişmek için bunları forwardedRequestHeaders dizisinde listeleyin:
İşleyicinizde, iletilen başlıklara şu şekilde erişin:
Başlık adları küçük harfe normalize edilir. Onlara küçük harfli anahtarlarla erişin (örneğin, event.headers['content-type']).

Özel HTTP yanıtı

Varsayılan olarak, işleyicinizden düz bir değer döndürmek, onu 200 yanıtı olarak geri gönderir (nesneler için JSON, stringler için text/plain). Durum kodunu ve yanıt üstbilgilerini kontrol etmek için, twenty-sdk/logic-function içinden bir Response döndürün:
Güvenlik nedenleriyle, yanıt üstbilgileri bir izin listesiyle sınırlandırılmıştır. Listede yer almayan herhangi bir üstbilgi (örneğin Set-Cookie, Access-Control-Allow-Origin gibi CORS üstbilgileri veya özel X-* üstbilgileri), yanıt gönderilmeden önce sessizce yok sayılır. İzin verilen yanıt üstbilgileri şunlardır:
  • content-type
  • content-language
  • content-disposition
  • cache-control
  • retry-after
Durum kodu geçerli bir HTTP durum kodu olmalıdır (100 ile 599 arasında). Yanıt üstbilgisi adları büyük/küçük harfe duyarsız olarak eşleştirilir.

Sunucu rota tetikleyicisi

httpRouteTriggerSettings, /s/ altında bir fonksiyon sunar ve çalışma alanını istek ana bilgisayarından çözümler — bu da her çalışma alanının kendi alan adına sahip olduğu durumda işe yarar. Üçüncü taraf sağlayıcılar ise, her kiracının olaylarını tek URL’ye iletir. Bu durum için serverRouteTriggerSettings kullanın.Tetikleyicinin iki parçası vardır:
  1. Bir resolver mantık fonksiyonu — serverRouteTriggerSettings ile tanımlanır — sahip çalışma alanınızda (uygulama kaydına sahip olan çalışma alanı) çalışır. Gelen isteği inceler ve şu ikisinden birini döndürür:
    • { workspaceId, targetLogicFunctionUniversalIdentifier, payload? } — platform bu hedefi çözümlenen çalışma alanında kuyruğa ekler ve 202 { queued: true } ile onay verir, veya
    • twenty-sdk/logic-function içinden bir Response — platform bu HTTP yanıtını senkron şekilde yansıtır ve hiçbir hedefi kuyruğa eklemez (bunu Slack url_verification gibi doğrulama el sıkışmaları için kullanın).
    Resolver, yetkilendirmenin tek noktasıdır — URL yalnızca resolver’ın tanımlayıcısını taşır. İstek imzalarını doğrulamak için tercih edilen yer burasıdır: resolver, herhangi bir yan etkiden önce çalışır, orijinal rawBody ve iletilen başlıklara erişebilir ve hedefe hiç dokunmadan isteği reddedebilir.
  2. Ardından bir hedef mantık fonksiyonu — her çalışma alanı için normal bir mantık fonksiyonu — resolver tarafından döndürülen payload ile (veya resolver onu dönüştürmediyse orijinal istek payload’ı ile) çözümlenen çalışma alanında çalışır. Çözümleyici kuyruğa alma yolunu seçtiğinde, döndürdüğü değer HTTP çağrıcısı tarafından gözlemlenmez.
src/logic-functions/resolve-server-route.logic-function.ts
src/logic-functions/handle-invoice-paid.logic-function.ts
Uç noktaya şu adresten erişilebilir:
Tanımlayıcı, manifest’inizdeki resolver’ın universalIdentifier değeridir. Bu URL’yi sağlayıcıya kaydedin.
Uygulama, sahip çalışma alanında sahiplenilip kurulmalıdır. Çözücü sahip çalışma alanında (uygulama kaydına sahip olan çalışma alanı) çalıştığı için, bir sunucu rota tetikleyicisi yalnızca uygulama sahiplenildikten — yani bir sahip çalışma alanına sahiptir — ve o uygulama sahip çalışma alanına kurulduğunda çalışır. Her ikisi de doğru olana kadar çözücünün çalışacağı bir yer yoktur, bu yüzden rota çalıştırılamaz. Bu nedenle, serverRouteTriggerSettings mantık işlevini sunan bir uygulama, sahip çalışma alanında sahiplenilip kurulana kadar pazaryerinde listelenemez.
Resolver sözleşmesi. SDK’nin LogicFunctionConfig türü bunu derleme zamanında zorunlu kılar: serverRouteTriggerSettings’i ayarladığınız anda, işleyicinizin ya bir Response ya da { workspaceId: string; targetLogicFunctionUniversalIdentifier: string; payload?: object } (veya bunlardan birinin Promise’i) döndürmesi gerekir. Dispatch yolunda, workspaceId hedef fonksiyonun kurulu olduğu bir çalışma alanı olmalıdır, aksi takdirde istek 404 ile reddedilir. Her iki şekille de eşleşmeyen bir sonuç — tanımlayıcıları UUID olmayanlar da dahil — 502 ile reddedilir.
İmza doğrulama sizin sorumluluğunuzdadır — doğrulamayı resolver içinde yapın. Platform istek imzalarını doğrulamaz. Bunu yapmak için önerilen yer resolver’dır: ilk olarak çalışır, event.rawBody ve forwardedRequestHeaders içinde listelediğiniz başlıklara erişir ve fırlatılan bir hata (veya eşleşmeyen herhangi bir workspaceId) hedef çağrılmadan önce yönlendirmeyi durdurur. Doğrulamayı bunun yerine hedefin içine iterseniz, hedef rawBody ve başlıkları kaybetmemeye dikkat etmelidir — yani resolver bir payload döndürmemelidir. Her zaman herhangi bir yan etkiden önce doğrulayın ve sabit süreli bir karşılaştırma kullanın.
İstek imzaları için, sağlayıcıların çoğu HMAC-SHA256 ile imzalar; farklı olan kısımlar başlık adı, özet kodlaması ve imzalanan payload dizesidir. Birkaç örnek:Yukarıdaki resolver örneği GitHub HMAC-SHA256 akışını zaten göstermektedir — tümleştirdiğiniz sağlayıcıya göre başlık adını, özet kodlamasını ve imzalanan payload dizesini uyarlayın.
Resolver bir dispatch nesnesi döndürdüğünde, yol 202 { queued: true } yanıtını verir ve hedef worker kuyruğunda çalıştırılır — çağıran taraf hedefin gecikmesini, sonucunu veya hatalarını asla gözlemlemez (bunlar yürütme günlüklerinde kaydedilir). Bu, göndericinin yeniden gönderimlerinin işlem yavaşlamalarını artırmasını engeller; bu da webhook alımı için istediğiniz şeydir.Çağıran tarafın yanıt gövdesini aynı istek üzerinde okuması gerektiğinde (challenge el sıkışmaları, etkileşimli onaylar), bunun yerine resolver’dan bir Response döndürün. Platform bunu eşzamanlı olarak geri yansıtır ve kuyruğu atlar; başlıkları, HTTP route yanıtlarıyla aynı izin listesi üzerinden geçirilir. Resolver’ı hızlı tutun — bazı sağlayıcılar (örn. Slack) birkaç saniye içinde zaman aşımına uğrar. Resolver herkese açık bir uç nokta olarak erişilebilir olduğundan, onu edge’inizde hız sınırlama ile koruyun.

Veritabanı olay tetikleyicisi yükü

Bir veritabanı olay tetikleyicisi mantık fonksiyonunuzu çağırdığında, değişen her kayıt için bir DatabaseEventPayload alır. Yük, kaynak çalışma alanı ve nesne hakkındaki üstveriyi, kayıt düzeyindeki olayla birleştirir.
Yük, şunları içerir:Yumuşak silmeler için, kayıt deletedAt alanı değiştiğinden .deleted, güncelleme tarzı yapıyı izler. Kalıcı silmeler için .destroyed kullanın.
databaseEventTriggerSettings.updatedFields, hangi güncelleme olaylarının fonksiyonu tetikleyeceğini filtreler. event.properties.updatedFields, mevcut olayda hangi alanların gerçekten değiştiğini size bildirir.
Oluşturma olayı örneği:
Güncelleme olayı örneği:
Yalnızca e-posta güncellemelerinde tetikle:
Yok etme olayı örneği:

Bir işlevi bir yapay zekâ aracı veya iş akışı eylemi olarak kullanıma sunma

Mantık işlevleri, her birinin kendi tetikleyicisi olacak şekilde iki yerde kullanılabilir hâle getirilebilir:
  • toolTriggerSettings — işlevi Twenty’nin yapay zekâ özellikleri (sohbet, MCP, işlev çağırma) tarafından bulunabilir hâle getirir. Standart JSON Şeması’nı kullanır; LLM’lerin doğal olarak anladığı biçimdir.
  • workflowActionTriggerSettings — işlevin görsel iş akışı oluşturucusunda bir adım olarak görünmesini sağlar. Oluşturucunun uygun alan düzenleyicilerini, değişken seçicilerini ve etiketleri oluşturabilmesi için Twenty’nin zengin InputSchema’sını kullanır.
Bir işlev bunlardan birini, diğerini veya her ikisini de tercih edebilir. Bunlar, cronTriggerSettings, databaseEventTriggerSettings ve httpRouteTriggerSettings ile birlikte yer alır — aynı desen, aynı biçim.
İş akışındaki Code eylemiyle ilişkisi. İş akışı oluşturucusundaki yerleşik Code eylemi başlı başına bir mantık fonksiyonudur — Twenty, her Code adımı için bir tane oluşturur ve düzenleyicisini satır içi olarak sunar. workflowActionTriggerSettings, bu tek seferlik, satır içi kodu yeniden kullanılabilir bir eyleme dönüştürmenin yoludur: fonksiyonu uygulamanızda bir kez tanımlarsınız ve her Code adımına kopyalanıp yapıştırılmak yerine, herhangi bir iş akışı içinde seçilebilir hale gelir. Son kullanıcı görünümü için kullanıcı rehberindeki Code eylemine bakın.
src/logic-functions/enrich-company.logic-function.ts
Önemli noktalar:
  • Bir işlev yüzeyleri karıştırabilir — onu sohbette VE iş akışı oluşturucusunda kullanıma sunmak için hem toolTriggerSettings hem de workflowActionTriggerSettings bildirin.
  • toolTriggerSettings.inputSchema ve workflowActionTriggerSettings.inputSchema ikisi de isteğe bağlıdır. Atlandığında, manifest oluşturucu bunları işleyici kaynak kodundan çıkarır (yapay zekâ aracı için JSON Şeması, iş akışı eylemi için Twenty’nin InputSchema’sı). Daha zengin tipleme istediğinizde birini açıkça belirtin — örneğin, iş akışı oluşturucu için FieldMetadataType’ı bilen CURRENCY veya RELATION gibi alanlarla ya da yapay zekâ aracısının okuyabileceği description alanlarıyla:
Parametrelerinizi bir kez tanımlayıp her iki yüzeyde de kullanmak için tek bir JSON Şeması (InputJsonSchema) oluşturun ve bunu iş akışı eylemi için twenty-sdk/logic-function içindeki jsonSchemaToInputSchema ile dönüştürün. toolTriggerSettings.inputSchema, JSON Şemasını doğrudan alırken workflowActionTriggerSettings.inputSchema, Twenty’nin InputSchema tipini bekler:
Tam bir iş akışı eylemi örneği
workflowActionTriggerSettings dört alan kabul eder:Tümünü bir araya getirme — bir iş akışı eylemi olarak sunulan bir fonksiyon; daha sonraki adımların taskId değerine referans verebilmesi için tanımlanmış bir çıktıyla birlikte:
src/logic-functions/enrich-company.logic-function.ts
Uygulama kurulduktan sonra, Enrich Company iş akışı oluşturucusunun eylem seçicisinde görünür. Oluşturucu companyName ve domain alanlarını girdi alanları olarak render eder (her biri önceki adımlardan değer çekebilir) ve sonraki adımlar, adımın taskId ve enriched çıktılarına referans verebilir.
İyi bir description yazın. AI ajanları, aracı ne zaman kullanacaklarına karar vermek için işlevin description alanına güvenir. Aracın ne yaptığını ve ne zaman çağrılması gerektiğini açıkça belirtin.
Çalışma zamanı yardımcıları. twenty-sdk/utils, işleyicilerin doğrudan twenty-shared içinden içe aktarma yapmasına gerek kalmaması için küçük çalışma zamanı yardımcılarını yeniden dışa aktarır. Örneğin, isDefined(value) hem null hem de undefined için false döndürür — bunu, çalışma zamanında T | undefined olarak yazılmış olsa bile null olarak gelebilen isteğe bağlı işleyici girdilerini güvenli şekilde daraltmak için kullanın:
Yükleme kancaları — ön yükleme, yükleme sonrası ve kaldırma işleyicileri — bu çalışma zamanını paylaşır ancak kendi tanımlama işlevleriyle bildirilir ve tetikleyici ayarlarını almaz. definePreInstallLogicFunction, definePostInstallLogicFunction ve defineUninstallLogicFunction için Yükleme Kancaları bölümüne bakın.

Tipli API istemcileri (twenty-client-sdk)

twenty-client-sdk paketi, mantık fonksiyonlarınızdan ve ön uç bileşenlerinizden Twenty API ile etkileşim kurmak için tip tanımlı iki GraphQL istemcisi sağlar.
CoreApiClient, çalışma alanı verilerini sorgulamak ve değiştirmek için ana istemcidir. yarn twenty dev veya yarn twenty dev:build sırasında çalışma alanı şemanızdan oluşturulur, bu nedenle nesnelerinize ve alanlarınıza uyacak şekilde tamamen tiplenmiştir.
İstemci bir seçim kümesi sözdizimi kullanır: Bir alanı dahil etmek için true geçin, bağımsız değişkenler için __args kullanın ve ilişkiler için nesneleri iç içe yerleştirin. Çalışma alanı şemanıza göre tam otomatik tamamlama ve tip denetimi elde edersiniz.
CoreApiClient geliştirme/derleme zamanında oluşturulur. Bunu önce yarn twenty dev veya yarn twenty dev:build çalıştırmadan kullanırsanız, bir hata verir. Oluşturma otomatik olarak gerçekleşir — CLI, çalışma alanınızın GraphQL şemasını inceler ve @genql/cli kullanarak tiplenmiş bir istemci üretir.

Tür açıklamaları için CoreSchema’yı kullanma

CoreSchema, çalışma alanı nesnelerinize uyan TypeScript türleri sağlar — bileşen durumunu veya işlev parametrelerini tiplemek için kullanışlıdır:
MetadataApiClient, SDK ile birlikte önceden hazırlanmış olarak gelir (oluşturma gerektirmez). Çalışma alanı yapılandırması, uygulamalar ve dosya yüklemeleri için /metadata uç noktasını sorgular.

Dosya yükleme

MetadataApiClient, dosya türündeki alanlara dosya eklemek için bir uploadFile yöntemi içerir:
Önemli noktalar:
  • Alan için universalIdentifier kullanır (çalışma alanına özgü kimliği değil), böylece yükleme kodunuz uygulamanızın yüklü olduğu herhangi bir çalışma alanında çalışır.
  • Döndürülen url, yüklenen dosyaya erişmek için kullanabileceğiniz imzalı bir URL’dir.
Kodunuz Twenty üzerinde çalıştığında (mantık işlevleri veya ön uç bileşenleri), platform kimlik bilgilerini ortam değişkenleri olarak enjekte eder:
  • TWENTY_API_URL — Twenty API’nin temel URL’si
  • TWENTY_APP_ACCESS_TOKEN — Uygulamanızın varsayılan işlev rolü kapsamında kısa ömürlü bir anahtar
Bunları istemcilere iletmeniz gerekmez — otomatik olarak process.env’den okurlar. API anahtarının izinleri, defineApplicationRole() ile bildirilen role (veya application-config.ts içindeki defaultRoleUniversalIdentifier üzerinden referans verilen role) göre belirlenir.