Skip to main content

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.

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.
pub fn register_trigger(
    &self,
    trigger_type: impl Into<String>,
    function_id: impl Into<String>,
    config: impl serde::Serialize,
) -> Result<Trigger, IIIError>
trigger_type
impl Into<String>
required
Type of trigger (e.g., “http”, “cron”, “stream”)
function_id
impl Into<String>
required
ID of the function to invoke when triggered
config
impl serde::Serialize
required
Configuration specific to the trigger type (serialized to JSON)
Trigger
Result<Trigger, IIIError>
Trigger handle that can be used to unregister
Example - HTTP Trigger:
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:
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:
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:
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.
pub async fn list_triggers(&self) -> Result<Vec<TriggerInfo>, IIIError>
Vec<TriggerInfo>
Result<Vec<TriggerInfo>, IIIError>
List of all registered triggers
Example:
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.
#[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:
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.
pub fn register_trigger_type<H>(
    &self,
    id: impl Into<String>,
    description: impl Into<String>,
    handler: H,
)
where
    H: TriggerHandler + 'static
id
impl Into<String>
required
Unique identifier for this trigger type
description
impl Into<String>
required
Human-readable description of the trigger type
handler
H
required
Implementation of TriggerHandler that manages triggers of this type
Example:
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.
pub fn unregister_trigger_type(&self, id: impl Into<String>)
id
impl Into<String>
required
ID of the trigger type to unregister
Example:
iii.unregister_trigger_type("interval");

Types

Trigger

Handle to a registered trigger.
pub struct Trigger {
    // Internal fields
}

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

TriggerConfig

Configuration passed to trigger handlers.
pub struct TriggerConfig {
    pub id: String,
    pub function_id: String,
    pub config: Value,
}

TriggerInfo

Information about a registered trigger.
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.
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.
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.
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.
iii.register_trigger(
    "engine::functions-available",
    "on_functions_updated",
    json!({})
)?;
For convenience, use iii.on_functions_available() instead of registering this trigger directly.

See Also

Build docs developers (and LLMs) love