/*
* Copyright (C) 2025 Jonni Liljamo <jonni@liljamo.com>
*
* 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<State>,
headers: HeaderMap,
Json(message): Json<MessageForm>,
) -> 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, "")
}