From 9f0e3aae6d96d877c7eea49a098c0f2f1aebd508 Mon Sep 17 00:00:00 2001 From: lew Date: Fri, 10 Apr 2026 19:06:08 +0100 Subject: [PATCH] cargo: gate telegram behind a default feature --- Cargo.toml | 9 ++++++++- src/config.rs | 8 ++++++++ src/entries.rs | 5 +++++ src/main.rs | 34 ++++++++++++++++++++-------------- src/render.rs | 2 ++ src/web.rs | 2 ++ 6 files changed, 45 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3782636..26e8074 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,10 +6,14 @@ description = "A configurable, self-hosted guestbook for the web, allowing visit license = "MIT" repository = "https://git.ily.rs/lew/guestbook" +[features] +default = ["telegram"] +telegram = ["dep:teloxide"] + [dependencies] axum = "0.8" tokio = { version = "1", features = ["macros", "rt-multi-thread", "sync", "net"] } -teloxide = { version = "0.13", features = ["macros"] } +teloxide = { version = "0.13", features = ["macros"], optional = true } serde = { version = "1", features = ["derive"] } toml = "0.8" dotenvy = "0.15" @@ -19,6 +23,9 @@ base64 = "0.22" tracing = "0.1" tracing-subscriber = "0.3" +[profile.dev.package."*"] +opt-level = 1 + [dev-dependencies] tower = { version = "0.5", features = ["util"] } http-body-util = "0.1" diff --git a/src/config.rs b/src/config.rs index 711f78d..30f6e94 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,7 +7,9 @@ pub struct Config { pub data_dir: PathBuf, pub site_title: String, + #[cfg(feature = "telegram")] pub telegram_bot_token: Option, + #[cfg(feature = "telegram")] pub telegram_chat_id: Option, pub enable_honeypot: bool, pub max_name_length: usize, @@ -67,7 +69,9 @@ impl Config { .unwrap_or_else(|_| PathBuf::from("./data")), site_title: env::var("BOOK_SITE_TITLE").unwrap_or_else(|_| "guestbook".into()), + #[cfg(feature = "telegram")] telegram_bot_token: env::var("BOOK_TELEGRAM_BOT_TOKEN").ok(), + #[cfg(feature = "telegram")] telegram_chat_id: env::var("BOOK_TELEGRAM_CHAT_ID") .ok() .map(|v| v.parse().map_err(|_| "BOOK_TELEGRAM_CHAT_ID must be an integer")) @@ -188,7 +192,9 @@ mod tests { assert_eq!(config.listen_addr(), "127.0.0.1:9999"); assert_eq!(config.data_dir, PathBuf::from("/tmp/gb")); assert_eq!(config.site_title, "test.rs"); + #[cfg(feature = "telegram")] assert_eq!(config.telegram_bot_token.as_deref(), Some("123:ABC")); + #[cfg(feature = "telegram")] assert_eq!(config.telegram_chat_id, Some(12345)); // Clean up @@ -221,7 +227,9 @@ mod tests { env::remove_var("BOOK_TELEGRAM_CHAT_ID"); let config = Config::from_env().unwrap(); + #[cfg(feature = "telegram")] assert!(config.telegram_bot_token.is_none()); + #[cfg(feature = "telegram")] assert!(config.telegram_chat_id.is_none()); } diff --git a/src/entries.rs b/src/entries.rs index 3e0ca1e..f966b06 100644 --- a/src/entries.rs +++ b/src/entries.rs @@ -24,6 +24,7 @@ pub struct EntryMeta { #[derive(Debug, Clone)] pub struct Entry { + #[cfg_attr(not(feature = "telegram"), allow(dead_code))] pub id: String, pub meta: EntryMeta, pub body: String, @@ -49,6 +50,7 @@ impl Entry { }) } + #[cfg(any(feature = "telegram", test))] /// Return the short ID (UUID portion after the underscore). pub fn short_id(&self) -> &str { self.id.split('_').last().unwrap_or(&self.id) @@ -103,6 +105,7 @@ pub fn read_approved(dir: &Path) -> Vec { read_by_status(dir, Status::Approved) } +#[cfg(any(feature = "telegram", test))] /// Find a single entry by short ID (the UUID portion after the underscore). pub fn find_entry(dir: &Path, short_id: &str) -> Result { let read_dir = std::fs::read_dir(dir).map_err(|e| e.to_string())?; @@ -119,6 +122,7 @@ pub fn find_entry(dir: &Path, short_id: &str) -> Result { Err("Not found.".into()) } +#[cfg(any(feature = "telegram", test))] /// Delete an entry and its associated media files. /// `data_dir` is the parent directory containing entries/, drawings/, and voice_notes/. pub fn delete_entry(data_dir: &Path, short_id: &str) -> Result { @@ -148,6 +152,7 @@ pub fn delete_entry(data_dir: &Path, short_id: &str) -> Result { Ok(entry.meta.name.clone()) } +#[cfg(any(feature = "telegram", test))] /// Find an entry file by short ID prefix and update its status. pub fn set_status(dir: &Path, short_id: &str, status: Status) -> Result { let mut entry = find_entry(dir, short_id)?; diff --git a/src/main.rs b/src/main.rs index 566cd99..8e3db8d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,11 @@ mod config; mod entries; mod render; +#[cfg(feature = "telegram")] mod telegram; mod web; use std::sync::Arc; -use teloxide::prelude::*; #[tokio::main] async fn main() { @@ -18,25 +18,31 @@ async fn main() { std::fs::create_dir_all(&entries_dir).expect("failed to create entries directory"); - let (tx, rx) = tokio::sync::mpsc::channel::<(entries::Entry, Option>, Option>)>(32); + let (tx, _rx) = tokio::sync::mpsc::channel::<(entries::Entry, Option>, Option>)>(32); - // Spawn telegram tasks if configured - match (&config.telegram_bot_token, config.telegram_chat_id) { - (Some(token), Some(chat_id)) => { - let chat_id = ChatId(chat_id); - let bot = Bot::new(token); + #[cfg(feature = "telegram")] + { + use teloxide::prelude::*; + match (&config.telegram_bot_token, config.telegram_chat_id) { + (Some(token), Some(chat_id)) => { + let chat_id = ChatId(chat_id); + let bot = Bot::new(token); - let notify_bot = bot.clone(); - tokio::spawn(telegram::notification_task(notify_bot, chat_id, rx)); + let notify_bot = bot.clone(); + tokio::spawn(telegram::notification_task(notify_bot, chat_id, _rx)); - let cmd_data_dir = config.data_dir.clone(); - tokio::spawn(telegram::bot_task(bot, chat_id, cmd_data_dir)); - } - _ => { - tracing::info!("telegram not configured, moderation notifications disabled"); + let cmd_data_dir = config.data_dir.clone(); + tokio::spawn(telegram::bot_task(bot, chat_id, cmd_data_dir)); + } + _ => { + tracing::info!("telegram not configured, moderation notifications disabled"); + } } } + #[cfg(not(feature = "telegram"))] + tracing::info!("compiled without telegram support"); + let state = Arc::new(web::AppState { config, tx }); let app = web::router(state); diff --git a/src/render.rs b/src/render.rs index 19682a5..5d18c0c 100644 --- a/src/render.rs +++ b/src/render.rs @@ -322,7 +322,9 @@ mod tests { data_dir: PathBuf::from("./data"), site_title: "test".into(), + #[cfg(feature = "telegram")] telegram_bot_token: None, + #[cfg(feature = "telegram")] telegram_chat_id: None, enable_honeypot: true, max_name_length: 0, diff --git a/src/web.rs b/src/web.rs index badd5e2..a2e74bc 100644 --- a/src/web.rs +++ b/src/web.rs @@ -345,7 +345,9 @@ mod tests { data_dir: dir.to_path_buf(), site_title: "test".into(), + #[cfg(feature = "telegram")] telegram_bot_token: None, + #[cfg(feature = "telegram")] telegram_chat_id: None, enable_honeypot: true, max_name_length: 0,