> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/iii-hq/sdk/llms.txt
> Use this file to discover all available pages before exploring further.

# Triggers

> Event-driven function invocations

## Overview

Triggers enable event-driven function invocations. When a trigger's condition is met, it automatically invokes the associated function. The III SDK supports both registering triggers and implementing custom trigger types.

## Registering Triggers

### register\_trigger

Register a trigger that will invoke a function based on events.

```rust theme={null}
pub fn register_trigger(
    &self,
    trigger_type: impl Into<String>,
    function_id: impl Into<String>,
    config: impl serde::Serialize,
) -> Result<Trigger, IIIError>
```

<ParamField path="trigger_type" type="impl Into<String>" required>
  Type of trigger (e.g., "http", "cron", "stream")
</ParamField>

<ParamField path="function_id" type="impl Into<String>" required>
  ID of the function to invoke when triggered
</ParamField>

<ParamField path="config" type="impl serde::Serialize" required>
  Configuration specific to the trigger type (serialized to JSON)
</ParamField>

<ResponseField name="Trigger" type="Result<Trigger, IIIError>">
  Trigger handle that can be used to unregister
</ResponseField>

**Example - HTTP Trigger:**

```rust theme={null}
use iii_sdk::III;
use serde_json::json;

let iii = III::new("ws://localhost:49134");

// Register a function
iii.register_function("handle_webhook", |input| async move {
    println!("Webhook received: {:?}", input);
    Ok(json!({ "status": "processed" }))
});

// Register an HTTP trigger
let trigger = iii.register_trigger(
    "http",
    "handle_webhook",
    json!({
        "path": "/webhook",
        "method": "POST"
    })
)?;

iii.connect().await?;
```

**Example - Cron Trigger:**

```rust theme={null}
use serde_json::json;

// Schedule a function to run every 5 minutes
let trigger = iii.register_trigger(
    "cron",
    "cleanup_task",
    json!({
        "schedule": "*/5 * * * *"
    })
)?;
```

**Example - Stream Trigger:**

```rust theme={null}
use serde_json::json;

// Trigger on stream updates
let trigger = iii.register_trigger(
    "stream",
    "process_event",
    json!({
        "stream": "events",
        "group": "analytics"
    })
)?;
```

### Unregistering Triggers

Triggers are automatically unregistered when the `Trigger` handle is dropped, or you can manually unregister:

```rust theme={null}
let trigger = iii.register_trigger("http", "my_func", json!({}))?;

// Manually unregister
trigger.unregister();

// Or let it drop automatically
drop(trigger);
```

## Listing Triggers

### list\_triggers

List all registered triggers in the engine.

```rust theme={null}
pub async fn list_triggers(&self) -> Result<Vec<TriggerInfo>, IIIError>
```

<ResponseField name="Vec<TriggerInfo>" type="Result<Vec<TriggerInfo>, IIIError>">
  List of all registered triggers
</ResponseField>

**Example:**

```rust theme={null}
let triggers = iii.list_triggers().await?;

for trigger in triggers {
    println!("Trigger ID: {}", trigger.id);
    println!("  Type: {}", trigger.trigger_type);
    println!("  Function: {}", trigger.function_id);
    println!("  Config: {}", trigger.config);
}
```

## Implementing Custom Trigger Types

### TriggerHandler Trait

Implement custom trigger types by implementing the `TriggerHandler` trait.

```rust theme={null}
#[async_trait]
pub trait TriggerHandler: Send + Sync {
    async fn register_trigger(&self, config: TriggerConfig) -> Result<(), IIIError>;
    async fn unregister_trigger(&self, config: TriggerConfig) -> Result<(), IIIError>;
}
```

**Example - Custom Trigger Type:**

```rust theme={null}
use iii_sdk::{III, TriggerHandler, TriggerConfig, IIIError};
use async_trait::async_trait;
use std::sync::Arc;
use tokio::sync::RwLock;

struct IntervalTriggerHandler {
    iii: III,
    active_triggers: Arc<RwLock<Vec<TriggerConfig>>>,
}

impl IntervalTriggerHandler {
    fn new(iii: III) -> Self {
        Self {
            iii,
            active_triggers: Arc::new(RwLock::new(Vec::new())),
        }
    }
}

#[async_trait]
impl TriggerHandler for IntervalTriggerHandler {
    async fn register_trigger(&self, config: TriggerConfig) -> Result<(), IIIError> {
        // Extract interval from config
        let interval_ms = config.config
            .get("interval_ms")
            .and_then(|v| v.as_u64())
            .ok_or_else(|| IIIError::Handler("Missing interval_ms".into()))?;
        
        // Store the trigger
        self.active_triggers.write().await.push(config.clone());
        
        // Spawn a task that invokes the function at intervals
        let iii = self.iii.clone();
        let function_id = config.function_id.clone();
        tokio::spawn(async move {
            let mut interval = tokio::time::interval(
                std::time::Duration::from_millis(interval_ms)
            );
            loop {
                interval.tick().await;
                let _ = iii.trigger_void(&function_id, serde_json::json!({}));
            }
        });
        
        Ok(())
    }
    
    async fn unregister_trigger(&self, config: TriggerConfig) -> Result<(), IIIError> {
        let mut triggers = self.active_triggers.write().await;
        triggers.retain(|t| t.id != config.id);
        Ok(())
    }
}
```

### register\_trigger\_type

Register a custom trigger type handler.

```rust theme={null}
pub fn register_trigger_type<H>(
    &self,
    id: impl Into<String>,
    description: impl Into<String>,
    handler: H,
)
where
    H: TriggerHandler + 'static
```

<ParamField path="id" type="impl Into<String>" required>
  Unique identifier for this trigger type
</ParamField>

<ParamField path="description" type="impl Into<String>" required>
  Human-readable description of the trigger type
</ParamField>

<ParamField path="handler" type="H" required>
  Implementation of TriggerHandler that manages triggers of this type
</ParamField>

**Example:**

```rust theme={null}
let iii = III::new("ws://localhost:49134");

// Register the custom trigger type
let handler = IntervalTriggerHandler::new(iii.clone());
iii.register_trigger_type(
    "interval",
    "Invokes functions at regular intervals",
    handler
);

iii.connect().await?;

// Now others can use this trigger type
let trigger = iii.register_trigger(
    "interval",
    "periodic_task",
    json!({ "interval_ms": 5000 })
)?;
```

### unregister\_trigger\_type

Unregister a trigger type.

```rust theme={null}
pub fn unregister_trigger_type(&self, id: impl Into<String>)
```

<ParamField path="id" type="impl Into<String>" required>
  ID of the trigger type to unregister
</ParamField>

**Example:**

```rust theme={null}
iii.unregister_trigger_type("interval");
```

## Types

### Trigger

Handle to a registered trigger.

```rust theme={null}
pub struct Trigger {
    // Internal fields
}

impl Trigger {
    pub fn unregister(&self);
}
```

### TriggerConfig

Configuration passed to trigger handlers.

```rust theme={null}
pub struct TriggerConfig {
    pub id: String,
    pub function_id: String,
    pub config: Value,
}
```

### TriggerInfo

Information about a registered trigger.

```rust theme={null}
pub struct TriggerInfo {
    pub id: String,
    pub trigger_type: String,
    pub function_id: String,
    pub config: Value,
}
```

## Built-in Trigger Types

The III Engine provides these built-in trigger types:

### HTTP Trigger

Invokes a function when an HTTP request is received.

```rust theme={null}
iii.register_trigger(
    "http",
    "api_handler",
    json!({
        "path": "/api/endpoint",
        "method": "POST"
    })
)?;
```

**Config:**

* `path`: HTTP path (e.g., `/webhook`)
* `method`: HTTP method (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`)

### Cron Trigger

Invokes a function on a schedule.

```rust theme={null}
iii.register_trigger(
    "cron",
    "scheduled_task",
    json!({
        "schedule": "0 */6 * * *"  // Every 6 hours
    })
)?;
```

**Config:**

* `schedule`: Cron expression (standard crontab format)

### Stream Trigger

Invokes a function when stream data is updated.

```rust theme={null}
iii.register_trigger(
    "stream",
    "process_update",
    json!({
        "stream": "events",
        "group": "user-123"
    })
)?;
```

**Config:**

* `stream`: Stream name
* `group`: Optional group ID filter

### Functions Available Trigger

Special trigger that fires when functions are registered/updated.

```rust theme={null}
iii.register_trigger(
    "engine::functions-available",
    "on_functions_updated",
    json!({})
)?;
```

<Note>
  For convenience, use `iii.on_functions_available()` instead of registering this trigger directly.
</Note>

## See Also

* [Functions API](/rust/api/functions) - Register functions that triggers invoke
* [Invocation API](/rust/api/invocation) - Manually invoke functions
* [Context API](/rust/api/context) - Access context within triggered functions
