/* * Copyright (C) 2025 Jonni Liljamo * * This file is licensed under AGPL-3.0-or-later, see NOTICE and LICENSE for * more information. */ use std::sync::Arc; use axum::{Json, http::HeaderMap, response::IntoResponse}; use reqwest::StatusCode; use serde::Deserialize; use tracing::{error, info}; use crate::state::State; #[derive(Deserialize)] pub struct MessageForm { pub title: String, pub message: String, #[serde(default)] pub format_commonmark: bool, } pub async fn message( state: Arc, headers: HeaderMap, Json(message): Json, ) -> impl IntoResponse { let token = match headers.get("Authorization") { Some(token) => match token.to_str() { Ok(token) => token, Err(_) => { return (StatusCode::UNAUTHORIZED, "unauthorized"); } }, None => { return (StatusCode::UNAUTHORIZED, "unauthorized"); } }; let notifier = match state.notifiers.iter().find(|(_k, v)| v.token == token) { Some(n) => n, None => return (StatusCode::UNAUTHORIZED, "unauthorized"), }; info!(msg = "message", notifier = notifier.0); for (_k, v) in state .services .iter() .filter(|(k, _v)| notifier.1.services.contains(k)) { match v.send(&message).await { Ok(_) => {} Err(err) => { error!(msg = "message sending failed", ?err); return (StatusCode::INTERNAL_SERVER_ERROR, "failed to send message"); } } } (StatusCode::OK, "") }