openzeppelin_monitor/models/core/
trigger.rs

1use crate::{
2	models::{core::ScriptLanguage, SecretValue},
3	utils::RetryConfig,
4};
5use email_address::EmailAddress;
6use serde::{Deserialize, Serialize};
7
8/// Configuration for actions to take when monitored conditions are met.
9#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
10#[serde(deny_unknown_fields)]
11pub struct Trigger {
12	/// Unique name identifying this trigger
13	pub name: String,
14
15	/// Type of trigger (Email, Slack, Webhook, Telegram, Discord, Script)
16	pub trigger_type: TriggerType,
17
18	/// Configuration specific to the trigger type
19	pub config: TriggerTypeConfig,
20}
21
22/// Supported trigger action types
23#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
24#[serde(rename_all = "lowercase")]
25#[serde(deny_unknown_fields)]
26pub enum TriggerType {
27	/// Send notification to Slack
28	Slack,
29	/// Send notification to email
30	Email,
31	/// Make HTTP request to webhook
32	Webhook,
33	/// Send notification to Telegram
34	Telegram,
35	/// Send notification to Discord
36	Discord,
37	/// Execute local script
38	Script,
39}
40
41/// Notification message fields
42#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Default)]
43#[serde(deny_unknown_fields)]
44pub struct NotificationMessage {
45	/// Notification title or subject
46	pub title: String,
47	/// Message template
48	pub body: String,
49}
50
51/// Payload mode for webhook triggers
52#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Default)]
53#[serde(rename_all = "lowercase")]
54pub enum WebhookPayloadMode {
55	/// Use title/body templates with variable substitution (default)
56	#[default]
57	Template,
58	/// Send the raw MonitorMatch as the JSON payload
59	Raw,
60}
61
62/// Type-specific configuration for triggers
63#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
64#[serde(deny_unknown_fields)]
65#[serde(untagged)]
66pub enum TriggerTypeConfig {
67	/// Slack notification configuration
68	Slack {
69		/// Slack webhook URL
70		slack_url: SecretValue,
71		/// Notification message
72		message: NotificationMessage,
73		/// Retry policy for HTTP requests
74		#[serde(default)]
75		retry_policy: RetryConfig,
76	},
77	/// Email notification configuration
78	Email {
79		/// SMTP host
80		host: String,
81		/// SMTP port (default 465)
82		port: Option<u16>,
83		/// SMTP username
84		username: SecretValue,
85		/// SMTP password
86		password: SecretValue,
87		/// Notification message
88		message: NotificationMessage,
89		/// Email sender
90		sender: EmailAddress,
91		/// Email recipients
92		recipients: Vec<EmailAddress>,
93		/// Retry policy for SMTP requests
94		#[serde(default)]
95		retry_policy: RetryConfig,
96	},
97	/// Webhook configuration
98	Webhook {
99		/// Webhook endpoint URL
100		url: SecretValue,
101		/// HTTP method to use
102		method: Option<String>,
103		/// Secret
104		secret: Option<SecretValue>,
105		/// Optional HTTP headers
106		headers: Option<std::collections::HashMap<String, String>>,
107		/// Notification message (required for template mode, optional for raw mode)
108		#[serde(default)]
109		message: NotificationMessage,
110		/// Payload mode: "template" (default) or "raw"
111		#[serde(default)]
112		payload_mode: WebhookPayloadMode,
113		/// Retry policy for HTTP requests
114		#[serde(default)]
115		retry_policy: RetryConfig,
116	},
117	/// Telegram notification configuration
118	Telegram {
119		/// Telegram bot token
120		token: SecretValue,
121		/// Telegram chat ID
122		chat_id: String,
123		/// Disable web preview
124		disable_web_preview: Option<bool>,
125		/// Notification message
126		message: NotificationMessage,
127		/// Retry policy for HTTP requests
128		#[serde(default)]
129		retry_policy: RetryConfig,
130	},
131	/// Discord notification configuration
132	Discord {
133		/// Discord webhook URL
134		discord_url: SecretValue,
135		/// Notification message
136		message: NotificationMessage,
137		/// Retry policy for HTTP requests
138		#[serde(default)]
139		retry_policy: RetryConfig,
140	},
141	/// Script execution configuration
142	Script {
143		/// Language of the script
144		language: ScriptLanguage,
145		/// Path to script file
146		script_path: String,
147		/// Command line arguments
148		#[serde(default)]
149		arguments: Option<Vec<String>>,
150		/// Timeout in milliseconds
151		timeout_ms: u32,
152	},
153}
154
155impl TriggerTypeConfig {
156	/// Get the retry policy for the trigger type, if applicable.
157	pub fn get_retry_policy(&self) -> Option<RetryConfig> {
158		match self {
159			Self::Slack { retry_policy, .. } => Some(retry_policy.clone()),
160			Self::Discord { retry_policy, .. } => Some(retry_policy.clone()),
161			Self::Webhook { retry_policy, .. } => Some(retry_policy.clone()),
162			Self::Telegram { retry_policy, .. } => Some(retry_policy.clone()),
163			_ => None,
164		}
165	}
166}