Skip to main content
Логические функции выполняются в изолированной среде во временных процессах Node.js — после завершения запуска в памяти ничего не сохраняется. Когда вам нужно что-то запомнить между запусками (кэшировать дорогой ответ API, сохранить курсор для инкрементальной синхронизации, «задебаунсить» работу или передать состояние от одной функции к другой), сохраняйте это во встроенном хранилище ключ-значение. Каждое приложение получает собственное изолированное пространство имён: записи привязаны к аутентифицированному приложению, поэтому ваши ключи никогда не могут конфликтовать с ключами другого приложения или быть прочитаны другим приложением.

Получение, установка, удаление

Импортируйте kv из twenty-sdk/logic-function. Значения могут быть любыми JSON-сериализуемыми данными.
src/logic-functions/sync-linear-issues.ts

Области действия

У каждой записи есть область видимости (scope), которая передаётся как опция при каждом вызове. По умолчанию используется WORKSPACE.
  • WORKSPACE (по умолчанию) — запись доступна только для текущей установки вашего приложения в рабочем пространстве. Каждое рабочее пространство, в которое устанавливается приложение, получает собственный независимый набор ключей. Это то, что вам нужно для кэшей, курсоров и состояния на уровне рабочего пространства.
  • SERVER — запись разделяется между всеми установками вашего приложения на сервере. Серверные записи ведут себя как механизм резервирования: сохраняемым значением всегда является workspaceId, зарезервировавший ключ (опустите value при вызове set, чтобы зарезервировать ключ для текущего рабочего пространства), и только это рабочее пространство может перезаписать или удалить запись. Любая установка может прочитать эту запись.
Резервирования на сервере используются для маршрутизации между рабочими пространствами. Резолвер серверного маршрута выполняется в рабочем пространстве владельца регистрации приложения, но входящий вебхук обычно содержит только внешний идентификатор аккаунта, а не workspaceId в Twenty. Пусть каждое рабочее пространство зарезервирует свой внешний идентификатор в момент подключения, а затем разрешайте его в маршруте:
Поскольку серверный ключ может быть занят только для собственного рабочего пространства вызывающего кода и никогда не может быть перезаписан другим, рабочее пространство не может перехватить сопоставление, принадлежащее кому-то ещё. kv.set выбрасывает ошибку, если ключ уже занят другим рабочим пространством.

Использование: кэширование дорогого вызова

Типичный сценарий — кэширование медленного или ограниченного по частоте ответа стороннего сервиса, чтобы при повторных запусках переиспользовать его, а не нести затраты каждый раз.
src/logic-functions/getExchangeRate.logic-function.ts

Шаблоны и советы

  • Пространства имён. Добавляйте префиксы к ключам, чтобы разделять разные задачи — sync-cursor:linear, cache:exchange-rate:USD:EUR, lock:nightly-report.
  • Срок жизни (TTL). У хранилища нет встроенного механизма истечения срока действия. Сохраняйте метку времени внутри значения (как в примере с кэшем) и проверяйте её при чтении или очищайте устаревшие ключи из функции, запускаемой по cron.
  • Что хранить. Любое JSON-сериализуемое значение — числа, строки, массивы, объекты. Держите записи небольшими; это для координации и кэширования, а не для больших блобов или файлов. Для файлов используйте поле FILES и uploadFile.
  • Видимость. Записи хранятся в базе данных экземпляра, а не как записи рабочего пространства — они никогда не отображаются в интерфейсе рабочего пространства, не являются частью модели данных вашего приложения и не требуют ролей или прав доступа к объектам.

Альтернатива: объект-хранилище с возможностью запросов

Встроенное хранилище намеренно сделано непрозрачным: записи не являются записями объектов, поэтому вы не можете просматривать их в интерфейсе, связывать их с другими объектами или фильтровать их с помощью запросов к записям. Когда вам нужно что-то из этого — например, видимый журнал синхронизаций или состояние на уровне записи, — вместо этого определите небольшой технический объект с уникальным полем key и полем value типа RAW_JSON, и выполняйте к нему запросы через типизированный API-клиент. См. Objects для справки по defineObject и Data → Unique indexes по обеспечению уникальности ключей.
  • Привязка к записи. Добавьте relation от объекта-хранилища к целевому объекту вместо кодирования идентификатора в ключе.
  • Видимость и разрешения. Строки живут в базе данных рабочего пространства как любые другие записи, поэтому к ним можно обращаться через API, и они подчиняются ролям вашего приложения. Чтобы скрыть хранилище из основного пользовательского интерфейса, не добавляйте его в навигационное меню.
В отличие от встроенного хранилища, пользовательский объект всегда ограничен одним рабочим пространством — он не может разделять записи между установками так, как это делают ключи SERVER.