/*
* Zernio API
*
* API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api
*
* The version of the OpenAPI document: 1.0.4
* Contact: support@zernio.com
* Generated by: https://openapi-generator.tech
*/
use crate::models;
use serde::{Deserialize, Serialize};
/// WorkflowNode : A node in a workflow graph. `config` shape depends on `type`.
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct WorkflowNode {
/// Stable node id referenced by edges
#[serde(rename = "id")]
pub id: String,
/// Node kind. The 16 supported types break into four groups: messaging (send_message), control flow (trigger, condition, delay, wait_for_reply, a_b_split, end), data ops (set_variable, set_field, add_tag, remove_tag, enroll_sequence), integrations (webhook, ai, handoff, start_call).
#[serde(rename = "type")]
pub r#type: Type,
/// Type-specific settings. All string fields support `{{variable}}` interpolation against the run's variable bag (resolved at execution time). **trigger**: `{ triggerType: inbound_message|api_call|whatsapp_event, keywords:[string], matchType: any|contains|exact|regex, onlyFirstMessage:boolean, eventType: message_sent|message_delivered|message_read|message_failed|reaction }`. Default `triggerType` is `inbound_message` for legacy nodes. `eventType` is only honored when `triggerType` is `whatsapp_event` (WhatsApp-only). **send_message**: `{ messageType: text|template|media|interactive, text, template:{name,language,variableMapping}, media:{mediaType:image|video|audio|document, url,caption}, interactive }`. `template` and `interactive` are WhatsApp-only. **wait_for_reply**: `{ timeoutMinutes:int (max 43200), saveAs:string }`. Resume via the `'reply'` edge on inbound, or `'timeout'` edge after `timeoutMinutes` of silence. **condition**: `{ rules:[{ id, variable, operator: equals|not_equals|contains|not_contains|starts_with|ends_with|exists|not_exists|matches, value }] }`. First matching rule takes its `id` as the sourceHandle; otherwise `'default'`. **set_variable**: `{ assignments:[{ name, value }] }`. Run-scoped (lives only for this execution; use `set_field` for persistent values). **delay**: `{ delayMinutes:int (max 43200) }`. Suspends the run, resumes via timer. **webhook**: `{ url, method: GET|POST|PUT|PATCH|DELETE, headers, bodyTemplate, saveAs }`. SSRF-guarded (private/loopback/metadata IPs rejected). Response saved as `{ status, ok, body }` to `vars[saveAs]`. Edge: `'success'` on 2xx, `'error'` otherwise. **ai**: `{ provider: anthropic|openai|google|mistral|groq, model, preset: smart|tools|cheap, systemPrompt, userPromptTemplate, saveAs, temperature, maxTokens, outputType: text|json, tools:[{ name, description, parameters }] }`. Set `provider` + `model` for BYOK (uses your stored API key); omit `provider` for the legacy Telnyx path. Edges: `'success'`, `'tool:<name>'` (model picked a tool), `'error'`. **handoff**: `{ note, assignTo }`. Terminates the run as `exited`, flags the conversation for a human operator. **start_call**: `{ to, forwardTo, requirePermissionFirst, recordingEnabled, saveAs }`. WhatsApp-only. `forwardTo` can be `tel:+E164`, `sip:user@host`, or `wss://…` (AI voice agent). Edges: `'success'`, `'permission_required'`, `'failed'`. **a_b_split**: `{ percentage: number 0-100 (default 50) }`. Random branch picker. Edges: `'a'` (with probability `percentage/100`), `'b'`. **set_field**: `{ field, value }`. Persistent custom field on the Contact (vs `set_variable` which is run-scoped). Field name is sanitized to `[A-Za-z0-9_]`. No-op on `api_call` runs (no contact). **enroll_sequence**: `{ sequenceId, saveAs }`. Enrolls the run's contact into a Sequence. Edges: `'success'`, `'error'`. **add_tag** / **remove_tag**: `{ tag }`. Push or pull a tag on the Contact. No-op on `api_call` runs. **end**: no config. Terminates the run as `completed`.
#[serde(rename = "config", skip_serializing_if = "Option::is_none")]
pub config: Option<std::collections::HashMap<String, serde_json::Value>>,
#[serde(rename = "position", skip_serializing_if = "Option::is_none")]
pub position: Option<Box<models::WorkflowNodePosition>>,
}
impl WorkflowNode {
/// A node in a workflow graph. `config` shape depends on `type`.
pub fn new(id: String, r#type: Type) -> WorkflowNode {
WorkflowNode {
id,
r#type,
config: None,
position: None,
}
}
}
/// Node kind. The 16 supported types break into four groups: messaging (send_message), control flow (trigger, condition, delay, wait_for_reply, a_b_split, end), data ops (set_variable, set_field, add_tag, remove_tag, enroll_sequence), integrations (webhook, ai, handoff, start_call).
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Type {
#[serde(rename = "trigger")]
Trigger,
#[serde(rename = "send_message")]
SendMessage,
#[serde(rename = "wait_for_reply")]
WaitForReply,
#[serde(rename = "condition")]
Condition,
#[serde(rename = "set_variable")]
SetVariable,
#[serde(rename = "delay")]
Delay,
#[serde(rename = "webhook")]
Webhook,
#[serde(rename = "ai")]
Ai,
#[serde(rename = "handoff")]
Handoff,
#[serde(rename = "start_call")]
StartCall,
#[serde(rename = "a_b_split")]
ABSplit,
#[serde(rename = "set_field")]
SetField,
#[serde(rename = "enroll_sequence")]
EnrollSequence,
#[serde(rename = "add_tag")]
AddTag,
#[serde(rename = "remove_tag")]
RemoveTag,
#[serde(rename = "end")]
End,
}
impl Default for Type {
fn default() -> Type {
Self::Trigger
}
}