-
-
Notifications
You must be signed in to change notification settings - Fork 300
/
tgbot.rs
110 lines (96 loc) · 3.15 KB
/
tgbot.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#![deny(warnings)]
use anyhow::Result;
use log::{error, info, trace};
use reqwest;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use tokio::time::Duration;
use crate::notifier;
use crate::notifier::Event;
use crate::notifier::HostStat;
use crate::notifier::Notifier;
use crate::notifier::NOTIFIER_HANDLE;
const KIND: &str = "tgbot";
#[derive(Debug, Default, Deserialize, Serialize)]
pub struct Config {
pub enabled: bool,
pub bot_token: String,
pub chat_id: String,
pub custom_tpl: String,
}
pub struct TGBot {
config: &'static Config,
tg_url: String,
http_client: reqwest::Client,
}
impl TGBot {
pub fn new(cfg: &'static Config) -> Self {
let o = Self {
config: cfg,
tg_url: format!("https://api.telegram.org/bot{}/sendMessage", &cfg.bot_token),
http_client: reqwest::Client::new(),
};
notifier::add_template(KIND, o.config.custom_tpl.as_str()).unwrap();
o
}
fn custom_notify(&self, stat: &HostStat) -> Result<()> {
trace!("{} custom_notify => {:?}", self.kind(), stat);
notifier::render_template(KIND, stat).map(|content| {
info!("tmpl.render => {}", content);
if !content.is_empty() {
self.send_msg(format!("❗<b>Server Status</b>\n{}", content))
.unwrap_or_else(|err| {
error!("send_msg err => {:?}", err);
});
}
})
}
fn send_msg(&self, html_content: String) -> Result<()> {
let mut data = HashMap::new();
data.insert("chat_id", self.config.chat_id.to_string());
data.insert("parse_mode", "HTML".to_string());
data.insert("text", html_content);
let tg_url = self.tg_url.to_string();
let handle = NOTIFIER_HANDLE.lock().unwrap().as_ref().unwrap().clone();
let http_client = self.http_client.clone();
handle.spawn(async move {
match http_client
.post(&tg_url)
.timeout(Duration::from_secs(5))
.json(&data)
.send()
.await
{
Ok(resp) => {
info!("tg send msg resp => {:?}", resp);
}
Err(err) => {
error!("tg send msg error => {:?}", err);
}
}
});
Ok(())
}
}
impl crate::notifier::Notifier for TGBot {
fn kind(&self) -> &'static str {
KIND
}
fn notify(&self, e: &Event, stat: &HostStat) -> Result<()> {
trace!("{} notify {:?} => {:?}", self.kind(), e, stat);
match *e {
Event::NodeUp => {
let content = format!("❗<b>Server Status</b>\n❗ {} 主机上线 🟢", stat.name);
let _ = self.send_msg(content);
}
Event::NodeDown => {
let content = format!("❗<b>Server Status</b>\n❗ {} 主机下线 🔴", stat.name);
let _ = self.send_msg(content);
}
Event::Custom => {
let _ = self.custom_notify(stat);
}
}
Ok(())
}
}