alert2muc/src/main.rs

92 lines
2.1 KiB
Rust

use std::{
net::SocketAddr,
collections::HashMap,
sync::{Arc, Mutex},
};
use axum::{
extract::State,
routing::post,
http::StatusCode,
response::{IntoResponse, Response},
Json, Router,
};
use serde::Deserialize;
mod jabber;
#[derive(Deserialize, Clone, Debug)]
struct Alert {
generatorURL: String,
startsAt: String,
annotations: AlertAnnotations,
labels: HashMap<String, String>,
}
#[derive(Deserialize, Clone, Debug)]
struct AlertAnnotations {
summary: String,
}
#[derive(Clone)]
struct AppState {
jabber: jabber::Handle,
alerts: Arc<Mutex<HashMap<String, Alert>>>,
}
async fn alerts(
State(state): State<AppState>,
Json(payload): Json<Vec<Alert>>,
) -> Response {
let mut message = "".to_string();
let mut alerts = state.alerts.lock().unwrap();
for alert in payload.into_iter() {
let is_old = if let Some(old_alert) = alerts.get(&alert.generatorURL) {
old_alert.startsAt == alert.startsAt
} else {
false
};
if ! is_old {
if message != "" {
message += "\n";
}
message += &format!("{}: {}", alert.annotations.summary, alert.generatorURL);
alerts.insert(alert.generatorURL.clone(), alert);
}
}
drop(alerts);
if message != "" {
let jabber = state.jabber.clone();
tokio::spawn(async move {
jabber.send_message(message).await;
});
}
StatusCode::OK.into_response()
}
#[tokio::main]
async fn main() {
// initialize tracing
tracing_subscriber::fmt::init();
let jabber = jabber::run(/*secret*/).await;
let state = AppState {
jabber,
alerts: Arc::new(Mutex::new(HashMap::new())),
};
// build our application with a route
let app = Router::new()
.route("/", post(alerts))
.with_state(state);
let addr = SocketAddr::from(([127, 0, 0, 1], 9022));
tracing::debug!("listening on {}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}