diff --git a/packages/twenty-docs/l/de/developers/extend/apps/layout/front-components.mdx b/packages/twenty-docs/l/de/developers/extend/apps/layout/front-components.mdx index 02252a230b..a2c836f607 100644 --- a/packages/twenty-docs/l/de/developers/extend/apps/layout/front-components.mdx +++ b/packages/twenty-docs/l/de/developers/extend/apps/layout/front-components.mdx @@ -196,6 +196,94 @@ export default defineFrontComponent({ }); ``` +## Aufrufen einer Logikfunktion + +Front-Komponenten laufen browserseitig in einem isolierten Web Worker, während [Logikfunktionen](/l/de/developers/extend/apps/logic/logic-functions) serverseitig ausgeführt werden. Es gibt keinen direkten In-Process-Aufruf zwischen beiden – stattdessen ruft eine Front-Komponente eine Logikfunktion über HTTP auf. + +Eine mit `httpRouteTriggerSettings` deklarierte Logikfunktion wird unter dem `/s/`-Endpunkt unter `${TWENTY_API_URL}/s\` bereitgestellt. Ihre Front-Komponente ruft diese Route mit `fetch` auf und authentifiziert sich dabei mit dem `TWENTY_APP_ACCESS_TOKEN`, das Twenty in den Worker injiziert. + +Ein kleiner wiederverwendbarer Helper hält die Aufrufstellen übersichtlich: + +```ts src/shared/call-app-route.ts +export async function callAppRoute( + path: string, + body: Record, +): Promise { + const apiUrl = process.env.TWENTY_API_URL ?? ''; + const token = process.env.TWENTY_APP_ACCESS_TOKEN; + + const res = await fetch(`${apiUrl}/s${path}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(token ? { Authorization: `Bearer ${token}` } : {}), + }, + body: JSON.stringify(body), + }); + + if (!res.ok) { + throw new Error(`Logic function failed (${res.status})`); + } + + return res.json(); +} +``` + +Eine headless Front-Komponente kann den Aufruf beim Mounten über die `Command`-Komponente ausführen und sich anschließend automatisch unmounten: + +```tsx src/front-components/sync-prs.tsx +import { defineFrontComponent } from 'twenty-sdk/define'; +import { Command } from 'twenty-sdk/command'; +import { callAppRoute } from 'src/shared/call-app-route'; + +const SyncPrs = () => { + const execute = async () => { + await callAppRoute('/github/fetch-prs', { + owner: 'twentyhq', + repo: 'twenty', + }); + }; + + return ; +}; + +export default defineFrontComponent({ + universalIdentifier: '...', + name: 'sync-prs', + description: 'Triggers the fetch-prs logic function', + isHeadless: true, + component: SyncPrs, +}); +``` + +Der an `callAppRoute` übergebene `path` muss dem `httpRouteTriggerSettings.path` der Logikfunktion entsprechen (das `/s`-Präfix wird vom Helper hinzugefügt): + +```ts src/logic-functions/fetch-prs.logic-function.ts +import { defineLogicFunction } from 'twenty-sdk/define'; +import type { RoutePayload } from 'twenty-sdk/logic-function'; + +const handler = async (event: RoutePayload) => { + const { owner, repo } = (event.body ?? {}) as { owner: string; repo: string }; + // ...fetch from GitHub and persist records... + return { ok: true }; +}; + +export default defineLogicFunction({ + universalIdentifier: '...', + name: 'fetch-prs', + handler, + httpRouteTriggerSettings: { + path: '/github/fetch-prs', + httpMethod: 'POST', + isAuthRequired: true, + }, +}); +``` + + +`TWENTY_API_URL` und `TWENTY_APP_ACCESS_TOKEN` werden automatisch injiziert – siehe [Anwendungsvariablen](#application-variables). Da geheime Anwendungsvariablen niemals in Front-Komponenten offengelegt werden, sollten API-Schlüssel und andere sensible Logik in der Logikfunktion verbleiben und nicht in der Front-Komponente. + + ## Zugriff auf den Laufzeitkontext Verwenden Sie innerhalb Ihrer Komponente SDK-Hooks, um auf den aktuellen Benutzer, den Datensatz und die Komponenteninstanz zuzugreifen: diff --git a/packages/twenty-docs/l/de/developers/extend/apps/logic/logic-functions.mdx b/packages/twenty-docs/l/de/developers/extend/apps/logic/logic-functions.mdx index 0ba0944cfc..1464c196e3 100644 --- a/packages/twenty-docs/l/de/developers/extend/apps/logic/logic-functions.mdx +++ b/packages/twenty-docs/l/de/developers/extend/apps/logic/logic-functions.mdx @@ -53,6 +53,10 @@ export default defineLogicFunction({ Verfügbare Trigger-Typen: * **httpRoute**: Stellt Ihre Funktion unter einem HTTP-Pfad und einer Methode **unter dem Endpunkt `/s/`** bereit: > z. B. `path: '/post-card/create'` ist unter `https://your-twenty-server.com/s/post-card/create` aufrufbar + + +Um eine routenausgelöste Logikfunktion von einer (headless) Front-Komponente aus aufzurufen, siehe [Aufrufen einer Logikfunktion](/l/de/developers/extend/apps/layout/front-components#calling-a-logic-function). + * **cron**: Führt Ihre Funktion nach Zeitplan mithilfe eines CRON-Ausdrucks aus. * **databaseEvent**: Wird bei Lebenszyklusereignissen von Workspace-Objekten ausgeführt. Wenn die Ereignisoperation `updated` ist, können bestimmte zu überwachende Felder im Array `updatedFields` angegeben werden. Wenn das Array undefiniert oder leer ist, löst jede Aktualisierung die Funktion aus. > z. B. `person.updated`, `*.created`, `company.*` diff --git a/packages/twenty-docs/l/pt/developers/extend/apps/layout/front-components.mdx b/packages/twenty-docs/l/pt/developers/extend/apps/layout/front-components.mdx index 7e9a36a263..8935fdac0d 100644 --- a/packages/twenty-docs/l/pt/developers/extend/apps/layout/front-components.mdx +++ b/packages/twenty-docs/l/pt/developers/extend/apps/layout/front-components.mdx @@ -196,6 +196,94 @@ export default defineFrontComponent({ }); ``` +## Chamando uma função lógica + +Os componentes de front são executados no navegador em um Web Worker isolado, enquanto as [funções lógicas](/l/pt/developers/extend/apps/logic/logic-functions) são executadas no servidor. Não há chamada direta no mesmo processo entre os dois — em vez disso, um componente de front acessa uma função lógica via HTTP. + +Uma função lógica declarada com `httpRouteTriggerSettings` é exposta sob o endpoint `/s/` em `${TWENTY_API_URL}/s\`. Seu componente de front chama essa rota com `fetch`, autenticando com o `TWENTY_APP_ACCESS_TOKEN` que Twenty injeta no worker. + +Um pequeno helper reutilizável mantém os locais de chamada limpos: + +```ts src/shared/call-app-route.ts +export async function callAppRoute( + path: string, + body: Record, +): Promise { + const apiUrl = process.env.TWENTY_API_URL ?? ''; + const token = process.env.TWENTY_APP_ACCESS_TOKEN; + + const res = await fetch(`${apiUrl}/s${path}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(token ? { Authorization: `Bearer ${token}` } : {}), + }, + body: JSON.stringify(body), + }); + + if (!res.ok) { + throw new Error(`Logic function failed (${res.status})`); + } + + return res.json(); +} +``` + +Um componente de front headless pode executar a chamada ao montar via o componente `Command` e, em seguida, desmontar automaticamente: + +```tsx src/front-components/sync-prs.tsx +import { defineFrontComponent } from 'twenty-sdk/define'; +import { Command } from 'twenty-sdk/command'; +import { callAppRoute } from 'src/shared/call-app-route'; + +const SyncPrs = () => { + const execute = async () => { + await callAppRoute('/github/fetch-prs', { + owner: 'twentyhq', + repo: 'twenty', + }); + }; + + return ; +}; + +export default defineFrontComponent({ + universalIdentifier: '...', + name: 'sync-prs', + description: 'Triggers the fetch-prs logic function', + isHeadless: true, + component: SyncPrs, +}); +``` + +O `path` passado para `callAppRoute` deve corresponder ao `httpRouteTriggerSettings.path` da função lógica (o prefixo `/s` é adicionado pelo helper): + +```ts src/logic-functions/fetch-prs.logic-function.ts +import { defineLogicFunction } from 'twenty-sdk/define'; +import type { RoutePayload } from 'twenty-sdk/logic-function'; + +const handler = async (event: RoutePayload) => { + const { owner, repo } = (event.body ?? {}) as { owner: string; repo: string }; + // ...fetch from GitHub and persist records... + return { ok: true }; +}; + +export default defineLogicFunction({ + universalIdentifier: '...', + name: 'fetch-prs', + handler, + httpRouteTriggerSettings: { + path: '/github/fetch-prs', + httpMethod: 'POST', + isAuthRequired: true, + }, +}); +``` + + +`TWENTY_API_URL` e `TWENTY_APP_ACCESS_TOKEN` são injetados automaticamente — consulte [Variáveis de aplicação](#application-variables). Como as variáveis de aplicação secretas nunca são expostas aos componentes de front, mantenha as chaves de API e outra lógica sensível na função lógica, não no componente de front. + + ## Acessando o contexto de execução Dentro do seu componente, use hooks do SDK para acessar o usuário atual, o registro e a instância do componente: diff --git a/packages/twenty-docs/l/pt/developers/extend/apps/logic/logic-functions.mdx b/packages/twenty-docs/l/pt/developers/extend/apps/logic/logic-functions.mdx index 4c3b9ea614..4e751072cd 100644 --- a/packages/twenty-docs/l/pt/developers/extend/apps/logic/logic-functions.mdx +++ b/packages/twenty-docs/l/pt/developers/extend/apps/logic/logic-functions.mdx @@ -53,6 +53,10 @@ export default defineLogicFunction({ Tipos de gatilho disponíveis: * **httpRoute**: Expõe sua função em um caminho e método HTTP **no endpoint `/s/`**: > por exemplo, `path: '/post-card/create'` é acessível em `https://your-twenty-server.com/s/post-card/create` + + +Para invocar uma função de lógica acionada por rota a partir de um componente de front-end (headless), consulte [Chamando uma função de lógica](/l/pt/developers/extend/apps/layout/front-components#calling-a-logic-function). + * **cron**: Executa sua função em um agendamento usando uma expressão CRON. * **databaseEvent**: Executa em eventos do ciclo de vida de objetos do espaço de trabalho. Quando a operação do evento é `updated`, campos específicos a serem observados podem ser especificados no array `updatedFields`. Se deixar indefinido ou vazio, qualquer atualização acionará a função. > por exemplo, `person.updated`, `*.created`, `company.*` diff --git a/packages/twenty-docs/l/ro/developers/extend/apps/layout/front-components.mdx b/packages/twenty-docs/l/ro/developers/extend/apps/layout/front-components.mdx index 3d7511deca..f5469ac79d 100644 --- a/packages/twenty-docs/l/ro/developers/extend/apps/layout/front-components.mdx +++ b/packages/twenty-docs/l/ro/developers/extend/apps/layout/front-components.mdx @@ -196,6 +196,94 @@ export default defineFrontComponent({ }); ``` +## Apelarea unei funcții logice + +Componentele de front rulează în browser într-un Web Worker izolat, în timp ce [funcțiile logice](/l/ro/developers/extend/apps/logic/logic-functions) rulează pe server. Nu există un apel direct în același proces între cele două — în schimb, o componentă de front apelează o funcție logică prin HTTP. + +O funcție logică declarată cu `httpRouteTriggerSettings` este expusă sub endpoint-ul `/s/` la `${TWENTY_API_URL}/s\`. Componenta ta de front apelează acea rută cu `fetch`, autentificându-se cu `TWENTY_APP_ACCESS_TOKEN` pe care Twenty îl injectează în worker. + +Un mic utilitar reutilizabil menține locurile de apel curate: + +```ts src/shared/call-app-route.ts +export async function callAppRoute( + path: string, + body: Record, +): Promise { + const apiUrl = process.env.TWENTY_API_URL ?? ''; + const token = process.env.TWENTY_APP_ACCESS_TOKEN; + + const res = await fetch(`${apiUrl}/s${path}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(token ? { Authorization: `Bearer ${token}` } : {}), + }, + body: JSON.stringify(body), + }); + + if (!res.ok) { + throw new Error(`Logic function failed (${res.status})`); + } + + return res.json(); +} +``` + +O componentă de front headless poate efectua apelul la montare prin componenta `Command`, apoi se demontează automat: + +```tsx src/front-components/sync-prs.tsx +import { defineFrontComponent } from 'twenty-sdk/define'; +import { Command } from 'twenty-sdk/command'; +import { callAppRoute } from 'src/shared/call-app-route'; + +const SyncPrs = () => { + const execute = async () => { + await callAppRoute('/github/fetch-prs', { + owner: 'twentyhq', + repo: 'twenty', + }); + }; + + return ; +}; + +export default defineFrontComponent({ + universalIdentifier: '...', + name: 'sync-prs', + description: 'Triggers the fetch-prs logic function', + isHeadless: true, + component: SyncPrs, +}); +``` + +`path` transmis către `callAppRoute` trebuie să corespundă cu `httpRouteTriggerSettings.path` al funcției logice (prefixul `/s` este adăugat de utilitar): + +```ts src/logic-functions/fetch-prs.logic-function.ts +import { defineLogicFunction } from 'twenty-sdk/define'; +import type { RoutePayload } from 'twenty-sdk/logic-function'; + +const handler = async (event: RoutePayload) => { + const { owner, repo } = (event.body ?? {}) as { owner: string; repo: string }; + // ...fetch from GitHub and persist records... + return { ok: true }; +}; + +export default defineLogicFunction({ + universalIdentifier: '...', + name: 'fetch-prs', + handler, + httpRouteTriggerSettings: { + path: '/github/fetch-prs', + httpMethod: 'POST', + isAuthRequired: true, + }, +}); +``` + + +`TWENTY_API_URL` și `TWENTY_APP_ACCESS_TOKEN` sunt injectate automat — vezi [Application variables](#application-variables). Deoarece variabilele de aplicație secrete nu sunt niciodată expuse componentelor de front, păstrează cheile API și altă logică sensibilă în funcția logică, nu în componenta de front. + + ## Accesarea contextului de rulare În interiorul componentei, folosiți hook-urile SDK pentru a accesa utilizatorul curent, înregistrarea curentă și instanța componentei: diff --git a/packages/twenty-docs/l/ro/developers/extend/apps/logic/logic-functions.mdx b/packages/twenty-docs/l/ro/developers/extend/apps/logic/logic-functions.mdx index 04dc96068e..2252ed3ea3 100644 --- a/packages/twenty-docs/l/ro/developers/extend/apps/logic/logic-functions.mdx +++ b/packages/twenty-docs/l/ro/developers/extend/apps/logic/logic-functions.mdx @@ -53,6 +53,10 @@ export default defineLogicFunction({ Tipuri de declanșatoare disponibile: * **httpRoute**: Expune funcția pe o cale și metodă HTTP **sub endpoint-ul `/s/`**: > de ex. `path: '/post-card/create'` este apelabil la `https://your-twenty-server.com/s/post-card/create` + + +Pentru a apela o funcție logică declanșată de o rută dintr-o componentă front-end (headless), consultă [Apelarea unei funcții logice](/l/ro/developers/extend/apps/layout/front-components#calling-a-logic-function). + * **cron**: Rulează funcția pe un program folosind o expresie CRON. * **databaseEvent**: Rulează la evenimentele ciclului de viață ale obiectelor din spațiul de lucru. Când operațiunea evenimentului este `updated`, câmpurile specifice de urmărit pot fi specificate în array-ul `updatedFields`. Dacă este lăsat nedefinit sau gol, orice actualizare va declanșa funcția. > de ex. `person.updated`, `*.created`, `company.*` diff --git a/packages/twenty-docs/l/ru/developers/extend/apps/layout/front-components.mdx b/packages/twenty-docs/l/ru/developers/extend/apps/layout/front-components.mdx index 0c6c2fbcda..a69c06abce 100644 --- a/packages/twenty-docs/l/ru/developers/extend/apps/layout/front-components.mdx +++ b/packages/twenty-docs/l/ru/developers/extend/apps/layout/front-components.mdx @@ -196,6 +196,94 @@ export default defineFrontComponent({ }); ``` +## Вызов логической функции + +Front-компоненты выполняются в браузере в изолированном Web Worker, в то время как [логические функции](/l/ru/developers/extend/apps/logic/logic-functions) выполняются на стороне сервера. Между ними нет прямого внутрипроцессного вызова — вместо этого front-компонент обращается к логической функции по HTTP. + +Логическая функция, объявленная с `httpRouteTriggerSettings`, доступна по эндпоинту `/s/` по адресу `${TWENTY_API_URL}/s\`. Ваш front-компонент вызывает этот маршрут с помощью `fetch`, аутентифицируясь с использованием `TWENTY_APP_ACCESS_TOKEN`, который Twenty внедряет в worker. + +Небольшой переиспользуемый хелпер делает места вызова чище: + +```ts src/shared/call-app-route.ts +export async function callAppRoute( + path: string, + body: Record, +): Promise { + const apiUrl = process.env.TWENTY_API_URL ?? ''; + const token = process.env.TWENTY_APP_ACCESS_TOKEN; + + const res = await fetch(`${apiUrl}/s${path}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(token ? { Authorization: `Bearer ${token}` } : {}), + }, + body: JSON.stringify(body), + }); + + if (!res.ok) { + throw new Error(`Logic function failed (${res.status})`); + } + + return res.json(); +} +``` + +Безголовый front-компонент может выполнить вызов при монтировании через компонент `Command`, а затем автоматически размонтироваться: + +```tsx src/front-components/sync-prs.tsx +import { defineFrontComponent } from 'twenty-sdk/define'; +import { Command } from 'twenty-sdk/command'; +import { callAppRoute } from 'src/shared/call-app-route'; + +const SyncPrs = () => { + const execute = async () => { + await callAppRoute('/github/fetch-prs', { + owner: 'twentyhq', + repo: 'twenty', + }); + }; + + return ; +}; + +export default defineFrontComponent({ + universalIdentifier: '...', + name: 'sync-prs', + description: 'Triggers the fetch-prs logic function', + isHeadless: true, + component: SyncPrs, +}); +``` + +`path`, переданный в `callAppRoute`, должен совпадать с `httpRouteTriggerSettings.path` логической функции (префикс `/s` добавляется хелпером): + +```ts src/logic-functions/fetch-prs.logic-function.ts +import { defineLogicFunction } from 'twenty-sdk/define'; +import type { RoutePayload } from 'twenty-sdk/logic-function'; + +const handler = async (event: RoutePayload) => { + const { owner, repo } = (event.body ?? {}) as { owner: string; repo: string }; + // ...fetch from GitHub and persist records... + return { ok: true }; +}; + +export default defineLogicFunction({ + universalIdentifier: '...', + name: 'fetch-prs', + handler, + httpRouteTriggerSettings: { + path: '/github/fetch-prs', + httpMethod: 'POST', + isAuthRequired: true, + }, +}); +``` + + +`TWENTY_API_URL` и `TWENTY_APP_ACCESS_TOKEN` внедряются автоматически — см. [переменные приложения](#application-variables). Поскольку секретные переменные приложения никогда не раскрываются front-компонентам, храните ключи API и другую конфиденциальную логику в логической функции, а не во front-компоненте. + + ## Доступ к контексту времени выполнения Внутри вашего компонента используйте хуки SDK для доступа к текущему пользователю, записи и экземпляру компонента: diff --git a/packages/twenty-docs/l/ru/developers/extend/apps/logic/logic-functions.mdx b/packages/twenty-docs/l/ru/developers/extend/apps/logic/logic-functions.mdx index 2eade8f24e..2712d17108 100644 --- a/packages/twenty-docs/l/ru/developers/extend/apps/logic/logic-functions.mdx +++ b/packages/twenty-docs/l/ru/developers/extend/apps/logic/logic-functions.mdx @@ -53,6 +53,10 @@ export default defineLogicFunction({ Доступные типы триггеров: * **httpRoute**: Публикует вашу функцию по HTTP-пути и методу **под конечной точкой `/s/`**: > например, `path: '/post-card/create'` вызывается по адресу `https://your-twenty-server.com/s/post-card/create` + + +Чтобы вызвать логическую функцию, запускаемую маршрутом, из фронтенд-компонента (без интерфейса), см. раздел [Вызов логической функции](/l/ru/developers/extend/apps/layout/front-components#calling-a-logic-function). + * **cron**: Запускает вашу функцию по расписанию с использованием выражения CRON. * **databaseEvent**: Запускается при событиях жизненного цикла объектов рабочего пространства. Когда операция события — `updated`, можно указать конкретные поля для отслеживания в массиве `updatedFields`. Если оставить не заданным или пустым, любое обновление будет вызывать функцию. > например, `person.updated`, `*.created`, `company.*` diff --git a/packages/twenty-docs/l/tr/developers/extend/apps/layout/front-components.mdx b/packages/twenty-docs/l/tr/developers/extend/apps/layout/front-components.mdx index b856a57fee..d27aad1868 100644 --- a/packages/twenty-docs/l/tr/developers/extend/apps/layout/front-components.mdx +++ b/packages/twenty-docs/l/tr/developers/extend/apps/layout/front-components.mdx @@ -196,6 +196,94 @@ export default defineFrontComponent({ }); ``` +## Bir mantık işlevini çağırma + +Ön bileşenler, tarayıcı tarafında izole bir Web Worker içinde çalışırken, [mantık işlevleri](/l/tr/developers/extend/apps/logic/logic-functions) sunucu tarafında çalışır. İkisi arasında doğrudan, işlem içi bir çağrı yoktur — bunun yerine, bir ön bileşen bir mantık işlevine HTTP üzerinden erişir. + +`httpRouteTriggerSettings` ile bildirilen bir mantık işlevi, `${TWENTY_API_URL}/s\` altındaki `/s/` uç noktasında sunulur. Ön bileşeniniz bu rotayı, Twenty tarafından Worker'a enjekte edilen `TWENTY_APP_ACCESS_TOKEN` ile kimlik doğrulayarak `fetch` ile çağırır. + +Küçük, yeniden kullanılabilir bir yardımcı işlev çağrı noktalarını sade tutar: + +```ts src/shared/call-app-route.ts +export async function callAppRoute( + path: string, + body: Record, +): Promise { + const apiUrl = process.env.TWENTY_API_URL ?? ''; + const token = process.env.TWENTY_APP_ACCESS_TOKEN; + + const res = await fetch(`${apiUrl}/s${path}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(token ? { Authorization: `Bearer ${token}` } : {}), + }, + body: JSON.stringify(body), + }); + + if (!res.ok) { + throw new Error(`Logic function failed (${res.status})`); + } + + return res.json(); +} +``` + +Başsız bir ön bileşen, çağrıyı `Command` bileşeni aracılığıyla mount sırasında çalıştırabilir ve ardından otomatik olarak unmount olabilir: + +```tsx src/front-components/sync-prs.tsx +import { defineFrontComponent } from 'twenty-sdk/define'; +import { Command } from 'twenty-sdk/command'; +import { callAppRoute } from 'src/shared/call-app-route'; + +const SyncPrs = () => { + const execute = async () => { + await callAppRoute('/github/fetch-prs', { + owner: 'twentyhq', + repo: 'twenty', + }); + }; + + return ; +}; + +export default defineFrontComponent({ + universalIdentifier: '...', + name: 'sync-prs', + description: 'Triggers the fetch-prs logic function', + isHeadless: true, + component: SyncPrs, +}); +``` + +`callAppRoute` fonksiyonuna geçirilen `path`, mantık işlevinin `httpRouteTriggerSettings.path` değeriyle eşleşmelidir (`/s` öneki yardımcı işlev tarafından eklenir): + +```ts src/logic-functions/fetch-prs.logic-function.ts +import { defineLogicFunction } from 'twenty-sdk/define'; +import type { RoutePayload } from 'twenty-sdk/logic-function'; + +const handler = async (event: RoutePayload) => { + const { owner, repo } = (event.body ?? {}) as { owner: string; repo: string }; + // ...fetch from GitHub and persist records... + return { ok: true }; +}; + +export default defineLogicFunction({ + universalIdentifier: '...', + name: 'fetch-prs', + handler, + httpRouteTriggerSettings: { + path: '/github/fetch-prs', + httpMethod: 'POST', + isAuthRequired: true, + }, +}); +``` + + +`TWENTY_API_URL` ve `TWENTY_APP_ACCESS_TOKEN` otomatik olarak enjekte edilir — bkz. [Uygulama değişkenleri](#application-variables). Gizli uygulama değişkenleri asla ön bileşenlere açığa çıkarılmadığından, API anahtarlarını ve diğer hassas mantığı ön bileşende değil, mantık işlevinin içinde tutun. + + ## Çalışma zamanı bağlamına erişme Bileşeninizin içinde, geçerli kullanıcıya, kayda ve bileşen örneğine erişmek için SDK hook'larını kullanın: diff --git a/packages/twenty-docs/l/tr/developers/extend/apps/logic/logic-functions.mdx b/packages/twenty-docs/l/tr/developers/extend/apps/logic/logic-functions.mdx index c7d166712b..c790d60324 100644 --- a/packages/twenty-docs/l/tr/developers/extend/apps/logic/logic-functions.mdx +++ b/packages/twenty-docs/l/tr/developers/extend/apps/logic/logic-functions.mdx @@ -53,6 +53,10 @@ export default defineLogicFunction({ Kullanılabilir tetikleyici türleri: * **httpRoute**: İşlevinizi bir HTTP yolu ve yöntemiyle **`/s/` uç noktasının altında** kullanıma sunar: > örn. `path: '/post-card/create'` `https://your-twenty-server.com/s/post-card/create` adresinden çağrılabilir + + +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](/l/tr/developers/extend/apps/layout/front-components#calling-a-logic-function). + * **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.*` diff --git a/packages/twenty-docs/l/zh/developers/extend/apps/layout/front-components.mdx b/packages/twenty-docs/l/zh/developers/extend/apps/layout/front-components.mdx index 01c87824ad..6aed8e2c52 100644 --- a/packages/twenty-docs/l/zh/developers/extend/apps/layout/front-components.mdx +++ b/packages/twenty-docs/l/zh/developers/extend/apps/layout/front-components.mdx @@ -196,6 +196,94 @@ export default defineFrontComponent({ }); ``` +## 调用逻辑函数 + +前端组件在沙盒 Web Worker 中于浏览器端运行,而[逻辑函数](/l/zh/developers/extend/apps/logic/logic-functions)在服务器端运行。 二者之间没有直接的进程内调用——前端组件通过 HTTP 访问逻辑函数。 + +使用 `httpRouteTriggerSettings` 声明的逻辑函数会通过 `/s/` 端点暴露在 `${TWENTY_API_URL}/s\` 下。 你的前端组件使用 `fetch` 调用该路由,并使用 Twenty 注入到 worker 中的 `TWENTY_APP_ACCESS_TOKEN` 进行身份验证。 + +一个小型可复用的辅助函数可以让调用端保持简洁: + +```ts src/shared/call-app-route.ts +export async function callAppRoute( + path: string, + body: Record, +): Promise { + const apiUrl = process.env.TWENTY_API_URL ?? ''; + const token = process.env.TWENTY_APP_ACCESS_TOKEN; + + const res = await fetch(`${apiUrl}/s${path}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(token ? { Authorization: `Bearer ${token}` } : {}), + }, + body: JSON.stringify(body), + }); + + if (!res.ok) { + throw new Error(`Logic function failed (${res.status})`); + } + + return res.json(); +} +``` + +无头前端组件可以通过 `Command` 组件在挂载时执行调用,然后自动卸载: + +```tsx src/front-components/sync-prs.tsx +import { defineFrontComponent } from 'twenty-sdk/define'; +import { Command } from 'twenty-sdk/command'; +import { callAppRoute } from 'src/shared/call-app-route'; + +const SyncPrs = () => { + const execute = async () => { + await callAppRoute('/github/fetch-prs', { + owner: 'twentyhq', + repo: 'twenty', + }); + }; + + return ; +}; + +export default defineFrontComponent({ + universalIdentifier: '...', + name: 'sync-prs', + description: 'Triggers the fetch-prs logic function', + isHeadless: true, + component: SyncPrs, +}); +``` + +传递给 `callAppRoute` 的 `path` 必须与逻辑函数的 `httpRouteTriggerSettings.path` 匹配(`/s` 前缀由辅助函数添加): + +```ts src/logic-functions/fetch-prs.logic-function.ts +import { defineLogicFunction } from 'twenty-sdk/define'; +import type { RoutePayload } from 'twenty-sdk/logic-function'; + +const handler = async (event: RoutePayload) => { + const { owner, repo } = (event.body ?? {}) as { owner: string; repo: string }; + // ...fetch from GitHub and persist records... + return { ok: true }; +}; + +export default defineLogicFunction({ + universalIdentifier: '...', + name: 'fetch-prs', + handler, + httpRouteTriggerSettings: { + path: '/github/fetch-prs', + httpMethod: 'POST', + isAuthRequired: true, + }, +}); +``` + + +`TWENTY_API_URL` 和 `TWENTY_APP_ACCESS_TOKEN` 会被自动注入——参见 [应用变量](#application-variables)。 由于机密应用变量永远不会暴露给前端组件,请将 API 密钥和其他敏感逻辑保留在逻辑函数中,而不是前端组件中。 + + ## 访问运行时上下文 在组件内部,使用 SDK 的 hooks 获取当前用户、记录和组件实例: diff --git a/packages/twenty-docs/l/zh/developers/extend/apps/logic/logic-functions.mdx b/packages/twenty-docs/l/zh/developers/extend/apps/logic/logic-functions.mdx index 5d4b4255ed..af524c96ab 100644 --- a/packages/twenty-docs/l/zh/developers/extend/apps/logic/logic-functions.mdx +++ b/packages/twenty-docs/l/zh/developers/extend/apps/logic/logic-functions.mdx @@ -53,6 +53,10 @@ export default defineLogicFunction({ 可用的触发器类型: * **httpRoute**:在 **`/s/` 端点**下通过 HTTP 路径和方法公开你的函数: > 例如 `path: '/post-card/create'` 可在 `https://your-twenty-server.com/s/post-card/create` 调用 + + +要从(无头)前端组件调用由路由触发的逻辑函数,请参见[调用逻辑函数](/l/zh/developers/extend/apps/layout/front-components#calling-a-logic-function)。 + * **cron**:使用 CRON 表达式按计划运行你的函数。 * **databaseEvent**:在工作区对象生命周期事件上运行。 当事件操作为 `updated` 时,可以在 `updatedFields` 数组中指定要监听的特定字段。 如果未定义或为空,任何更新都会触发该函数。 > 例如 `person.updated`、`*.created`、`company.*`