diff --git a/Cargo.lock b/Cargo.lock index 92b96e0..614a04f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,6 +52,12 @@ dependencies = [ "syn 2.0.52", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.1.0" @@ -79,6 +85,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -293,12 +305,12 @@ dependencies = [ ] [[package]] -name = "discord-to-telegram-messages-resender" +name = "discord-bot" version = "0.1.0" dependencies = [ "chrono", "once_cell", - "reqwest", + "reqwest 0.12.5", "serenity", "tokio", ] @@ -521,6 +533,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "h2" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -566,6 +597,29 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.8.0" @@ -588,9 +642,9 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", + "h2 0.3.24", "http 0.2.12", - "http-body", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -602,6 +656,26 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.1", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -610,23 +684,63 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http 0.2.12", - "hyper", + "hyper 0.14.28", "rustls 0.21.10", "tokio", "tokio-rustls 0.24.1", ] [[package]] -name = "hyper-tls" -version = "0.5.0" +name = "hyper-rustls" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.4.1", + "hyper-util", + "rustls 0.23.7", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.0", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", - "hyper", + "http-body-util", + "hyper 1.4.1", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.4.1", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] @@ -921,6 +1035,26 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1025,35 +1159,32 @@ version = "0.11.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eea5a9eb898d3783f17c6407670e3592fd174cb81a10e51d4c37f49450b9946" dependencies = [ - "base64", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2", + "h2 0.3.24", "http 0.2.12", - "http-body", - "hyper", - "hyper-rustls", - "hyper-tls", + "http-body 0.4.6", + "hyper 0.14.28", + "hyper-rustls 0.24.2", "ipnet", "js-sys", "log", "mime", "mime_guess", - "native-tls", "once_cell", "percent-encoding", "pin-project-lite", "rustls 0.21.10", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", - "system-configuration", + "sync_wrapper 0.1.2", + "system-configuration 0.6.0", "tokio", - "tokio-native-tls", "tokio-rustls 0.24.1", "tokio-util", "tower-service", @@ -1063,7 +1194,50 @@ dependencies = [ "wasm-streams", "web-sys", "webpki-roots 0.25.4", - "winreg", + "winreg 0.50.0", +] + +[[package]] +name = "reqwest" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.4.1", + "hyper-rustls 0.27.2", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 2.1.3", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "system-configuration 0.5.1", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.52.0", ] [[package]] @@ -1126,20 +1300,43 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls" +version = "0.23.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebbbdb961df0ad3f2652da8f3fdc4b36122f568f968f45ad3316f26c025c677b" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki 0.102.2", + "subtle", + "zeroize", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64", + "base64 0.21.7", +] + +[[package]] +name = "rustls-pemfile" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.3.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" @@ -1295,7 +1492,7 @@ checksum = "c64da29158bb55d70677cacd4f4f8eab1acef005fb830d9c3bea411b090e96a9" dependencies = [ "arrayvec", "async-trait", - "base64", + "base64 0.21.7", "bitflags 2.4.2", "bytes", "chrono", @@ -1308,7 +1505,7 @@ dependencies = [ "mime_guess", "parking_lot", "percent-encoding", - "reqwest", + "reqwest 0.11.25", "secrecy", "serde", "serde_json", @@ -1420,6 +1617,23 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys 0.5.0", +] + [[package]] name = "system-configuration" version = "0.6.0" @@ -1428,7 +1642,17 @@ checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42" dependencies = [ "bitflags 2.4.2", "core-foundation", - "system-configuration-sys", + "system-configuration-sys 0.6.0", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", ] [[package]] @@ -1584,6 +1808,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls 0.23.7", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-tungstenite" version = "0.21.0" @@ -1614,6 +1849,27 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -2109,6 +2365,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "zeroize" version = "1.7.0" diff --git a/Cargo.toml b/Cargo.toml index fa75bd9..5442374 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "discord-to-telegram-messages-resender" +name = "discord-bot" version = "0.1.0" edition = "2021" @@ -8,6 +8,6 @@ edition = "2021" [dependencies] once_cell = "1.19.0" tokio = { version = "1.35.1", features = ["rt-multi-thread", "macros", "time"] } -serenity = { verstion = "0.12.1", features = ["collector"] } -reqwest = { version = "0.11.23", features = ["json"] } +serenity = { version = "0.12.1", features = ["collector"] } +reqwest = { version = "0.12.5", features = ["json"] } chrono = "0.4.38" diff --git a/docker/build.dockerfile b/docker/build.dockerfile index 37d149a..42b32dd 100644 --- a/docker/build.dockerfile +++ b/docker/build.dockerfile @@ -4,7 +4,7 @@ WORKDIR /app COPY . . -RUN cargo build --release --bin discord-to-telegram-messages-resender +RUN cargo build --release --bin discord-bot FROM debian:bullseye-slim @@ -17,5 +17,5 @@ RUN update-ca-certificates WORKDIR /app -COPY --from=builder /app/target/release/discord-to-telegram-messages-resender /usr/local/bin -ENTRYPOINT ["/usr/local/bin/discord-to-telegram-messages-resender"] +COPY --from=builder /app/target/release/discord-bot /usr/local/bin +ENTRYPOINT ["/usr/local/bin/discord-bot"] diff --git a/src/config.rs b/src/config.rs index 417ec67..34e3110 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,11 +8,15 @@ fn get_env(env: &'static str) -> String { pub struct Config { pub discord_bot_token: String, + pub discord_guild_id: u64, pub discord_channel_id: u64, + pub discord_bot_activity: String, + pub discord_game_list_channel_id: u64, pub discord_game_list_message_id: u64, + pub telegram_bot_token: String, pub telegram_channel_id: i128, } diff --git a/src/commands/add_game.rs b/src/handler/commands/add_game.rs similarity index 100% rename from src/commands/add_game.rs rename to src/handler/commands/add_game.rs diff --git a/src/commands/delete_game.rs b/src/handler/commands/delete_game.rs similarity index 100% rename from src/commands/delete_game.rs rename to src/handler/commands/delete_game.rs diff --git a/src/commands/mod.rs b/src/handler/commands/mod.rs similarity index 100% rename from src/commands/mod.rs rename to src/handler/commands/mod.rs diff --git a/src/handler/mod.rs b/src/handler/mod.rs new file mode 100644 index 0000000..d2ed918 --- /dev/null +++ b/src/handler/mod.rs @@ -0,0 +1,129 @@ +use serenity::prelude::*; +use serenity::all::{AutocompleteChoice, CreateAutocompleteResponse, CreateInteractionResponse, CreateInteractionResponseMessage, EditMessage, GuildId, Interaction}; +use serenity::async_trait; +use serenity::model::channel::Message; + +use chrono::offset::FixedOffset; + +use crate::config; +use crate::notifiers::telegram::send_to_telegram; +use crate::utils::{add_game, delete_game, format_games_list, parse_games_list}; + +pub mod commands; + + +pub struct Handler; + +#[async_trait] +impl EventHandler for Handler { + async fn interaction_create(&self, ctx: Context, interaction: Interaction) { + if let Interaction::Command(command) = interaction { + if command.channel_id != config::CONFIG.discord_game_list_channel_id { + return; + } + + match command.data.name.as_str() { + "add" => { + let mut message = command.channel_id.message(&ctx.http, config::CONFIG.discord_game_list_message_id).await.unwrap(); + + let utc_offset = FixedOffset::east_opt(3 * 3600); // UTC+3 offset in seconds + let current_time = chrono::Local::now().with_timezone(&utc_offset.unwrap()); + + let mut categories = parse_games_list(&message.content).await; + + categories = add_game( + categories, + command.data.options[0].value.as_str().unwrap(), + &format!( + "* {} ({}) | {}", + command.data.options[2].value.as_str().unwrap(), + command.data.options[1].value.as_str().unwrap(), + match command.data.options.get(3) { + Some(v) => v.value.as_str().unwrap().to_string(), + None => format!("{}", current_time.format("%d.%m.%Y")), + }, + ) + ).await; + + let new_content = format_games_list(categories).await; + + message.edit(&ctx.http, EditMessage::new().content(new_content)).await.unwrap(); + + let data = CreateInteractionResponseMessage::new().content("Игра добавлена!").ephemeral(true); + let builder = CreateInteractionResponse::Message(data); + if let Err(why) = command.create_response(&ctx.http, builder).await { + println!("Cannot respond to slash command: {why}"); + } + }, + "delete" => { + let mut message = command.channel_id.message(&ctx.http, config::CONFIG.discord_game_list_message_id).await.unwrap(); + + let mut categories = parse_games_list(&message.content).await; + + categories = delete_game( + categories, + command.data.options[0].value.as_str().unwrap() + ).await; + + let new_content = format_games_list(categories).await; + + message.edit(&ctx.http, EditMessage::new().content(new_content)).await.unwrap(); + + let data = CreateInteractionResponseMessage::new().content("Игра удалена!").ephemeral(true); + let builder = CreateInteractionResponse::Message(data); + if let Err(why) = command.create_response(&ctx.http, builder).await { + println!("Cannot respond to slash command: {why}"); + } + }, + _ => (), + }; + } else if let Interaction::Autocomplete(interaction) = interaction { + if interaction.channel_id != config::CONFIG.discord_game_list_channel_id { + return; + } + + if interaction.data.name.as_str() == "delete" { + let message = interaction.channel_id.message(&ctx.http, config::CONFIG.discord_game_list_message_id).await.unwrap(); + let categories = parse_games_list(&message.content).await; + let games = categories.iter().flat_map(|category| category.games.iter()).collect::>(); + + let query = interaction.data.options[0].value.as_str().unwrap(); + + let autocompolete_response = CreateAutocompleteResponse::new().set_choices( + games + .iter() + .filter(|game| game.to_lowercase().contains(&query.to_lowercase())) + .map(|game| { + AutocompleteChoice::new(game.to_string(), game.to_string()) + }).collect() + ); + + let _ = interaction.create_response(&ctx.http, serenity::builder::CreateInteractionResponse::Autocomplete(autocompolete_response)).await.unwrap(); + }; + } + } + + async fn message(&self, _ctx: Context, msg: Message) { + if msg.guild_id != Some(config::CONFIG.discord_guild_id.into()) { + return; + } + + if msg.channel_id == config::CONFIG.discord_channel_id { + send_to_telegram(&msg.content).await; + return; + } + } + + async fn ready(&self, ctx: Context, _ready: serenity::model::gateway::Ready) { + let guild_id = GuildId::new(config::CONFIG.discord_guild_id); + + let _ = guild_id + .set_commands( + &ctx.http, + vec![ + commands::add_game::register(), + commands::delete_game::register(), + ] + ).await.unwrap(); + } +} diff --git a/src/main.rs b/src/main.rs index 4844e5b..384bc10 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,163 +1,32 @@ -use reqwest::Url; -use serenity::all::{ActivityData, AutocompleteChoice, CreateAutocompleteResponse, CreateInteractionResponse, CreateInteractionResponseMessage, EditMessage, GuildId, Interaction}; -use serenity::async_trait; -use serenity::model::channel::Message; +use serenity::all::ActivityData; use serenity::prelude::*; -use utils::{add_game, delete_game, format_games_list, parse_games_list}; -use chrono::offset::FixedOffset; pub mod config; -pub mod commands; +pub mod handler; pub mod utils; +pub mod notifiers; -async fn send_to_telegram(msg: &str) { - let base_url = format!("https://api.telegram.org/bot{}/sendMessage", config::CONFIG.telegram_bot_token); - - let url = Url::parse_with_params( - base_url.as_ref(), - &[ - ("chat_id", &config::CONFIG.telegram_channel_id.to_string().as_ref()), - ("text", &msg) - ] - ).unwrap(); - - reqwest::get(url).await.expect("Error sending message to Telegram"); -} - - -struct Handler; - -#[async_trait] -impl EventHandler for Handler { - async fn interaction_create(&self, ctx: Context, interaction: Interaction) { - if let Interaction::Command(command) = interaction { - if command.channel_id != config::CONFIG.discord_game_list_channel_id { - return; - } - - match command.data.name.as_str() { - "add" => { - let mut message = command.channel_id.message(&ctx.http, config::CONFIG.discord_game_list_message_id).await.unwrap(); - - let utc_offset = FixedOffset::east_opt(3 * 3600); // UTC+3 offset in seconds - let current_time = chrono::Local::now().with_timezone(&utc_offset.unwrap()); - - let mut categories = parse_games_list(&message.content).await; - - categories = add_game( - categories, - command.data.options[0].value.as_str().unwrap(), - &format!( - "* {} ({}) | {}", - command.data.options[2].value.as_str().unwrap(), - command.data.options[1].value.as_str().unwrap(), - match command.data.options.get(3) { - Some(v) => v.value.as_str().unwrap().to_string(), - None => format!("{}", current_time.format("%d.%m.%Y")), - }, - ) - ).await; - - let new_content = format_games_list(categories).await; - - message.edit(&ctx.http, EditMessage::new().content(new_content)).await.unwrap(); - - let data = CreateInteractionResponseMessage::new().content("Игра добавлена!").ephemeral(true); - let builder = CreateInteractionResponse::Message(data); - if let Err(why) = command.create_response(&ctx.http, builder).await { - println!("Cannot respond to slash command: {why}"); - } - }, - "delete" => { - let mut message = command.channel_id.message(&ctx.http, config::CONFIG.discord_game_list_message_id).await.unwrap(); - - let mut categories = parse_games_list(&message.content).await; - - categories = delete_game( - categories, - command.data.options[0].value.as_str().unwrap() - ).await; - - let new_content = format_games_list(categories).await; - - message.edit(&ctx.http, EditMessage::new().content(new_content)).await.unwrap(); - - let data = CreateInteractionResponseMessage::new().content("Игра удалена!").ephemeral(true); - let builder = CreateInteractionResponse::Message(data); - if let Err(why) = command.create_response(&ctx.http, builder).await { - println!("Cannot respond to slash command: {why}"); - } - }, - _ => (), - }; - } else if let Interaction::Autocomplete(interaction) = interaction { - if interaction.channel_id != config::CONFIG.discord_game_list_channel_id { - return; - } - - if interaction.data.name.as_str() == "delete" { - let message = interaction.channel_id.message(&ctx.http, config::CONFIG.discord_game_list_message_id).await.unwrap(); - let categories = parse_games_list(&message.content).await; - let games = categories.iter().flat_map(|category| category.games.iter()).collect::>(); - - let query = interaction.data.options[0].value.as_str().unwrap(); - - let autocompolete_response = CreateAutocompleteResponse::new().set_choices( - games - .iter() - .filter(|game| game.to_lowercase().contains(&query.to_lowercase())) - .map(|game| { - AutocompleteChoice::new(game.to_string(), game.to_string()) - }).collect() - ); - - let _ = interaction.create_response(&ctx.http, serenity::builder::CreateInteractionResponse::Autocomplete(autocompolete_response)).await.unwrap(); - }; - } - } - - async fn message(&self, _ctx: Context, msg: Message) { - if msg.guild_id != Some(config::CONFIG.discord_guild_id.into()) { - return; - } - - if msg.channel_id == config::CONFIG.discord_channel_id { - send_to_telegram(&msg.content).await; - return; - } - } - - async fn ready(&self, ctx: Context, _ready: serenity::model::gateway::Ready) { - let guild_id = GuildId::new(config::CONFIG.discord_guild_id); - - let _ = guild_id - .set_commands( - &ctx.http, - vec![ - commands::add_game::register(), - commands::delete_game::register(), - ] - ).await.unwrap(); - } -} - - -#[tokio::main] -async fn main() { +async fn start_discord_bot() { let intents = GatewayIntents::GUILD_MESSAGES | GatewayIntents::DIRECT_MESSAGES | GatewayIntents::MESSAGE_CONTENT; let mut client = Client::builder(&config::CONFIG.discord_bot_token, intents) - .event_handler(Handler) + .event_handler(handler::Handler) .status(serenity::all::OnlineStatus::Online) .activity(ActivityData::playing(&config::CONFIG.discord_bot_activity)) .await .expect("Err creating client"); if let Err(why) = client.start().await { - println!("Client error: {why:?}"); + panic!("Client error: {why:?}"); } } + + +#[tokio::main] +async fn main() { + start_discord_bot().await; +} diff --git a/src/notifiers/discord.rs b/src/notifiers/discord.rs new file mode 100644 index 0000000..d608ca7 --- /dev/null +++ b/src/notifiers/discord.rs @@ -0,0 +1,3 @@ +pub async fn send_to_discord(_msg: &str) { + todo!(); +} diff --git a/src/notifiers/mod.rs b/src/notifiers/mod.rs new file mode 100644 index 0000000..b4ef203 --- /dev/null +++ b/src/notifiers/mod.rs @@ -0,0 +1,2 @@ +pub mod telegram; +pub mod discord; diff --git a/src/notifiers/telegram.rs b/src/notifiers/telegram.rs new file mode 100644 index 0000000..06029f3 --- /dev/null +++ b/src/notifiers/telegram.rs @@ -0,0 +1,18 @@ +use reqwest::Url; + +use crate::config; + + +pub async fn send_to_telegram(msg: &str) { + let base_url = format!("https://api.telegram.org/bot{}/sendMessage", config::CONFIG.telegram_bot_token); + + let url = Url::parse_with_params( + base_url.as_ref(), + &[ + ("chat_id", &config::CONFIG.telegram_channel_id.to_string().as_ref()), + ("text", &msg) + ] + ).unwrap(); + + reqwest::get(url).await.expect("Error sending message to Telegram"); +}