diff --git a/Cargo.toml b/Cargo.toml index 5a9954c..ee2543f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,13 +46,14 @@ lettre_email = { version = "0.9", optional = true } libstrophe = { version = "0.13", default-features = false, optional = true } [features] -default = ["notifier-email", "notifier-twilio", "notifier-slack", "notifier-telegram", "notifier-pushover", "notifier-webhook"] +default = ["notifier-email", "notifier-twilio", "notifier-slack", "notifier-telegram", "notifier-pushover", "notifier-webhook", "notifier-mailgun"] notifier-email = ["lettre", "lettre_email"] notifier-twilio = [] notifier-slack = [] notifier-telegram = [] notifier-pushover = [] notifier-webhook = [] +notifier-mailgun = [] notifier-xmpp = ["libstrophe"] [profile.dev] diff --git a/README.md b/README.md index bbc4baa..fc10239 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ _👋 You use Vigil and you want to be listed there? [Contact me](https://valeri * Pushover * XMPP * Webhook + *Mailgun * **Generates a status page**, that you can host on your domain for your public users (eg. `https://status.example.com`) ## How does it work? @@ -240,6 +241,12 @@ Use the sample [config.cfg](https://github.com/valeriansaliou/vigil/blob/master/ * `hook_url` (type: _string_, allowed: URL, no default) — Web Hook URL (eg. `https://domain.com/webhooks/[..]`) +**[notify.mailgun]** +* `api_key` (type: _string_, allowed: any string, no default) - Your api key +* `api_url` (type: _array[string]_, allowed: URL, no default) - Your api url (eg. `https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages`) +* `to` (type: _string_, allowed: email address, no default) — Email address to which to send emails +* `from` (type: _string_, allowed: email address, no default) — Email address from which to send emails + **[probe]** **[[probe.service]]** diff --git a/config.cfg b/config.cfg index 9d5ef81..445900b 100644 --- a/config.cfg +++ b/config.cfg @@ -118,6 +118,15 @@ xmpp_password = "xmpp-password" hook_url = "https://domain.com/webhooks/xxxx" +[notify.mailgun] +api_key ="YOUR_KEY" +api_url = "https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages" +from = "exemple@domain.com" +to = [ + "exemple@mail.com", + "other@mail.com" +] + [probe] [[probe.service]] diff --git a/src/aggregator/manager.rs b/src/aggregator/manager.rs index 71b448c..5476ac8 100644 --- a/src/aggregator/manager.rs +++ b/src/aggregator/manager.rs @@ -36,6 +36,9 @@ use crate::notifier::xmpp::XMPPNotifier; #[cfg(feature = "notifier-webhook")] use crate::notifier::webhook::WebHookNotifier; +#[cfg(feature = "notifier-mailgun")] +use crate::notifier::mailgun::MailgunNotifier; + const AGGREGATE_INTERVAL_SECONDS: u64 = 10; struct BumpedStates { @@ -310,6 +313,9 @@ fn notify(bumped_states: &BumpedStates) { #[cfg(feature = "notifier-webhook")] Notification::dispatch::(notify, ¬ification).ok(); + + #[cfg(feature = "notifier-mailgun")] + Notification::dispatch::(notify, ¬ification).ok(); } } diff --git a/src/config/config.rs b/src/config/config.rs index 7c793c0..0e36c10 100644 --- a/src/config/config.rs +++ b/src/config/config.rs @@ -109,6 +109,7 @@ pub struct ConfigNotify { pub pushover: Option, pub xmpp: Option, pub webhook: Option, + pub mailgun: Option, } #[derive(Deserialize)] @@ -205,6 +206,14 @@ pub struct ConfigNotifyWebHook { pub hook_url: SerdeUrl, } +#[derive(Deserialize)] +pub struct ConfigNotifyMailgun { + pub api_url: SerdeUrl, + pub api_key: String, + pub to: Vec, + pub from: String, +} + #[derive(Deserialize)] pub struct ConfigProbe { pub service: Vec, diff --git a/src/notifier/mailgun.rs b/src/notifier/mailgun.rs new file mode 100644 index 0000000..b8d23a1 --- /dev/null +++ b/src/notifier/mailgun.rs @@ -0,0 +1,114 @@ +// Vigil +// +// Microservices Status Page +// Copyright: 2019, Valerian Saliou +// License: Mozilla Public License v2.0 (MPL v2.0) + +use std::time::Duration; +use std::collections::HashMap; + +use reqwest::blocking::Client; + +use super::generic::{GenericNotifier, Notification, DISPATCH_TIMEOUT_SECONDS}; +use crate::config::config::ConfigNotify; +// use crate::prober::status::Status; +use crate::APP_CONF; + +lazy_static! { + static ref MAILGUN_HTTP_CLIENT: Client = Client::builder() + .timeout(Duration::from_secs(DISPATCH_TIMEOUT_SECONDS)) + .gzip(true) + .build() + .unwrap(); +} + +pub struct MailgunNotifier; + +impl GenericNotifier for MailgunNotifier { + fn attempt(notify: &ConfigNotify, notification: &Notification) -> Result<(), bool> { + if let Some(ref mailgun) = notify.mailgun { + + let nodes_label = notification.replicas.join("\n, "); + let mut message = String::new(); + if notification.startup == true { + message.push_str(&format!( + "Status startup alert from: {}\n", + APP_CONF.branding.page_title + )); + } else if notification.changed == true { + message.push_str(&format!( + "Status change report from: {}\n", + APP_CONF.branding.page_title + )); + } else { + message.push_str(&format!( + "Status unchanged reminder from: {}\n", + APP_CONF.branding.page_title + )); + } + + message.push_str("\n--\n"); + message.push_str(&format!("Status: {:?}\n", notification.status)); + message.push_str(&format!("Nodes: {}\n", &nodes_label)); + message.push_str(&format!("Time: {}\n", ¬ification.time)); + message.push_str(&format!("URL: {}", APP_CONF.branding.page_url.as_str())); + + message.push_str("\n--\n"); + message.push_str("\n"); + message.push_str("To unsubscribe, please edit your status page configuration."); + + debug!("will send email notification with message: {}", &message); + + // Submit payload to Web Hooks + let mut sender = String::new(); + sender.push_str(&format!("KKiaPay Status : {}", mailgun.from)); + let mut subject = String::new(); + subject.push_str(&format!( + "{}", + notification.status.as_str().to_uppercase() + )); + let mut has_sub_delivery_failure = false; + + for to_email in &mailgun.to { + // Build form parameters + let mut params = HashMap::new(); + params.insert("from", &sender); + params.insert("to", to_email); + params.insert("subject", &subject); + params.insert("text", &message); + + let response = MAILGUN_HTTP_CLIENT + .post(mailgun.api_url.as_str()) + .basic_auth("api", Some(&mailgun.api_key)) + .form(¶ms) + .send(); + + if let Ok(response_inner) = response { + if response_inner.status().is_success() != true { + has_sub_delivery_failure = true; + + } + } else { + has_sub_delivery_failure = true; + } + } + if has_sub_delivery_failure == true { + return Err(true); + } + return Ok(()); + + + // return Err(true); + } + + Err(false) + } + + fn can_notify(notify: &ConfigNotify, _: &Notification) -> bool { + notify.mailgun.is_some() + } + + fn name() -> &'static str { + "mailgun" + } +} diff --git a/src/notifier/mod.rs b/src/notifier/mod.rs index a78b73e..fc180b8 100644 --- a/src/notifier/mod.rs +++ b/src/notifier/mod.rs @@ -26,3 +26,6 @@ pub mod xmpp; #[cfg(feature = "notifier-webhook")] pub mod webhook; + +#[cfg(feature = "notifier-mailgun")] +pub mod mailgun;