use std::collections::HashMap;
use std::time::Duration;
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 PUSHOVER_HTTP_CLIENT: Client = Client::builder()
.timeout(Duration::from_secs(DISPATCH_TIMEOUT_SECONDS))
.gzip(true)
.build()
.unwrap();
}
static PUSHOVER_API_URL: &'static str = "https://api.pushover.net/1/messages.json";
pub struct PushoverNotifier;
impl GenericNotifier for PushoverNotifier {
fn attempt(notify: &ConfigNotify, notification: &Notification) -> Result<(), bool> {
if let Some(ref pushover) = notify.pushover {
let mut message = String::new();
if notification.startup == true {
message.push_str("<b><i>This is a startup alert.</i></b>\n\n");
} else if notification.changed == false {
message.push_str("<b><i>This is a reminder.</i></b>\n\n");
}
message.push_str(&format!(
"<u>Status:</u> <b><font color=\"{}\">{}</font></b>\n",
status_to_color(¬ification.status),
notification.status.as_str().to_uppercase()
));
message.push_str(&format!(
"<u>Nodes:</u> {}\n",
¬ification.replicas.join(", ")
));
message.push_str(&format!("<u>Time:</u> {}", ¬ification.time));
debug!("will send Pushover notification with message: {}", &message);
let mut has_sub_delivery_failure = false;
for (user_index, user_key) in pushover.user_keys.iter().enumerate() {
let mut params: HashMap<&str, &str> = HashMap::new();
params.insert("token", &pushover.app_token);
params.insert("user", user_key);
params.insert("title", &APP_CONF.branding.page_title);
params.insert("message", &message);
params.insert("html", "1");
let url_title = format!("Details on {}", APP_CONF.branding.page_title);
params.insert("url_title", &url_title);
params.insert("url", APP_CONF.branding.page_url.as_str());
if notification.escalated_for(user_index) == true {
params.insert("priority", "1");
}
let response = PUSHOVER_HTTP_CLIENT
.post(PUSHOVER_API_URL)
.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(());
}
Err(false)
}
fn can_notify(notify: &ConfigNotify, notification: &Notification) -> bool {
if let Some(ref pushover_config) = notify.pushover {
notification.expected(pushover_config.reminders_only)
} else {
false
}
}
fn name() -> &'static str {
"pushover"
}
}
fn status_to_color(status: &Status) -> &'static str {
match status {
&Status::Healthy => "#54A158",
&Status::Sick => "#D5A048",
&Status::Dead => "#C4291C",
}
}