i18n - docs translations (#23244)
Created by Github action <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/23244?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
committed by
GitHub
parent
7f1e3d3541
commit
d1b556f4a8
@@ -59,7 +59,7 @@ Pour appeler une fonction logique déclenchée par une route depuis un composant
|
||||
* **cron** : Exécute votre fonction selon une planification à l’aide d’une expression CRON.
|
||||
* **databaseEvent**: S'exécute lors des événements du cycle de vie des objets de l'espace de travail. Lorsque l'opération de l'événement est `updated`, des champs spécifiques à surveiller peuvent être spécifiés dans le tableau `updatedFields`. S'il est laissé indéfini ou vide, toute mise à jour déclenchera la fonction.
|
||||
> p. ex. `person.updated`, `*.created`, `company.*`
|
||||
* **serverRoute** : expose une seule route HTTP à portée d’enregistrement. Une fonction de **résolution** (déclarée avec `serverRouteTriggerSettings`) s’exécute dans l’espace de travail propriétaire et renvoie l’espace de travail cible ET la fonction logique cible vers laquelle acheminer la requête ; la plateforme accuse réception avec `202` et exécute cette fonction **cible** dans la file d’attente du worker. Voir [déclencheur de route serveur](#server-route-trigger).
|
||||
* **serverRoute** : expose une seule route HTTP à portée d’enregistrement. Une fonction de **résolution** (déclarée avec `serverRouteTriggerSettings`) s’exécute dans l’espace de travail propriétaire et renvoie soit une `Response` synchrone, soit l’espace de travail cible ET la fonction logique cible à mettre en file d’attente ; dans le cas de la mise en file d’attente, la plateforme accuse réception avec `202` et exécute cette **cible** dans la file d’attente du worker. Voir [déclencheur de route serveur](#server-route-trigger).
|
||||
|
||||
<Note>
|
||||
Vous pouvez également exécuter manuellement une fonction à l'aide de la CLI :
|
||||
@@ -178,13 +178,18 @@ Le code d’état doit être un code d’état HTTP valide (compris entre 100 et
|
||||
|
||||
Le déclencheur comporte deux parties :
|
||||
|
||||
1. Une fonction de logique de **résolution** — déclarée avec `serverRouteTriggerSettings` — s’exécute dans votre **espace de travail propriétaire** (l’espace de travail qui possède l’enregistrement de l’application). Elle inspecte la requête entrante et retourne `{ workspaceId, targetLogicFunctionUniversalIdentifier, payload? }`, en choisissant *à la fois* l’espace de travail cible et la fonction cible. Le résolveur est le point d’autorisation unique — l’URL transporte uniquement l’identifiant du résolveur. **C’est l’endroit privilégié pour vérifier les signatures des requêtes** : le résolveur s’exécute avant tout effet de bord, a accès au `rawBody` original et aux en-têtes transmis, et peut rejeter la requête sans jamais toucher la cible.
|
||||
2. Une fonction de logique **cible** — une fonction de logique classique par espace de travail — s’exécute ensuite dans l’espace de travail résolu avec la charge utile renvoyée par le résolveur (ou la charge utile originale de la requête si le résolveur ne l’a pas transformée). Sa valeur de retour devient la réponse HTTP.
|
||||
1. Une fonction de logique de **résolution** — déclarée avec `serverRouteTriggerSettings` — s’exécute dans votre **espace de travail propriétaire** (l’espace de travail qui possède l’enregistrement de l’application). Elle inspecte la requête entrante et renvoie soit :
|
||||
|
||||
* `{ workspaceId, targetLogicFunctionUniversalIdentifier, payload? }` — la plateforme met cette cible en file d’attente dans l’espace de travail résolu et accuse réception avec `202 { queued: true }`, ou
|
||||
* une `Response` de `twenty-sdk/logic-function` — la plateforme renvoie cette réponse HTTP **de manière synchrone** et ne met **pas** de cible en file d’attente (utilisez ceci pour les échanges de vérification, comme la `url_verification` de Slack).
|
||||
|
||||
Le résolveur est le point d’autorisation unique — l’URL transporte uniquement l’identifiant du résolveur. **C’est l’endroit privilégié pour vérifier les signatures des requêtes** : le résolveur s’exécute avant tout effet de bord, a accès au `rawBody` original et aux en-têtes transmis, et peut rejeter la requête sans jamais toucher la cible.
|
||||
2. Une fonction de logique **cible** — une fonction de logique classique par espace de travail — s’exécute ensuite dans l’espace de travail résolu avec la charge utile renvoyée par le résolveur (ou la charge utile originale de la requête si le résolveur ne l’a pas transformée). Sa valeur de retour **n’est pas** observée par l’appelant HTTP lorsque le résolveur a choisi le chemin de mise en file d’attente.
|
||||
|
||||
```ts src/logic-functions/resolve-server-route.logic-function.ts
|
||||
import { createHmac, timingSafeEqual } from 'crypto';
|
||||
import { defineLogicFunction } from 'twenty-sdk/define';
|
||||
import type { RoutePayload } from 'twenty-sdk/logic-function';
|
||||
import { Response, type RoutePayload } from 'twenty-sdk/logic-function';
|
||||
|
||||
// Runs in the owner workspace. Verifies the request signature, picks
|
||||
// which target function should handle the event, and returns the
|
||||
@@ -211,12 +216,25 @@ const handler = async (event: RoutePayload) => {
|
||||
}
|
||||
|
||||
const body = (event.body ?? {}) as {
|
||||
challenge?: string;
|
||||
metadata?: { twentyWorkspaceId?: string };
|
||||
type?: string;
|
||||
};
|
||||
|
||||
// Handshakes must be answered on this same response, so reply from the
|
||||
// resolver instead of returning a dispatch target.
|
||||
if (body.type === 'url_verification') {
|
||||
return new Response({ challenge: body.challenge });
|
||||
}
|
||||
|
||||
const workspaceId = body.metadata?.twentyWorkspaceId;
|
||||
|
||||
if (!workspaceId) {
|
||||
throw new Error('event is not linked to a workspace');
|
||||
}
|
||||
|
||||
return {
|
||||
workspaceId: body.metadata?.twentyWorkspaceId ?? '',
|
||||
workspaceId,
|
||||
// Route different event types to different target functions.
|
||||
targetLogicFunctionUniversalIdentifier:
|
||||
body.type === 'invoice.paid'
|
||||
@@ -265,7 +283,7 @@ L’identifiant est le `universalIdentifier` du résolveur issu de votre manifes
|
||||
**L’application doit être revendiquée et installée sur son espace de travail propriétaire.** Comme le résolveur s’exécute dans l’**espace de travail propriétaire** (l’espace de travail qui détient l’enregistrement de l’application), un déclencheur de route serveur ne fonctionne que lorsque l’application a été *revendiquée* — c’est‑à‑dire qu’elle possède un espace de travail propriétaire — **et** que cette application est **installée sur l’espace de travail propriétaire**. Tant que ces deux conditions ne sont pas remplies, le résolveur n’a nulle part où s’exécuter, donc la route ne peut pas être envoyée. Une application qui expose une fonction logique `serverRouteTriggerSettings` ne peut donc pas être répertoriée sur la place de marché tant qu’elle n’a pas été revendiquée et installée sur son espace de travail propriétaire.
|
||||
</Note>
|
||||
|
||||
**Contrat du résolveur.** Le type `LogicFunctionConfig` du SDK impose cela à la compilation : dès que vous définissez `serverRouteTriggerSettings`, votre gestionnaire est contraint de retourner `{ workspaceId: string; targetLogicFunctionUniversalIdentifier: string; payload?: object }` (ou une `Promise` de cette valeur). Le `workspaceId` doit être celui d’un espace de travail où la fonction cible est installée, sinon la requête est rejetée avec un `404`.
|
||||
**Contrat du résolveur.** Le type `LogicFunctionConfig` du SDK impose cela à la compilation : dès que vous définissez `serverRouteTriggerSettings`, votre gestionnaire est contraint de retourner soit un `Response`, soit `{ workspaceId: string; targetLogicFunctionUniversalIdentifier: string; payload?: object }` (ou une `Promise` de l’un ou l’autre). Sur le chemin de dispatch, le `workspaceId` doit être celui d’un espace de travail où la fonction cible est installée, sinon la requête est rejetée avec un `404`. Un résultat qui ne correspond à aucune de ces formes — y compris un résultat dont les identifiants ne sont pas des UUID — est rejeté avec un `502`.
|
||||
|
||||
| Champ | Type | Notes |
|
||||
| ---------------------------------------- | --------------------- | -------------------------------------------------------------------------------------- |
|
||||
@@ -290,7 +308,9 @@ Pour les signatures de requêtes, la plupart des fournisseurs signent avec HMAC-
|
||||
L’exemple de résolveur ci-dessus montre déjà le flux GitHub HMAC-SHA256 — adaptez le nom de l’en-tête, l’encodage de l’empreinte et la chaîne de la charge utile signée en fonction du fournisseur avec lequel vous vous intégrez.
|
||||
|
||||
<Note>
|
||||
La route répond `202 { queued: true }` juste après le retour du résolveur et la cible s’exécute dans la file d’attente du worker — l’appelant n’observe jamais la latence, le résultat ou les échecs de la cible (ceux-ci sont enregistrés dans les journaux d’exécution). Cela évite que les nouvelles tentatives d’envoi de l’émetteur n’amplifient les ralentissements de traitement, ce qui est souhaitable pour l’ingestion de webhook. Pour les endpoints dont l’appelant doit lire le corps de la réponse (handshakes de vérification, commandes Slack), utilisez plutôt une route `httpRouteTriggerSettings`. Gardez le résolveur rapide — certains fournisseurs (par ex. Slack) ont un délai d’attente de seulement quelques secondes. Comme le résolveur est accessible en tant que point de terminaison public, protégez-le avec une limitation de débit à votre périphérie.
|
||||
Lorsque le résolveur retourne un objet de dispatch, la route répond `202 { queued: true }` et la cible s’exécute dans la file d’attente du worker — l’appelant n’observe jamais la latence, le résultat ou les échecs de la cible (ceux-ci sont enregistrés dans les journaux d’exécution). Cela évite que les nouvelles tentatives d’envoi de l’émetteur n’amplifient les ralentissements de traitement, ce qui est souhaitable pour l’ingestion de webhook.
|
||||
|
||||
Lorsque l’appelant doit lire le corps de la réponse sur la même requête (handshakes de challenge, accusés de réception interactifs), retournez plutôt un `Response` depuis le **résolveur**. La plateforme le renvoie en écho de manière synchrone et ignore la file d’attente ; ses en-têtes passent par la même liste d’autorisation que les réponses de routes HTTP. Gardez le résolveur rapide — certains fournisseurs (par ex. Slack) ont un délai d’attente de seulement quelques secondes. Comme le résolveur est accessible en tant que point de terminaison public, protégez-le avec une limitation de débit à votre périphérie.
|
||||
</Note>
|
||||
|
||||
#### Charge utile du déclencheur d'événement de base de données
|
||||
|
||||
Reference in New Issue
Block a user