# Triggers

Triggers are the entry points into your agent's flows, handling incoming events and initializing conversations with context and memory.

## Trigger Types

MindedJS supports two types of triggers:

### 1. Webhook Triggers

Triggered by HTTP requests to specific endpoints in the Minded platform. Configured through the Minded platform interface. Each webhook trigger belongs to a specific agent and cannot be shared between agents.

> **Note**: All triggers are agent-specific and configured through the Minded platform.

#### Webhook Structure

For webhook triggers, `triggerBody` contains:

* **`body`**: The HTTP request body payload
* **`headers`**: The HTTP request headers

```typescript
// Webhook triggerBody structure
{
  body: any;        // Request payload
  headers: {        // Request headers
    'content-type': string;
    'x-forwarded-for': string;
    'user-agent': string;
    // ... other headers
  }
}
```

**Accessing headers:**

```typescript
agent.on(AgentEvents.TRIGGER_EVENT, async ({ triggerBody }) => {
  const senderIP = triggerBody.headers?.['x-forwarded-for'];
  const contentType = triggerBody.headers?.['content-type'];
  return { isQualified: true };
});
```

**Common headers:** `x-forwarded-for`, `content-type`, `user-agent`, and custom headers.

#### Validate Webhook Input

```typescript
// ✅ Good - Input validation
agent.on(AgentEvents.TRIGGER_EVENT, async ({ triggerBody, state }) => {
  if (triggerBody.headers?.authorization !== 'expected-token') {
    return { isQualified: false };
  }
  if (!triggerBody.body?.customerId || !triggerBody.body?.message) {
    return { isQualified: false };
  }
  return { isQualified: true };
});
```

#### Output Schema

Define an `outputSchema` on webhook triggers to automatically extract structured fields from the payload using LLM. Extracted fields are available via `{trigger.fieldName}` placeholders in prompts and parameters.

```yaml
# In your flow YAML
trigger:
  type: trigger
  triggerType: webhook
  outputSchema:
    - name: orderId
      type: string
      description: The order identifier
    - name: customerEmail
      type: string
      description: Customer email address
```

**Usage in prompts:**

```
Process order {trigger.orderId} for customer {trigger.customerEmail}
```

### 2. Schedule Triggers

Triggered automatically based on a cron schedule. Configured with a cron expression and optional timezone (defaults to UTC).

#### Cron Expression Format

**Examples:**

* `'0 0 * * *'` - Daily at midnight
* `'0 9 * * 1'` - Every Monday at 9:00 AM
* `'*/15 * * * *'` - Every 15 minutes
* `'0 12 * * 1-5'` - Every weekday at noon

#### Timezone Configuration

Use IANA timezone identifiers:

```typescript
{
  triggerType: TriggerType.SCHEDULE,
  cronExpression: '0 9 * * 1-5', // Weekdays at 9 AM
  timezone: 'America/New_York' // Optional, defaults to UTC
}
```

**Behavior:**

* Automatically deployed when agent is deployed
* Enabled when agent is "live", disabled otherwise
* Creates new session unless `sessionId` is provided

## Trigger Event

The `TRIGGER_EVENT` is emitted when any trigger is invoked, allowing you to qualify triggers and modify state before processing.

### TriggerEvent Interface

```typescript
export interface TriggerEvent {
  triggerBody: any;
  triggerName: string;
}
```

### Event Lifecycle

The handler serves two purposes:

1. **Qualifying Triggers**: Return `{ isQualified: boolean }` to determine if processing should continue
2. **Adding Information to State**: Modify `state` directly by reference

**Handler must return:**

```typescript
return { isQualified: true }; // Continue processing
return { isQualified: false }; // Stop processing
```

**Modifying state:**

```typescript
agent.on(AgentEvents.TRIGGER_EVENT, async ({ triggerBody, state }) => {
  state.memory.customerId = triggerBody.body?.customerId;
  state.messages.push(new SystemMessage('Processing request'));
  return { isQualified: true };
});
```

### Development Environment: Dashboard Messages

In development, agents are invoked with `triggerName = 'dashboard_message'` for dashboard messages. Handle this case to prevent default webhook behavior. Otherwise, avoid using this parameter.

```typescript
agent.on(AgentEvents.TRIGGER_EVENT, async ({ triggerName, triggerBody, state }) => {
  if (triggerName === 'dashboard_message') {
    return { isQualified: true };
  }

  // Handle webhook triggers
  if (triggerBody.body && triggerBody.headers) {
    if (!triggerBody.body.customerId) {
      return { isQualified: false };
    }
    state.memory.webhookData = triggerBody.body;
    return { isQualified: true };
  }

  return { isQualified: false };
});
```

## Extracting Session ID from Webhooks

Extract a unique `sessionId` from webhook payloads to maintain conversation continuity.

### Using parseSessionIdFromTrigger

Configure the Agent to automatically extract `sessionId`:

```typescript
const agent = new Agent({
  memorySchema,
  config,
  tools,
  parseSessionIdFromTrigger: (triggerBody) => triggerBody?.body?.data?.item?.id,
});
```

**How it works:**

* Receives `triggerBody` as parameter
* Returns a string session identifier
* If `undefined`/`null`, platform generates a new `sessionId`
* Used to resume existing agent sessions or create new ones

**Examples:**

```typescript
// Extract from nested structure
parseSessionIdFromTrigger: (triggerBody) => {
  return triggerBody?.body?.data?.item?.id;
};
```

**Fallback:** If not provided or returns `undefined`/`null`, checks `triggerBody.sessionId`, then generates a new UUID.

### Session ID in Trigger Events

* **Sandbox Playground**: Platform auto-generates `sessionId` for each execution
* **Production**: Users provide their own `sessionId` to support resuming sessions
* **Session Continuity**: Matching `sessionId` resumes previous state instead of starting fresh
* **Schedule Triggers**: Creates new session unless `sessionId` is explicitly provided


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.minded.com/low-code-editor/triggers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
