Контекст и хранилище
Справочник по ActionContext и TriggerContext — объекты контекста выполнения, предоставляющие аутентификацию, значения свойств, персистентное хранилище и данные вебхуков.
Контекст и хранилище
Каждая функция run действия и каждый хук жизненного цикла триггера получает объект контекста. Контекст предоставляет доступ к учётным данным аутентификации, разрешённым значениям свойств и персистентному key-value хранилищу.
ActionContext
import type { ActionContext } from "@triggo/connector-sdk";
interface ActionContext<TAuth = unknown, TProps = unknown> {
readonly auth: TAuth;
readonly propsValue: TProps;
readonly store: StoreContext;
}| Поле | Тип | Описание |
|---|---|---|
auth | TAuth | Учётные данные аутентификации. Форма зависит от типа аутентификации коннектора (см. ниже). |
propsValue | TProps | Разрешённые значения входных свойств. Ключи соответствуют объекту props, переданному в createAction(). |
store | StoreContext | Персистентное key-value хранилище, привязанное к коннектору + подключению. |
TriggerContext
import type { TriggerContext } from "@triggo/connector-sdk";
interface TriggerContext<TAuth = unknown, TProps = unknown> {
readonly auth: TAuth;
readonly propsValue: TProps;
readonly store: StoreContext;
readonly webhookUrl?: string;
readonly payload?: unknown;
}TriggerContext расширяет ActionContext двумя дополнительными полями:
| Поле | Тип | Описание |
|---|---|---|
webhookUrl | string | undefined | Сгенерированный URL вебхука. Доступен во время onEnable для webhook-триггеров. |
payload | unknown | undefined | Сырые данные входящего события. Доступны во время run для webhook-триггеров. |
Форма auth по типу аутентификации
Тип context.auth зависит от AuthDefinition коннектора:
| Тип аутентификации | Форма context.auth |
|---|---|
ConnectorAuth.OAuth2 | OAuth2Credentials (см. Аутентификация) |
ConnectorAuth.SecretText | { secret: string } |
ConnectorAuth.CustomAuth | Record<string, unknown> (ключи соответствуют именам свойств аутентификации) |
ConnectorAuth.None | undefined |
Типизация с помощью дженериков
Используйте параметры типов в createAction и createTrigger для типобезопасного доступа к контексту:
import { createAction } from "@triggo/connector-sdk";
interface MyAuth {
readonly secret: string;
}
interface MyProps {
readonly message: string;
readonly chatId: string;
}
export const sendMessage = createAction<MyAuth, MyProps>({
name: "send_message",
displayName: "Send Message",
description: "Sends a message to a chat.",
props: {
message: Property.ShortText({
displayName: "Message",
required: true,
}),
chatId: Property.ShortText({
displayName: "Chat ID",
required: true,
}),
},
async run(context) {
// context.auth is typed as MyAuth
const token = context.auth.secret;
// context.propsValue is typed as MyProps
const { message, chatId } = context.propsValue;
const response = await fetch(`https://api.example.com/chats/${chatId}/messages`, {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ text: message }),
});
return await response.json();
},
});StoreContext
Хранилище предоставляет персистентное key-value хранение, привязанное к экземпляру коннектора. Данные сохраняются между выполнениями пайплайна.
interface StoreContext {
get(key: string): Promise<unknown>;
put(key: string, value: unknown): Promise<void>;
delete(key: string): Promise<void>;
}Методы
| Метод | Описание |
|---|---|
get(key) | Получает значение по ключу. Возвращает undefined, если ключ не существует. |
put(key, value) | Сохраняет значение. Значение сериализуется как JSON. Перезаписывает существующее значение. |
delete(key) | Удаляет пару ключ-значение. Не вызывает ошибку, если ключ не существует. |
Типичные сценарии использования
Кеширование ответов API:
async run(context) {
const cacheKey = "user_list";
const cached = await context.store.get(cacheKey) as CachedData | undefined;
if (cached && Date.now() - cached.timestamp < 300_000) {
return cached.data;
}
const data = await fetchUsers(context.auth);
await context.store.put(cacheKey, { data, timestamp: Date.now() });
return data;
}Отслеживание курсора для polling-триггеров:
async run(context) {
const lastCursor = (await context.store.get("cursor")) as string | undefined;
const events = await fetchEvents(context.auth, lastCursor);
if (events.length > 0) {
const newCursor = events[events.length - 1]!.id;
await context.store.put("cursor", newCursor);
}
return events;
}Хранение внешних ID вебхуков для очистки:
async onEnable(context) {
const webhookId = await registerWebhook(context.auth, context.webhookUrl!);
await context.store.put("webhookId", webhookId);
return { externalWebhookId: webhookId };
}
async onDisable(context) {
const webhookId = (await context.store.get("webhookId")) as string | null;
if (webhookId) {
await deleteWebhook(context.auth, webhookId);
await context.store.delete("webhookId");
}
}Лучшие практики
- Всегда приводите результаты
store.get()к нужному типу, так как возвращаемый тип --unknown - Используйте параметры типов
createAction<TAuth, TProps>для типобезопасности на этапе компиляции - Храните в хранилище небольшие сериализуемые значения (без функций, без циклических ссылок)
- Очищайте ключи хранилища в
onDisable, чтобы избежать устаревших данных - Используйте контекстно-зависимые ключи кеша (например, включайте ID пользователя или ID рабочего пространства в ключ)