use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum WebhookVersion {
V1,
V2,
V3,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TriggerEvent {
pub id: String,
pub uuid: String,
pub user_id: String,
pub toolkit_slug: String,
pub trigger_slug: String,
pub metadata: TriggerMetadata,
#[serde(skip_serializing_if = "Option::is_none")]
pub payload: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub original_payload: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TriggerMetadata {
pub id: String,
pub uuid: String,
pub toolkit_slug: String,
pub trigger_slug: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub trigger_data: Option<String>,
pub trigger_config: serde_json::Value,
pub connected_account: TriggerConnectedAccount,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TriggerConnectedAccount {
pub id: String,
pub uuid: String,
pub auth_config_id: String,
pub auth_config_uuid: String,
pub user_id: String,
pub status: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VerifyWebhookResult {
pub version: WebhookVersion,
pub payload: TriggerEvent,
pub raw_payload: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TriggerType {
pub slug: String,
pub name: String,
pub description: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub instructions: Option<String>,
#[serde(rename = "type")]
pub trigger_type: String,
pub toolkit: TriggerToolkitRef,
pub config: serde_json::Value,
pub payload: serde_json::Value,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TriggerToolkitRef {
pub slug: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub logo: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TriggerInstance {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub uuid: Option<String>,
pub trigger_name: String,
pub connected_account_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_id: Option<String>,
pub trigger_config: serde_json::Value,
#[serde(skip_serializing_if = "Option::is_none")]
pub state: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub disabled_at: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct TriggerTypeRetrieveParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub toolkit_versions: Option<String>,
}
pub type TriggerTypeRetrieveEnumResponse = Vec<String>;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct TriggerTypeListParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub cursor: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub toolkit_slugs: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub toolkit_versions: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TriggerTypeListResponse {
pub items: Vec<TriggerType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_pages: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub current_page: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_items: Option<u32>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct TriggerInstanceListParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub trigger_ids: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub trigger_names: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub auth_config_ids: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub connected_account_ids: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub show_disabled: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TriggerInstanceListResponse {
pub items: Vec<TriggerInstance>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_pages: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub current_page: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_items: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TriggerCreateParams {
pub slug: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub connected_account_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub trigger_config: Option<HashMap<String, serde_json::Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub toolkit_versions: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TriggerCreateResponse {
pub id: String,
pub trigger_name: String,
pub connected_account_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_id: Option<String>,
pub trigger_config: serde_json::Value,
#[serde(skip_serializing_if = "Option::is_none")]
pub state: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WebhookVerifyParams {
pub id: String,
pub payload: String,
pub secret: String,
pub signature: String,
pub timestamp: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub tolerance: Option<u32>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_webhook_version_serialization() {
let v1 = WebhookVersion::V1;
let json = serde_json::to_string(&v1).unwrap();
assert_eq!(json, "\"V1\"");
let v3 = WebhookVersion::V3;
let json = serde_json::to_string(&v3).unwrap();
assert_eq!(json, "\"V3\"");
}
#[test]
fn test_trigger_type_retrieve_params_serialization() {
let params = TriggerTypeRetrieveParams {
toolkit_versions: Some("latest".to_string()),
};
let value = serde_json::to_value(¶ms).unwrap();
assert_eq!(value["toolkit_versions"], "latest");
}
#[test]
fn test_trigger_type_retrieve_enum_response_deserialization() {
let payload = serde_json::json!(["GITHUB_COMMIT_EVENT", "SLACK_NEW_MESSAGE"]);
let response: TriggerTypeRetrieveEnumResponse = serde_json::from_value(payload).unwrap();
assert_eq!(response.len(), 2);
assert_eq!(response[0], "GITHUB_COMMIT_EVENT");
}
#[test]
fn test_trigger_type_list_params_default() {
let params = TriggerTypeListParams::default();
assert!(params.cursor.is_none());
assert!(params.limit.is_none());
assert!(params.toolkit_slugs.is_none());
}
#[test]
fn test_trigger_instance_list_params_default() {
let params = TriggerInstanceListParams::default();
assert!(params.trigger_ids.is_none());
assert!(params.trigger_names.is_none());
assert!(params.show_disabled.is_none());
}
#[test]
fn test_trigger_event_deserialization() {
let json = r#"{
"id": "ti_123",
"uuid": "uuid_123",
"user_id": "user_456",
"toolkit_slug": "github",
"trigger_slug": "GITHUB_COMMIT_EVENT",
"metadata": {
"id": "ti_123",
"uuid": "uuid_123",
"toolkit_slug": "github",
"trigger_slug": "GITHUB_COMMIT_EVENT",
"trigger_data": null,
"trigger_config": {},
"connected_account": {
"id": "ca_789",
"uuid": "ca_uuid_789",
"auth_config_id": "ac_101",
"auth_config_uuid": "ac_uuid_101",
"user_id": "user_456",
"status": "ACTIVE"
}
},
"payload": {"test": "data"},
"original_payload": null
}"#;
let event: TriggerEvent = serde_json::from_str(json).unwrap();
assert_eq!(event.id, "ti_123");
assert_eq!(event.user_id, "user_456");
assert_eq!(event.trigger_slug, "GITHUB_COMMIT_EVENT");
assert_eq!(event.metadata.connected_account.id, "ca_789");
}
#[test]
fn test_trigger_create_params() {
let params = TriggerCreateParams {
slug: "GITHUB_COMMIT_EVENT".to_string(),
connected_account_id: Some("ca_123".to_string()),
user_id: None,
trigger_config: Some(HashMap::from([
("repo".to_string(), serde_json::json!("composio")),
("owner".to_string(), serde_json::json!("composio")),
])),
toolkit_versions: None,
};
assert_eq!(params.slug, "GITHUB_COMMIT_EVENT");
assert!(params.connected_account_id.is_some());
assert!(params.trigger_config.is_some());
}
}