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)]
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/// Type-specific configuration for triggers
52#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
53#[serde(deny_unknown_fields)]
54#[serde(untagged)]
55pub enum TriggerTypeConfig {
56	/// Slack notification configuration
57	Slack {
58		/// Slack webhook URL
59		slack_url: SecretValue,
60		/// Notification message
61		message: NotificationMessage,
62		/// Retry policy for HTTP requests
63		#[serde(default)]
64		retry_policy: RetryConfig,
65	},
66	/// Email notification configuration
67	Email {
68		/// SMTP host
69		host: String,
70		/// SMTP port (default 465)
71		port: Option<u16>,
72		/// SMTP username
73		username: SecretValue,
74		/// SMTP password
75		password: SecretValue,
76		/// Notification message
77		message: NotificationMessage,
78		/// Email sender
79		sender: EmailAddress,
80		/// Email recipients
81		recipients: Vec<EmailAddress>,
82		/// Retry policy for SMTP requests
83		#[serde(default)]
84		retry_policy: RetryConfig,
85	},
86	/// Webhook configuration
87	Webhook {
88		/// Webhook endpoint URL
89		url: SecretValue,
90		/// HTTP method to use
91		method: Option<String>,
92		/// Secret
93		secret: Option<SecretValue>,
94		/// Optional HTTP headers
95		headers: Option<std::collections::HashMap<String, String>>,
96		/// Notification message
97		message: NotificationMessage,
98		/// Retry policy for HTTP requests
99		#[serde(default)]
100		retry_policy: RetryConfig,
101	},
102	/// Telegram notification configuration
103	Telegram {
104		/// Telegram bot token
105		token: SecretValue,
106		/// Telegram chat ID
107		chat_id: String,
108		/// Disable web preview
109		disable_web_preview: Option<bool>,
110		/// Notification message
111		message: NotificationMessage,
112		/// Retry policy for HTTP requests
113		#[serde(default)]
114		retry_policy: RetryConfig,
115	},
116	/// Discord notification configuration
117	Discord {
118		/// Discord webhook URL
119		discord_url: SecretValue,
120		/// Notification message
121		message: NotificationMessage,
122		/// Retry policy for HTTP requests
123		#[serde(default)]
124		retry_policy: RetryConfig,
125	},
126	/// Script execution configuration
127	Script {
128		/// Language of the script
129		language: ScriptLanguage,
130		/// Path to script file
131		script_path: String,
132		/// Command line arguments
133		#[serde(default)]
134		arguments: Option<Vec<String>>,
135		/// Timeout in milliseconds
136		timeout_ms: u32,
137	},
138}
139
140impl TriggerTypeConfig {
141	/// Get the retry policy for the trigger type, if applicable.
142	pub fn get_retry_policy(&self) -> Option<RetryConfig> {
143		match self {
144			Self::Slack { retry_policy, .. } => Some(retry_policy.clone()),
145			Self::Discord { retry_policy, .. } => Some(retry_policy.clone()),
146			Self::Webhook { retry_policy, .. } => Some(retry_policy.clone()),
147			Self::Telegram { retry_policy, .. } => Some(retry_policy.clone()),
148			_ => None,
149		}
150	}
151}