feat: add ntfy optional feature

This commit is contained in:
əlemi 2024-05-27 19:02:35 +02:00
parent ed0be85550
commit fb82f92da5
Signed by: alemi
GPG key ID: A4895B84D311642C
3 changed files with 2015 additions and 0 deletions

1964
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -22,12 +22,14 @@ tokio = { version = "1.36", features = ["net", "macros", "rt-multi-thread", "io-
tokio-native-tls = "0.3.1" tokio-native-tls = "0.3.1"
tracing = "0.1.40" tracing = "0.1.40"
tracing-subscriber = "0.3.18" tracing-subscriber = "0.3.18"
reqwest = { version = "0.12", optional = true }
[build-dependencies] [build-dependencies]
prost-build = "0.12" prost-build = "0.12"
[features] [features]
default = [] default = []
ntfy = ["dep:reqwest"]
[lints.rust] [lints.rust]
unsafe_code = "forbid" unsafe_code = "forbid"

View file

@ -46,6 +46,14 @@ struct CliArgs {
/// disable arbitrary server join and peek /// disable arbitrary server join and peek
#[arg(long, default_value_t = false)] #[arg(long, default_value_t = false)]
no_peek: bool, no_peek: bool,
/// ntfy.sh server to use for notifications
#[arg(long, default_value = "https://ntfy.sh")]
ntfy: String,
/// ntfy.sh topic to use for notifications, leave empty to disable notifications
#[arg(long)]
topic: Option<String>,
} }
#[tokio::main] #[tokio::main]
@ -72,6 +80,13 @@ async fn main() {
// if !args.no_peek { // if !args.no_peek {
// app = app.route("/peek", get(peek_server)); // app = app.route("/peek", get(peek_server));
// } // }
#[cfg(feature = "ntfy")]
if let Some(topic) = args.topic {
let events = session.events();
let target = format!("{}/{topic}", args.ntfy);
tokio::spawn(async move { handle_ntfy(target, events).await });
}
let app = app let app = app
.route("/info", get(server_info)) .route("/info", get(server_info))
@ -100,6 +115,40 @@ async fn server_ws(ws: WebSocketUpgrade, State(session): State<Arc<Session>>) ->
ws.on_upgrade(|socket| handle_ws(socket, sub)) ws.on_upgrade(|socket| handle_ws(socket, sub))
} }
#[cfg(feature = "ntfy")]
async fn handle_ntfy(target: String, mut sub: broadcast::Receiver<session::SessionEvent>) {
use std::collections::HashMap;
let client = reqwest::Client::new();
let mut users = HashMap::new();
while let Ok(event) = sub.recv().await {
if let Err(e) = match event {
session::SessionEvent::AddUser(user) => {
users.insert(user.session, user.name.clone());
client
.post(&target)
.body(format!("user {} connected", user.name))
.header("Title", "mumble")
.header("Priority", "default")
.header("Tags", "studio_microphone")
.send()
.await
},
session::SessionEvent::RemoveUser(id) =>
client
.post(&target)
.body(format!("user {} left", users.remove(&id).unwrap_or_default()))
.header("Title", "mumble")
.header("Priority", "default")
.header("Tags", "x")
.send()
.await,
} {
tracing::debug!("events channel closed: {e}");
}
}
}
async fn handle_ws(mut socket: WebSocket, mut sub: broadcast::Receiver<session::SessionEvent>) { async fn handle_ws(mut socket: WebSocket, mut sub: broadcast::Receiver<session::SessionEvent>) {
while let Ok(event) = sub.recv().await { while let Ok(event) = sub.recv().await {
if let Err(e) = match event { if let Err(e) = match event {