133 lines
4.0 KiB
Rust
133 lines
4.0 KiB
Rust
|
extern crate rand;
|
||
|
|
||
|
use crate::message::*;
|
||
|
pub use crate::output::*;
|
||
|
use serde::Deserialize;
|
||
|
|
||
|
use percent_encoding::{utf8_percent_encode, DEFAULT_ENCODE_SET};
|
||
|
use rand::distributions::Alphanumeric;
|
||
|
use rand::Rng;
|
||
|
use reqwest::header;
|
||
|
use reqwest::{Client, Url};
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
struct MatrixClient {
|
||
|
http_client: Client,
|
||
|
homeserver_uri: String,
|
||
|
token: String,
|
||
|
}
|
||
|
impl MatrixClient {
|
||
|
fn new(homeserver_uri: &str, token: &str) -> Self {
|
||
|
Self {
|
||
|
http_client: Client::new(),
|
||
|
homeserver_uri: homeserver_uri.to_owned(),
|
||
|
token: token.to_owned(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// fn get(
|
||
|
// &self,
|
||
|
// path: &str,
|
||
|
// params: &HashMap<&str, String>,
|
||
|
// ) -> Result<reqwest::Response, reqwest::Error> {
|
||
|
// let mut path = self.homeserver_uri.clone() + path;
|
||
|
|
||
|
// let mut first = true;
|
||
|
// for (k, v) in params {
|
||
|
// path += &format!(
|
||
|
// "{}{}={}",
|
||
|
// if first { "?" } else { "&" },
|
||
|
// utf8_percent_encode(k.as_ref(), DEFAULT_ENCODE_SET),
|
||
|
// utf8_percent_encode(v.as_ref(), DEFAULT_ENCODE_SET)
|
||
|
// );
|
||
|
// first = false;
|
||
|
// }
|
||
|
|
||
|
// self.http_client
|
||
|
// .get(Url::parse(&path).unwrap())
|
||
|
// .header(header::AUTHORIZATION, format!("Bearer {}", self.token))
|
||
|
// .send()
|
||
|
// }
|
||
|
fn put(&self, path: &str, body: String) -> reqwest::Response {
|
||
|
let path = self.homeserver_uri.clone() + path;
|
||
|
|
||
|
self.http_client
|
||
|
.put(Url::parse(&path).expect(&format!("Invalid path: {}", path)))
|
||
|
.header(header::AUTHORIZATION, format!("Bearer {}", self.token))
|
||
|
.header(header::CONTENT_TYPE, "application/json")
|
||
|
.body(body)
|
||
|
.send()
|
||
|
.unwrap()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
pub struct Matrix {
|
||
|
client: MatrixClient,
|
||
|
config: MatrixConfig,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Deserialize)]
|
||
|
struct MatrixConfig {
|
||
|
homeserver_url: String,
|
||
|
token: String,
|
||
|
room_id: String,
|
||
|
}
|
||
|
|
||
|
impl Output for Matrix {
|
||
|
fn new(config: serde_yaml::Value) -> Result<Self, Box<dyn std::error::Error>> {
|
||
|
let config: MatrixConfig = serde_yaml::from_value(config)?;
|
||
|
|
||
|
Ok(Matrix {
|
||
|
client: MatrixClient::new(&config.homeserver_url, &config.token),
|
||
|
config: config,
|
||
|
})
|
||
|
}
|
||
|
fn process_message(&mut self, message: Message) {
|
||
|
use serde_json::json;
|
||
|
|
||
|
let msg_type = match message.level {
|
||
|
Level::Debug | Level::Notice => "m.notice",
|
||
|
_ => "m.text",
|
||
|
};
|
||
|
|
||
|
let decorator = match message.level {
|
||
|
Level::Debug | Level::Notice => ("", ""),
|
||
|
Level::Anomaly => ("<font color=\"#FFFF00\">", "</font>"),
|
||
|
Level::Issue => ("<font color=\"#FF0000\">", "</font>"),
|
||
|
Level::Critical => ("<strong><font color=\"#FF0000\">", "</font></strong>"),
|
||
|
};
|
||
|
|
||
|
let text = match message.level {
|
||
|
Level::Critical => format!("@room {}", message.text),
|
||
|
_ => message.text,
|
||
|
};
|
||
|
|
||
|
let body = json!({
|
||
|
"body": format!("[{}->{}]: {}", message.emitter, message.msg_type, text),
|
||
|
"formatted_body": format!("[{}->{}]: {}{}{}", message.emitter, message.msg_type, decorator.0, text, decorator.1),
|
||
|
"msgtype": msg_type,
|
||
|
"format": "org.matrix.custom.html",
|
||
|
})
|
||
|
.to_string();
|
||
|
|
||
|
let mut res = self.client.put(
|
||
|
&format!(
|
||
|
"/_matrix/client/r0/rooms/{}/send/m.room.message/{}",
|
||
|
utf8_percent_encode(&self.config.room_id, DEFAULT_ENCODE_SET),
|
||
|
utf8_percent_encode(
|
||
|
&rand::thread_rng()
|
||
|
.sample_iter(&Alphanumeric)
|
||
|
.take(32)
|
||
|
.collect::<String>(),
|
||
|
DEFAULT_ENCODE_SET
|
||
|
),
|
||
|
),
|
||
|
body,
|
||
|
);
|
||
|
if res.status().as_u16() != 200 {
|
||
|
log::warn!("Could not send Matrix message: {}", res.text().unwrap());
|
||
|
}
|
||
|
}
|
||
|
}
|