|
- #![feature(proc_macro_hygiene, decl_macro)]
-
- mod auth_tools;
- mod discord;
- mod command_definitions;
- mod gitea;
- mod gitea_command;
- mod macros;
-
- #[macro_use] extern crate rocket;
- use lazy_static::lazy_static;
-
- use rocket_contrib::json::Json;
- use std::sync::RwLock;
- use crate::auth_tools::{AuthenticatedInteraction};
- use crate::discord::{Interaction, InteractionResponse, InteractionResponseRaw, InteractionApplicationCommandCallbackData};
- use crate::command_definitions::{hello_world, def_hello_world, def_gitea_release, def_gitea_issue, def_cardlife, def_robocraft, def_techblox};
- use crate::gitea_command::{gitea_release, gitea_issue};
- use crate::macros::{cardlife, robocraft, techblox};
-
- static GLOBAL_COMMAND_KEY: &str = "GLOBAL command KEY";
-
- lazy_static! {
- pub static ref VERIFICATION_KEY: RwLock<Option<ed25519_dalek::PublicKey>> = RwLock::new(None);
- pub static ref APPLICATION_ID: RwLock<Option<String>> = RwLock::new(None);
- pub static ref BOT_TOKEN: RwLock<Option<String>> = RwLock::new(None);
- }
-
- #[post("/", data = "<interaction>")]
- fn root_post(interaction: AuthenticatedInteraction) -> Json<InteractionResponseRaw> {
- Json(
- match &interaction.interaction {
- Interaction::Ping {} => InteractionResponse::Pong {},
- Interaction::Command {data, ..} => {
- match &data.name as &str {
- "hello-world" => hello_world(&interaction.interaction),
- "gitea-release" => gitea_release(&interaction.interaction),
- "gitea-issue" => gitea_issue(&interaction.interaction),
- "cardlife" => cardlife(&interaction.interaction),
- "robocraft" => robocraft(&interaction.interaction),
- "techblox" => techblox(&interaction.interaction),
- _ => InteractionResponse::ChannelMessageWithSource {
- data: Some(InteractionApplicationCommandCallbackData {
- tts: false,
- content: "Oops, that's not implemented yet!".to_string(),
- embeds: None,
- allowed_mentions: None,
- flags: Some(64),
- })
- },
- }
- },
- _ => InteractionResponse::AcknowledgeWithSource {},
- }.raw()
- )
- }
-
- #[get("/")]
- fn hello_get() -> &'static str {
- "Hello, why are you here?"
- }
-
- fn main() {
- // Init verification key
- let public_key = std::env::var("DISCORD_PUBLIC_KEY")
- .expect("Environment variable DISCORD_PUBLIC_KEY not found");
- //println!("Discord Pub Key {}", &public_key);
- *VERIFICATION_KEY.write().unwrap() = Some(ed25519_dalek::PublicKey::from_bytes(
- &hex::decode(public_key)
- .expect("Invalid hex string")).expect("Invalid public key"));
- // get application ID for sending API requests
- let app_id = std::env::var("DISCORD_APP_ID")
- .expect("Environment variable DISCORD_APP_ID not found");
- //println!("Discord App Id {}", &app_id);
- *APPLICATION_ID.write().unwrap() = Some(app_id.to_string());
- // get bot token for sending API requests
- let token = std::env::var("DISCORD_TOKEN")
- .expect("Environment variable DISCORD_TOKEN not found");
- //println!("Discord Token {}", &token);
- *BOT_TOKEN.write().unwrap() = Some(token.to_string());
-
- // send API requests to bootstrap commands
- let req_client = reqwest::blocking::Client::new();
- // TODO add more commands
- register_command(&def_hello_world, &req_client);
- register_command(&def_gitea_release, &req_client);
- register_command(&def_gitea_issue, &req_client);
- register_command(&def_cardlife, &req_client);
- register_command(&def_robocraft, &req_client);
- register_command(&def_techblox, &req_client);
- // start web server
- rocket::ignite().mount("/", routes![root_post, hello_get]).launch();
- }
-
- fn register_command(f: &dyn Fn() -> (discord::ApplicationCommand, Option<String>),
- client: &reqwest::blocking::Client) {
- let (payload, guild_opt) = f();
- if let Some(guild_id) = guild_opt {
- // create/upsert command
- let url = format!("https://discord.com/api/v8/applications/{}/guilds/{}/commands", APPLICATION_ID.read().unwrap().as_ref().unwrap().clone(), &guild_id);
- let res = client.post(&url)
- .header("Authorization", format!("Bot {}", BOT_TOKEN.read().unwrap().as_ref().unwrap().clone()))
- .json(&payload.raw())
- .send();
- if let Ok(d) = res {
- println!("Registered/updated `{}` ({}) GUILD:{}", &payload.name, &d.status().as_str(), &guild_id);
- //println!("{}", &d.text().unwrap());
- }
- } else {
- // create/upsert command
- let url = format!("https://discord.com/api/v8/applications/{}/commands", APPLICATION_ID.read().unwrap().as_ref().unwrap().clone());
- let res = client.post(&url)
- .header("Authorization", format!("Bot {}", BOT_TOKEN.read().unwrap().as_ref().unwrap().clone()))
- .json(&payload.raw())
- .send();
- if let Ok(d) = res {
- println!("Registered/updated `{}` ({})", &payload.name, &d.status().as_str());
- //println!("{}", &d.text().unwrap());
- }
- }
- }
-
- /*
- fn get_commands(client: &reqwest::blocking::Client) -> Vec<ApplicationCommand> {
- let url = format!("https://discord.com/api/v8/applications/{}/commands", APPLICATION_ID.read().unwrap().as_ref().unwrap().clone());
- let res = client.get(&url)
- .header("Authorization", format!("Bot {}", BOT_TOKEN.read().unwrap().as_ref().unwrap().clone()))
- .send();
- if let Ok(d) = res {
- println!("Commands GET status {}", &d.status().as_str());
- return d.json().unwrap();
- }
- return Vec::new();
- }
-
- fn get_guild_commands(client: &reqwest::blocking::Client, guild_id: &str) -> Vec<ApplicationCommand> {
- let url = format!("https://discord.com/api/v8/applications/{}/guilds/{}/commands", APPLICATION_ID.read().unwrap().as_ref().unwrap().clone(), guild_id);
- let res = client.get(&url)
- .header("Authorization", format!("Bot {}", BOT_TOKEN.read().unwrap().as_ref().unwrap().clone()))
- .send();
- if let Ok(d) = res {
- println!("Commands GET status {}", &d.status().as_str());
- return d.json().unwrap();
- }
- return Vec::new();
- }
- */
|