Triggo Documentation
SDK

Context and Store

Reference for ActionContext and TriggerContext — runtime context objects providing auth, property values, persistent storage, and webhook data.

Context and Store

Every action run function and trigger lifecycle hook receives a context object. The context provides access to authentication credentials, resolved property values, and a persistent key-value store.

ActionContext

import type { ActionContext } from "@triggo/connector-sdk";

interface ActionContext<TAuth = unknown, TProps = unknown> {
  readonly auth: TAuth;
  readonly propsValue: TProps;
  readonly store: StoreContext;
}
FieldTypeDescription
authTAuthAuthentication credentials. Shape depends on the connector's auth type (see below).
propsValueTPropsResolved input property values. Keys match the props object passed to createAction().
storeStoreContextPersistent key-value store scoped to the connector + connection.

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 extends ActionContext with two additional fields:

FieldTypeDescription
webhookUrlstring | undefinedThe generated webhook URL. Available during onEnable for webhook triggers.
payloadunknown | undefinedThe raw incoming event payload. Available during run for webhook triggers.

Auth Shape by Type

The context.auth type depends on the connector's AuthDefinition:

Auth Typecontext.auth Shape
ConnectorAuth.OAuth2OAuth2Credentials (see Authentication)
ConnectorAuth.SecretText{ secret: string }
ConnectorAuth.CustomAuthRecord<string, unknown> (keys match auth prop names)
ConnectorAuth.Noneundefined

Typing with Generics

Use the generic parameters on createAction and createTrigger for type-safe context access:

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

The store provides persistent key-value storage scoped to the connector instance. Data survives across pipeline executions.

interface StoreContext {
  get(key: string): Promise<unknown>;
  put(key: string, value: unknown): Promise<void>;
  delete(key: string): Promise<void>;
}

Methods

MethodDescription
get(key)Retrieves a value by key. Returns undefined if the key does not exist.
put(key, value)Stores a value. The value is serialized as JSON. Overwrites any existing value.
delete(key)Removes a key-value pair. No-op if the key does not exist.

Common Use Cases

Caching API responses:

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;
}

Tracking poll cursor for polling triggers:

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;
}

Storing external webhook IDs for cleanup:

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");
  }
}

Best Practices

  • Always cast store.get() results since the return type is unknown
  • Use the generic type parameters on createAction<TAuth, TProps> for compile-time safety
  • Keep stored values small and serializable (no functions, no circular references)
  • Clean up store keys in onDisable to avoid stale data
  • Scope cache keys by relevant context (e.g., include user ID or workspace ID in the key)

On this page