Используйте ресурсы SDK (типы и конфигурация)
Пакет twenty-sdk предоставляет типизированные строительные блоки и вспомогательные функции, которые вы используете внутри своего приложения. Ниже — ключевые части, с которыми вы будете работать чаще всего.Вспомогательные функции
SDK предоставляет вспомогательные функции для определения сущностей вашего приложения. Как описано в Обнаружение сущностей, вы должны использоватьexport default define<Entity>({...}), чтобы ваши сущности были обнаружены:
| Функция | Назначение |
|---|---|
defineApplication | Настройка метаданных приложения (обязательно, по одному на приложение) |
defineObject | Определяет пользовательские объекты с полями |
defineLogicFunction | Определение логических функций с обработчиками |
definePreInstallLogicFunction | Определяет предустановочную логическую функцию (по одной на приложение) |
definePostInstallLogicFunction | Определяет послеустановочную логическую функцию (по одной на приложение) |
defineFrontComponent | Определение фронт-компонентов для настраиваемого интерфейса |
defineRole | Настраивает права роли и доступ к объектам |
defineField | Расширение существующих объектов дополнительными полями |
defineView | Определяйте сохранённые представления для объектов |
defineNavigationMenuItem | Определяйте ссылки боковой панели навигации |
defineSkill | Определение навыков агента ИИ |
Определение объектов
Пользовательские объекты описывают как схему, так и поведение записей в вашем рабочем пространстве. ИспользуйтеdefineObject() для определения объектов со встроенной валидацией:
- Используйте
defineObject()для встроенной валидации и лучшей поддержки в IDE. universalIdentifierдолжен быть уникальным и стабильным между развёртываниями.- Каждому полю требуются
name,type,labelи собственный стабильныйuniversalIdentifier. - Массив
fieldsнеобязателен — вы можете определять объекты без пользовательских полей. - Вы можете сгенерировать новые объекты с помощью
yarn twenty entity:add, который проведёт вас через настройку имени, полей и связей.
Базовые поля создаются автоматически. Когда вы определяете пользовательский объект, Twenty автоматически добавляет стандартные поля,
такие как
id, name, createdAt, updatedAt, createdBy, updatedBy и deletedAt.
Вам не нужно определять их в массиве fields — добавляйте только свои пользовательские поля.
Вы можете переопределить поля по умолчанию, определив поле с тем же именем в массиве fields,
но это не рекомендуется.Конфигурация приложения (application-config.ts)
У каждого приложения есть единственный файлapplication-config.ts, который описывает:
- Что это за приложение: идентификаторы, отображаемое имя и описание.
- Как запускаются его функции: какую роль они используют для прав доступа.
- (Необязательно) переменные: пары ключ-значение, предоставляемые вашим функциям как переменные окружения.
- (Необязательно) предустановочная функция: логическая функция, которая запускается до установки приложения.
- (Необязательно) послеустановочная функция: функция логики, которая запускается после установки приложения.
defineApplication() для определения конфигурации вашего приложения:
universalIdentifier— это детерминированные идентификаторы, которыми вы управляете; сгенерируйте их один раз и сохраняйте стабильными между синхронизациями.applicationVariablesстановятся переменными окружения для ваших функций (например,DEFAULT_RECIPIENT_NAMEдоступна какprocess.env.DEFAULT_RECIPIENT_NAME).defaultRoleUniversalIdentifierдолжен соответствовать файлу роли (см. ниже).- Предустановочные и послеустановочные функции автоматически обнаруживаются во время сборки манифеста. См. Предустановочные функции и Послеустановочные функции.
Роли и разрешения
Приложения могут определять роли, инкапсулирующие права на объекты и действия в вашем рабочем пространстве. ПолеdefaultRoleUniversalIdentifier в application-config.ts обозначает роль по умолчанию, используемую логическими функциями вашего приложения.
- Ключ API во время выполнения, подставляемый как
TWENTY_API_KEY, получается из этой роли функции по умолчанию. - Типизированный клиент будет ограничен правами, предоставленными этой ролью.
- Следуйте принципу наименьших привилегий: создайте отдельную роль только с теми правами, которые нужны вашим функциям, и укажите её универсальный идентификатор.
Роль функции по умолчанию (*.role.ts)
Когда вы генерируете новое приложение, CLI также создаёт файл роли по умолчанию. ИспользуйтеdefineRole() для определения ролей со встроенной валидацией:
universalIdentifier этой роли затем указывается в application-config.ts как defaultRoleUniversalIdentifier. Иными словами:
- *.role.ts определяет, что может делать роль функции по умолчанию.
- application-config.ts указывает на эту роль, чтобы ваши функции наследовали её права.
- Начните со сгенерированной роли, затем постепенно ограничивайте её, следуя принципу наименьших привилегий.
- Замените
objectPermissionsиfieldPermissionsна объекты/поля, которые нужны вашим функциям. permissionFlagsуправляют доступом к возможностям на уровне платформы. Держите их минимальными; добавляйте только то, что нужно.- См. рабочий пример в приложении Hello World:
packages/twenty-apps/hello-world/src/roles/function-role.ts.
Конфигурация логической функции и точка входа
Каждый файл функции используетdefineLogicFunction() для экспорта конфигурации с обработчиком и необязательными триггерами.
- route: Публикует вашу функцию по HTTP-пути и методу под конечной точкой
/s/:
например,path: '/post-card/create',-> вызов по адресу<APP_URL>/s/post-card/create
- cron: Запускает вашу функцию по расписанию с использованием выражения CRON.
- databaseEvent: Запускается при событиях жизненного цикла объектов рабочего пространства. Когда операция события —
updated, можно указать конкретные поля для отслеживания в массивеupdatedFields. Если оставить не заданным или пустым, любое обновление будет вызывать функцию.
например, person.updated
Заметки:
- Массив
triggersнеобязателен. Функции без триггеров можно использовать как вспомогательные, вызываемые другими функциями. - Вы можете сочетать несколько типов триггеров в одной функции.
Предустановочные функции
Предустановочная функция — это логическая функция, которая автоматически выполняется до установки вашего приложения в рабочем пространстве. Это полезно для задач валидации, проверки предварительных условий или подготовки состояния рабочего пространства перед основной установкой. Когда вы создаёте каркас нового приложения с помощьюcreate-twenty-app, для вас генерируется предустановочная функция по пути src/logic-functions/pre-install.ts:
- Предустановочные функции используют
definePreInstallLogicFunction()— специализированный вариант, который опускает настройки триггеров (cronTriggerSettings,databaseEventTriggerSettings,httpRouteTriggerSettings,isTool). - Обработчик получает
InstallLogicFunctionPayloadс{ previousVersion: string }— версией приложения, которая была установлена ранее (или пустой строкой для новых установок). - Для каждого приложения допускается только одна предустановочная функция. Сборка манифеста завершится ошибкой, если будет обнаружено более одной такой функции.
- Параметр
universalIdentifierфункции автоматически устанавливается какpreInstallLogicFunctionUniversalIdentifierв манифесте приложения во время сборки — вам не нужно ссылаться на него вdefineApplication(). - Тайм-аут по умолчанию установлен на 300 секунд (5 минут), чтобы обеспечить выполнение более длительных задач подготовки.
- Предустановочным функциям не нужны триггеры — платформа вызывает их перед установкой или вручную через
function:execute --preInstall.
Послеустановочные функции
Послеустановочная функция — это функция логики, которая автоматически выполняется после установки вашего приложения в рабочем пространстве. Это полезно для одноразовых задач настройки, таких как инициализация данных по умолчанию, создание начальных записей или настройка параметров рабочего пространства. Когда вы создаёте каркас нового приложения с помощьюcreate-twenty-app, для вас генерируется постустановочная функция по пути src/logic-functions/post-install.ts:
- Послеустановочные функции используют
definePostInstallLogicFunction()— специализированный вариант, который опускает настройки триггеров (cronTriggerSettings,databaseEventTriggerSettings,httpRouteTriggerSettings,isTool). - Обработчик получает
InstallLogicFunctionPayloadс{ previousVersion: string }— версией приложения, которая была установлена ранее (или пустой строкой для новых установок). - Для каждого приложения допускается только одна послеустановочная функция. Сборка манифеста завершится ошибкой, если будет обнаружено более одной такой функции.
- Параметр
universalIdentifierфункции автоматически устанавливается какpostInstallLogicFunctionUniversalIdentifierв манифесте приложения во время сборки — вам не нужно ссылаться на него вdefineApplication(). - Тайм-аут по умолчанию установлен на 300 секунд (5 минут), чтобы позволить выполнять более длительные задачи настройки, такие как инициализация данных.
- Постустановочным функциям не нужны триггеры — платформа вызывает их во время установки или вручную через
function:execute --postInstall.
Полезная нагрузка триггера маршрута
Когда триггер маршрута вызывает вашу логическую функцию, она получает объектRoutePayload, соответствующий формату AWS HTTP API v2. Импортируйте тип из twenty-sdk:
RoutePayload имеет следующую структуру:
| Свойство | Тип | Описание |
|---|---|---|
headers | Record<string, string | undefined> | HTTP-заголовки (только перечисленные в forwardedRequestHeaders) |
queryStringParameters | Record<string, string | undefined> | Параметры строки запроса (несколько значений объединяются запятыми) |
pathParameters | Record<string, string | undefined> | Параметры пути, извлечённые из шаблона маршрута (например, /users/:id → { id: '123' }) |
body | object | null | Разобранное тело запроса (JSON) |
isBase64Encoded | логический тип | Является ли тело закодированным в base64 |
requestContext.http.method | строка | Метод HTTP (GET, POST, PUT, PATCH, DELETE) |
requestContext.http.path | строка | Необработанный путь запроса |
Проброс HTTP-заголовков
По умолчанию HTTP-заголовки из входящих запросов не передаются в вашу логическую функцию по соображениям безопасности. Чтобы получить доступ к определённым заголовкам, явно перечислите их в массивеforwardedRequestHeaders:
Имена заголовков приводятся к нижнему регистру. Обращайтесь к ним, используя ключи в нижнем регистре (например,
event.headers['content-type']).- Сгенерировано: Запустите
yarn twenty entity:addи выберите опцию добавления новой функции логики. Это создаёт стартовый файл с обработчиком и конфигурацией. - Вручную: Создайте новый файл
*.logic-function.tsи используйтеdefineLogicFunction(), следуя тому же шаблону.
Пометка логической функции как инструмента
Логические функции можно предоставлять как инструменты для ИИ-агентов и рабочих процессов. Когда функция помечена как инструмент, она становится доступной для ИИ Twenty и может быть выбрана в качестве шага в автоматизациях рабочих процессов. Чтобы пометить логическую функцию как инструмент, установитеisTool: true и укажите toolInputSchema для описания ожидаемых входных параметров с помощью схемы JSON:
isTool(boolean, по умолчанию:false): Если значение равноtrue, функция регистрируется как инструмент и становится доступной агентам ИИ и автоматизациям рабочих процессов.toolInputSchema(object, необязательно): Объект JSON Schema, который описывает параметры, которые принимает ваша функция. Агенты ИИ используют эту схему, чтобы понять, какие входные данные ожидает инструмент, и проверять корректность вызовов. Если опущено, по умолчанию используется схема{ type: 'object', properties: {} }(без параметров).- Функции с
isTool: false(или без указания) не выставляются как инструменты. Их по-прежнему можно выполнять напрямую или вызывать из других функций, но они не будут отображаться при обнаружении инструментов. - Именование инструмента: При публикации как инструмента имя функции автоматически нормализуется до
logic_function_<name>(в нижнем регистре, небуквенно-цифровые символы заменяются на подчёркивания). Например,enrich-companyстановитсяlogic_function_enrich_company. - Вы можете комбинировать
isToolс триггерами — функция может одновременно быть инструментом (вызываемым агентами ИИ) и запускаться событиями (cron, события базы данных, маршруты).
Напишите хорошее описание в поле
description. Агенты ИИ опираются на поле description функции, чтобы решить, когда использовать инструмент. Чётко опишите, что делает инструмент и когда его следует вызывать.Фронт-компоненты
Фронт-компоненты позволяют создавать пользовательские компоненты React, которые рендерятся внутри интерфейса Twenty. ИспользуйтеdefineFrontComponent() для определения компонентов со встроенной валидацией:
- Фронт-компоненты — это компоненты React, которые рендерятся в изолированных контекстах внутри Twenty.
- Поле
componentссылается на ваш компонент React. - Компоненты автоматически собираются и синхронизируются во время
yarn twenty app:dev.
- Сгенерировано: Запустите
yarn twenty entity:addи выберите опцию добавления нового фронтенд-компонента. - Вручную: Создайте новый файл
.tsxи используйтеdefineFrontComponent(), следуя тому же шаблону.
Навыки
Навыки определяют многократно используемые инструкции и возможности, которые агенты ИИ могут использовать в вашем рабочем пространстве. ИспользуйтеdefineSkill() для определения навыков со встроенной валидацией:
name— уникальная строка-идентификатор навыка (рекомендуется kebab-case).label— читаемое человеком отображаемое имя, показываемое в UI.contentсодержит инструкции навыка — это текст, который использует агент ИИ.icon(необязательно) задаёт значок, отображаемый в UI.description(необязательно) предоставляет дополнительный контекст о назначении навыка.
- Сгенерировано: Запустите
yarn twenty entity:addи выберите опцию добавления нового навыка. - Вручную: Создайте новый файл и используйте
defineSkill(), следуя тому же шаблону.
Сгенерированные типизированные клиенты
Два типизированных клиента автоматически генерируются с помощьюyarn twenty app:dev и сохраняются в node_modules/twenty-sdk/generated на основе схемы вашего рабочего пространства:
CoreApiClient— выполняет запросы к конечной точке/graphqlдля получения данных рабочего пространстваMetadataApiClient— выполняет запросы к эндпоинту/metadataдля получения конфигурации рабочего пространства и загрузки файлов.
yarn twenty app:dev при изменении ваших объектов или полей.
Учётные данные времени выполнения в логических функциях
Когда ваша функция запускается на Twenty, платформа подставляет учётные данные как переменные окружения перед выполнением вашего кода:TWENTY_API_URL: Базовый URL API Twenty, на который нацелено ваше приложение.TWENTY_API_KEY: Краткоживущий ключ, ограниченный ролью функции по умолчанию вашего приложения.
- Вам не нужно передавать URL или ключ API сгенерированному клиенту. Он читает
TWENTY_API_URLиTWENTY_API_KEYиз process.env во время выполнения. - Права ключа API определяются ролью, на которую ссылается ваш
application-config.tsчерезdefaultRoleUniversalIdentifier. Это роль по умолчанию, используемая логическими функциями вашего приложения. - Приложения могут определять роли, чтобы следовать принципу наименьших привилегий. Предоставляйте только те права, которые нужны вашим функциям, затем укажите в
defaultRoleUniversalIdentifierуниверсальный идентификатор этой роли.
Загрузка файлов
СгенерированныйMetadataApiClient включает метод uploadFile для прикрепления файлов к полям типа «файл» в объектах вашего рабочего пространства. Поскольку стандартные клиенты GraphQL изначально не поддерживают многочастовую загрузку файлов, клиент предоставляет специальный метод, который под капотом реализует спецификацию многочастных запросов GraphQL.
| Параметр | Тип | Описание |
|---|---|---|
fileBuffer | Buffer | Необработанное содержимое файла |
filename | строка | Имя файла (используется для хранения и отображения) |
contentType | строка | Тип MIME файла (по умолчанию application/octet-stream, если не указан) |
fieldMetadataUniversalIdentifier | строка | Значение universalIdentifier для поля типа файла в вашем объекте |
- Метод
uploadFileдоступен вMetadataApiClient, потому что мутация загрузки обрабатывается эндпоинтом/metadata. - Он использует
universalIdentifierполя (а не его идентификатор, специфичный для рабочего пространства), поэтому ваш код загрузки будет работать в любом рабочем пространстве, где установлено ваше приложение — в соответствии с тем, как приложения ссылаются на поля повсюду. - Возвращаемый
url— это подписанный URL, который можно использовать для доступа к загруженному файлу.