Generalize notification handling

This commit is contained in:
Michael Vines
2021-01-19 09:20:25 -08:00
parent dcaa025822
commit 332371635d

View File

@ -75,12 +75,16 @@ fn get_twilio_config() -> Result<Option<TwilioWebHook>, String> {
Ok(Some(config))
}
enum NotificationType {
Discord(String),
Slack(String),
Telegram(TelegramWebHook),
Twilio(TwilioWebHook),
}
pub struct Notifier {
client: Client,
discord_webhook: Option<String>,
slack_webhook: Option<String>,
telegram_webhook: Option<TelegramWebHook>,
twilio_webhook: Option<TwilioWebHook>,
notifiers: Vec<NotificationType>,
}
impl Notifier {
@ -91,41 +95,45 @@ impl Notifier {
pub fn new(env_prefix: &str) -> Self {
info!("Initializing {}Notifier", env_prefix);
let discord_webhook = env::var(format!("{}DISCORD_WEBHOOK", env_prefix))
.map_err(|_| {
info!("Discord notifications disabled");
})
.ok();
let slack_webhook = env::var(format!("{}SLACK_WEBHOOK", env_prefix))
.map_err(|_| {
info!("Slack notifications disabled");
})
.ok();
let mut notifiers = vec![];
let telegram_webhook = if let (Ok(bot_token), Ok(chat_id)) = (
if let Ok(webhook) = env::var(format!("{}DISCORD_WEBHOOK", env_prefix)) {
notifiers.push(NotificationType::Discord(webhook));
}
if let Ok(webhook) = env::var(format!("{}SLACK_WEBHOOK", env_prefix)) {
notifiers.push(NotificationType::Slack(webhook));
}
if let (Ok(bot_token), Ok(chat_id)) = (
env::var(format!("{}TELEGRAM_BOT_TOKEN", env_prefix)),
env::var(format!("{}TELEGRAM_CHAT_ID", env_prefix)),
) {
Some(TelegramWebHook { bot_token, chat_id })
} else {
info!("Telegram notifications disabled");
None
};
let twilio_webhook = get_twilio_config()
.map_err(|err| panic!("Twilio config error: {}", err))
.unwrap();
notifiers.push(NotificationType::Telegram(TelegramWebHook {
bot_token,
chat_id,
}));
}
if let Ok(Some(webhook)) = get_twilio_config() {
notifiers.push(NotificationType::Twilio(webhook));
}
info!("{} notifiers", notifiers.len());
Notifier {
client: Client::new(),
discord_webhook,
slack_webhook,
telegram_webhook,
twilio_webhook,
notifiers,
}
}
pub fn is_empty(&self) -> bool {
self.notifiers.is_empty()
}
pub fn send(&self, msg: &str) {
if let Some(webhook) = &self.discord_webhook {
for notifier in &self.notifiers {
match notifier {
NotificationType::Discord(webhook) => {
for line in msg.split('\n') {
// Discord rate limiting is aggressive, limit to 1 message a second
sleep(Duration::from_millis(1000));
@ -152,15 +160,14 @@ impl Notifier {
}
}
}
if let Some(webhook) = &self.slack_webhook {
NotificationType::Slack(webhook) => {
let data = json!({ "text": msg });
if let Err(err) = self.client.post(webhook).json(&data).send() {
warn!("Failed to send Slack message: {:?}", err);
}
}
if let Some(TelegramWebHook { chat_id, bot_token }) = &self.telegram_webhook {
NotificationType::Telegram(TelegramWebHook { chat_id, bot_token }) => {
let data = json!({ "chat_id": chat_id, "text": msg });
let url = format!("https://api.telegram.org/bot{}/sendMessage", bot_token);
@ -169,13 +176,12 @@ impl Notifier {
}
}
if let Some(TwilioWebHook {
NotificationType::Twilio(TwilioWebHook {
account,
token,
to,
from,
}) = &self.twilio_webhook
{
}) => {
let url = format!(
"https://{}:{}@api.twilio.com/2010-04-01/Accounts/{}/Messages.json",
account, token, account
@ -186,4 +192,6 @@ impl Notifier {
}
}
}
}
}
}