defineLogicFunction
Определяйте логические функции и их триггеры
defineLogicFunction
Определяйте логические функции и их триггеры
Каждый файл функции использует Доступные типы триггеров:Тип В обработчике обращайтесь к переданным заголовкам следующим образом:По соображениям безопасности заголовки ответа ограничены списком разрешенных заголовков. Любой заголовок, которого нет в этом списке (например, Конечная точка доступна по адресу:Идентификатор — это Контракт резолвера. Тип Полезная нагрузка включает:Пример события создания:Пример события обновления:Триггер только при обновлении email:Пример события уничтожения:Основные моменты:Чтобы объявить параметры один раз и использовать их в обоих сценариях, определите одну JSON Schema (После установки приложения Enrich Company появляется в селекторе действий конструктора рабочих процессов. Конструктор отображает
defineLogicFunction() для экспорта конфигурации с обработчиком и необязательными триггерами.src/logic-functions/createPostCard.logic-function.ts
- httpRoute: Публикует вашу функцию по HTTP-пути и методу под конечной точкой
/s/:
например,path: '/post-card/create'вызывается по адресуhttps://your-twenty-server.com/s/post-card/create
Чтобы вызвать логическую функцию, запускаемую маршрутом, из фронтенд-компонента (без интерфейса), см. раздел Вызов логической функции.
- cron: Запускает вашу функцию по расписанию с использованием выражения CRON.
- databaseEvent: Запускается при событиях жизненного цикла объектов рабочего пространства. Когда операция события —
updated, можно указать конкретные поля для отслеживания в массивеupdatedFields. Если оставить не заданным или пустым, любое обновление будет вызывать функцию.
например,person.updated,*.created,company.*
- serverRoute: открывает один HTTP-маршрут в области регистрации. Функция-резолвер (объявленная с помощью
serverRouteTriggerSettings) выполняется в рабочем пространстве-владельце и возвращает целевое рабочее пространство И целевую логическую функцию для маршрутизации; платформа затем запускает эту целевую функцию и возвращает ее ответ. См. триггер серверного маршрута.
Вы также можете вручную выполнить функцию с помощью CLI:Вы можете просматривать логи с помощью:
Полезная нагрузка триггера маршрута
Когда триггер маршрута вызывает вашу логическую функцию, она получает объектRoutePayload, который соответствует формату AWS HTTP API v2.
Импортируйте тип RoutePayload из twenty-sdk/logic-function:RoutePayload имеет следующую структуру:forwardedRequestHeaders
По умолчанию HTTP-заголовки из входящих запросов не передаются в вашу логическую функцию по соображениям безопасности. Чтобы получить доступ к определённым заголовкам, перечислите их в массивеforwardedRequestHeaders:Имена заголовков приводятся к нижнему регистру. Обращайтесь к ним, используя ключи в нижнем регистре (например,
event.headers['content-type']).Пользовательский HTTP-ответ
По умолчанию возврат простого значения из обработчика отправляет его обратно как ответ200 (JSON для объектов, text/plain для строк). Чтобы управлять статус-кодом и заголовками ответа, верните Response из twenty-sdk/logic-function:Set-Cookie, CORS-заголовки, такие как Access-Control-Allow-Origin, или пользовательские заголовки X-*), молчаливо удаляется перед отправкой ответа. Разрешенные заголовки ответа:content-typecontent-languagecontent-dispositioncache-controlretry-after
Код состояния должен быть допустимым кодом состояния HTTP (в диапазоне от 100 до 599). Имена заголовков ответа сравниваются без учета регистра.
Триггер серверного маршрута
httpRouteTriggerSettings предоставляет функцию по пути /s/ и определяет рабочее пространство из хоста запроса — это работает, когда у каждого рабочего пространства свой домен. Поставщики сторонних сервисов, однако, отправляют события всех арендаторов на один URL. В этом случае используйте serverRouteTriggerSettings.Триггер состоит из двух частей:- Логическая функция-резолвер — объявляется с помощью
serverRouteTriggerSettings— выполняется в вашем рабочем пространстве-владельце (рабочем пространстве, которому принадлежит регистрация приложения). Она анализирует входящий запрос и возвращает{ workspaceId, targetLogicFunctionUniversalIdentifier, payload? }, выбирая и целевое рабочее пространство, и целевую функцию. Резолвер является единой точкой авторизации — URL содержит только идентификатор резолвера. Это предпочтительное место для проверки подписей запросов: резолвер выполняется до любых побочных эффектов, имеет доступ к исходнымrawBodyи переадресованным заголовкам и может отклонить запрос, не обращаясь к целевой функции. - Целевая логическая функция — обычная логическая функция на рабочее пространство — затем выполняется в определенном рабочем пространстве с полезной нагрузкой, возвращенной резолвером (или с исходной полезной нагрузкой запроса, если резолвер ее не преобразовал). Ее возвращаемое значение становится HTTP-ответом.
src/logic-functions/resolve-server-route.logic-function.ts
src/logic-functions/handle-invoice-paid.logic-function.ts
universalIdentifier резолвера из вашего манифеста. Зарегистрируйте этот URL у поставщика.Приложение должно быть закреплено и установлено в рабочем пространстве владельца. Поскольку резолвер выполняется в рабочем пространстве владельца (рабочем пространстве, которому принадлежит регистрация приложения), триггер серверного маршрута будет работать только после того, как приложение будет закреплено — то есть у него появится рабочее пространство владельца — и это приложение будет установлено в рабочем пространстве владельца. Пока оба этих условия не выполнены, резолверу негде выполняться, поэтому маршрут не может быть отправлен на обработку. Приложение, которое предоставляет логическую функцию
serverRouteTriggerSettings, соответственно, не может быть размещено в маркетплейсе, пока оно не будет закреплено и установлено в рабочем пространстве владельца.LogicFunctionConfig в SDK обеспечивает это на этапе компиляции: как только вы задаете serverRouteTriggerSettings, ваш обработчик обязан возвращать { workspaceId: string; targetLogicFunctionUniversalIdentifier: string; payload?: object } (или Promise этого объекта). workspaceId должен указывать на рабочее пространство, в котором установлена целевая функция, иначе запрос будет отклонен с кодом 404.Для подписей запросов большинство провайдеров используют HMAC-SHA256; различаются имя заголовка, кодировка дайджеста и строка подписываемой полезной нагрузки. Несколько примеров:
Приведенный выше пример резолвера уже показывает поток GitHub HMAC-SHA256 — адаптируйте имя заголовка, кодировку дайджеста и строку подписываемой полезной нагрузки в соответствии с провайдером, с которым вы интегрируетесь.
Целевая функция выполняется синхронно, и ее возвращаемое значение становится HTTP-ответом, поэтому вызывающая сторона видит ваш статус-код и может повторить запрос при не-2xx коде. Делайте оба обработчика быстрыми — некоторые провайдеры (например, Slack) прерывают запрос через несколько секунд. Поскольку резолвер доступен как публичная конечная точка, защитите его с помощью ограничения частоты запросов (rate limiting) на вашем периметре (edge).
Полезная нагрузка триггера события базы данных
Когда триггер события базы данных вызывает вашу функцию логики, она получает по одномуDatabaseEventPayload на каждую изменённую запись. Полезная нагрузка объединяет метаданные о рабочем пространстве-источнике и объекте с событием на уровне записи.При логическом удалении
.deleted имеет формат обновления, поскольку изменяется поле deletedAt записи.
Для окончательного удаления используйте .destroyed.databaseEventTriggerSettings.updatedFields фильтрует, какие события обновления запускают функцию.
event.properties.updatedFields указывает, какие поля фактически изменились в текущем событии.Предоставление функции в качестве инструмента ИИ или действия рабочего процесса
Функции логики могут быть представлены в двух интерфейсах, у каждого — свой триггер:toolTriggerSettings— делает функцию обнаруживаемой для возможностей ИИ Twenty (чат, MCP, вызов функций). Использует стандартную JSON Schema — формат, который модели LLM изначально понимают.workflowActionTriggerSettings— делает функцию доступной как шаг в визуальном конструкторе рабочих процессов. Использует расширеннуюInputSchemaот Twenty, чтобы конструктор мог отрисовывать корректные редакторы полей, селекторы переменных и подписи.
cronTriggerSettings, databaseEventTriggerSettings и httpRouteTriggerSettings — тот же шаблон, та же структура.Связь с действием Code рабочего процесса. Встроенное действие Code в конструкторе рабочих процессов само по себе является логической функцией — Twenty создаёт по одной на каждый шаг Code и отображает его редактор встроенным образом.
workflowActionTriggerSettings — это способ превратить разовый встроенный код в повторно используемое действие: определите функцию один раз в своём приложении, и она станет доступной для выбора в любом рабочем процессе, вместо копирования и вставки в каждый шаг Code. См. действие Code в руководстве пользователя, чтобы увидеть, как это выглядит для конечного пользователя.src/logic-functions/enrich-company.logic-function.ts
- Функция может сочетать интерфейсы — объявите и
toolTriggerSettings, иworkflowActionTriggerSettings, чтобы сделать её доступной и в чате, и в конструкторе рабочих процессов. toolTriggerSettings.inputSchemaиworkflowActionTriggerSettings.inputSchema— обе необязательны. Если они опущены, конструктор манифеста выводит их из исходного кода обработчика (JSON Schema — для инструмента ИИ,InputSchemaот Twenty — для действия рабочего процесса). Укажите её явно, когда вам нужна более богатая типизация — например, с полями, учитывающимиFieldMetadataType, такими какCURRENCYилиRELATION, для конструктора рабочих процессов, или с полямиdescription, которые может прочитать ИИ-агент:
InputJsonSchema) и преобразуйте её для действия рабочего процесса с помощью jsonSchemaToInputSchema из twenty-sdk/logic-function. toolTriggerSettings.inputSchema принимает JSON Schema напрямую, в то время как workflowActionTriggerSettings.inputSchema ожидает InputSchema Twenty:Полный пример действия рабочего процесса
workflowActionTriggerSettings принимает четыре поля:Объединяя всё вместе — функция, представленная как действие рабочего процесса, с объявленным выходом, чтобы последующие шаги могли ссылаться на
taskId:src/logic-functions/enrich-company.logic-function.ts
companyName и domain как поля ввода (каждое может получать значения из предыдущих шагов), а последующие шаги могут ссылаться на выходные значения шага taskId и enriched.Напишите хорошее описание в поле
description. Агенты ИИ опираются на поле description функции, чтобы решить, когда использовать инструмент. Чётко опишите, что делает инструмент и когда его следует вызывать.Вспомогательные функции времени выполнения.
twenty-sdk/utils повторно экспортирует небольшие вспомогательные функции времени выполнения, поэтому обработчики никогда не импортируют напрямую из twenty-shared. Например, isDefined(value) возвращает false как для null, так и для undefined — используйте её, чтобы безопасно сузить необязательные входные данные обработчика, которые могут приходить как null во время выполнения, даже если имеют тип T | undefined:Хуки установки — обработчики до установки и после установки — используют тот же рантайм, но объявляются с помощью собственных функций
define и не принимают настройки триггеров. См. раздел Install Hooks для definePreInstallLogicFunction и definePostInstallLogicFunction.Типизированные клиенты API (twenty-client-sdk)
Пакетtwenty-client-sdk предоставляет два типизированных клиента GraphQL для взаимодействия с API Twenty из ваших логических функций и фронт-компонентов.
CoreApiClient
Запрос и изменение данных рабочего пространства (записи, объекты)
CoreApiClient
Запрос и изменение данных рабочего пространства (записи, объекты)
CoreApiClient — основной клиент для запросов и изменений данных рабочего пространства. Он генерируется из схемы вашего рабочего пространства во время yarn twenty dev или yarn twenty dev:build, поэтому полностью типизирован в соответствии с вашими объектами и полями.true, чтобы включить поле, используйте __args для аргументов и вкладывайте объекты для отношений. Вы получаете полное автодополнение и проверку типов на основе схемы вашего рабочего пространства.CoreApiClient генерируется на этапе dev/build. Если вы используете его, не запустив сначала
yarn twenty dev или yarn twenty dev:build, он выбросит ошибку. Генерация происходит автоматически — CLI анализирует GraphQL-схему вашего рабочего пространства и создает типизированный клиент с помощью @genql/cli.Использование CoreSchema для аннотаций типов
CoreSchema предоставляет типы TypeScript, соответствующие объектам вашего рабочего пространства — это полезно для типизации состояния компонентов или параметров функций:MetadataApiClient
Конфигурация рабочего пространства, приложения и загрузка файлов
MetadataApiClient
Конфигурация рабочего пространства, приложения и загрузка файлов
MetadataApiClient поставляется в готовом виде вместе с SDK (генерация не требуется). Он выполняет запросы к эндпоинту /metadata для получения конфигурации рабочего пространства, приложений и загрузки файлов.Загрузка файлов
MetadataApiClient включает метод uploadFile для прикрепления файлов к полям типа файла:Основные моменты:
- Он использует
universalIdentifierполя (а не его идентификатор, специфичный для рабочего пространства), поэтому ваш код загрузки будет работать в любом рабочем пространстве, где установлено ваше приложение. - Возвращаемый
url— это подписанный URL, который можно использовать для доступа к загруженному файлу.
Когда ваш код выполняется на Twenty (логические функции или фронт-компоненты), платформа предоставляет учётные данные в виде переменных окружения:
TWENTY_API_URL— базовый URL API TwentyTWENTY_APP_ACCESS_TOKEN— краткоживущий ключ, ограниченный ролью функции по умолчанию вашего приложения
process.env. Права ключа API определяются ролью, объявленной с помощью defineApplicationRole() (или указанной через defaultRoleUniversalIdentifier в application-config.ts).