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 allow functions to be invoked automatically when certain events occur. The III SDK provides types for configuring triggers and implementing trigger handlers.
TriggerConfig
Configuration passed to a trigger handler when a trigger is registered.
type TriggerConfig<TConfig> = {
id: string
function_id: string
config: TConfig
}
class TriggerConfig(BaseModel, Generic[TConfig]):
id: str
function_id: str
config: Any # TConfig
pub struct TriggerConfig {
pub id: String,
pub function_id: String,
pub config: Value,
}
Fields
Unique identifier for this trigger instance.
The function to invoke when the trigger fires.
Custom configuration specific to this trigger type.
TriggerHandler
Interface for implementing custom trigger types.
type TriggerHandler<TConfig> = {
registerTrigger(config: TriggerConfig<TConfig>): Promise<void>
unregisterTrigger(config: TriggerConfig<TConfig>): Promise<void>
}
class TriggerHandler(ABC, Generic[TConfig]):
@abstractmethod
async def register_trigger(self, config: TriggerConfig[TConfig]) -> None:
pass
@abstractmethod
async def unregister_trigger(self, config: TriggerConfig[TConfig]) -> None:
pass
#[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>;
}
Methods
Called when a trigger of this type is registered. Should set up the necessary resources or listeners.
Called when a trigger is unregistered. Should clean up resources and stop listeners.
RegisterTriggerMessage
Message format for registering a trigger with the engine.
type RegisterTriggerMessage = {
message_type: MessageType.RegisterTrigger
id: string
type: string
function_id: string
config: unknown
}
class RegisterTriggerMessage(BaseModel):
id: str
trigger_type: str
function_id: str
config: Any
message_type: MessageType = MessageType.REGISTER_TRIGGER
pub struct RegisterTriggerMessage {
pub id: String,
pub trigger_type: String,
pub function_id: String,
pub config: Value,
}
Fields
Unique identifier for this trigger instance (auto-generated).
The trigger type identifier (e.g., "http", "cron", "custom::event").
The function to invoke when this trigger fires.
Configuration specific to the trigger type.
Example: Custom Trigger Type
type TimerConfig = {
interval_ms: number
}
const timerHandler: TriggerHandler<TimerConfig> = {
async registerTrigger(config) {
const timer = setInterval(async () => {
await iii.trigger(config.function_id, { timestamp: Date.now() })
}, config.config.interval_ms)
// Store timer for cleanup
timers.set(config.id, timer)
},
async unregisterTrigger(config) {
const timer = timers.get(config.id)
if (timer) {
clearInterval(timer)
timers.delete(config.id)
}
}
}
iii.registerTriggerType(
{ id: 'timer', description: 'Periodic timer trigger' },
timerHandler
)
from dataclasses import dataclass
@dataclass
class TimerConfig:
interval_ms: int
class TimerHandler(TriggerHandler[TimerConfig]):
def __init__(self, iii):
self.iii = iii
self.tasks = {}
async def register_trigger(self, config: TriggerConfig[TimerConfig]) -> None:
async def periodic_trigger():
while True:
await asyncio.sleep(config.config.interval_ms / 1000)
await self.iii.trigger(config.function_id, {"timestamp": time.time()})
task = asyncio.create_task(periodic_trigger())
self.tasks[config.id] = task
async def unregister_trigger(self, config: TriggerConfig[TimerConfig]) -> None:
task = self.tasks.pop(config.id, None)
if task:
task.cancel()
iii.register_trigger_type(
'timer',
'Periodic timer trigger',
TimerHandler(iii)
)
use async_trait::async_trait;
struct TimerHandler {
iii: III,
tasks: Arc<Mutex<HashMap<String, JoinHandle<()>>>>,
}
#[async_trait]
impl TriggerHandler for TimerHandler {
async fn register_trigger(&self, config: TriggerConfig) -> Result<(), IIIError> {
let interval_ms = config.config.get("interval_ms")
.and_then(|v| v.as_u64())
.ok_or(IIIError::InvalidConfig)?;
let iii = self.iii.clone();
let function_id = config.function_id.clone();
let task = tokio::spawn(async move {
let mut interval = tokio::time::interval(
Duration::from_millis(interval_ms)
);
loop {
interval.tick().await;
let _ = iii.trigger(&function_id, json!({ "timestamp": now() })).await;
}
});
self.tasks.lock().await.insert(config.id.clone(), task);
Ok(())
}
async fn unregister_trigger(&self, config: TriggerConfig) -> Result<(), IIIError> {
if let Some(task) = self.tasks.lock().await.remove(&config.id) {
task.abort();
}
Ok(())
}
}
iii.register_trigger_type(
"timer",
"Periodic timer trigger",
TimerHandler { iii: iii.clone(), tasks: Arc::new(Mutex::new(HashMap::new())) }
);