Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mailgun notifications feature #64

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down Expand Up @@ -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]]**
Expand Down
9 changes: 9 additions & 0 deletions config.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "[email protected]"
to = [
"[email protected]",
"[email protected]"
]

[probe]

[[probe.service]]
Expand Down
6 changes: 6 additions & 0 deletions src/aggregator/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -310,6 +313,9 @@ fn notify(bumped_states: &BumpedStates) {

#[cfg(feature = "notifier-webhook")]
Notification::dispatch::<WebHookNotifier>(notify, &notification).ok();

#[cfg(feature = "notifier-mailgun")]
Notification::dispatch::<MailgunNotifier>(notify, &notification).ok();
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/config/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ pub struct ConfigNotify {
pub pushover: Option<ConfigNotifyPushover>,
pub xmpp: Option<ConfigNotifyXMPP>,
pub webhook: Option<ConfigNotifyWebHook>,
pub mailgun: Option<ConfigNotifyMailgun>,
}

#[derive(Deserialize)]
Expand Down Expand Up @@ -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<String>,
pub from: String,
}

#[derive(Deserialize)]
pub struct ConfigProbe {
pub service: Vec<ConfigProbeService>,
Expand Down
114 changes: 114 additions & 0 deletions src/notifier/mailgun.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Vigil
//
// Microservices Status Page
// Copyright: 2019, Valerian Saliou <[email protected]>
// 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", &notification.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(&params)
.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"
}
}
3 changes: 3 additions & 0 deletions src/notifier/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ pub mod xmpp;

#[cfg(feature = "notifier-webhook")]
pub mod webhook;

#[cfg(feature = "notifier-mailgun")]
pub mod mailgun;