use skynet_discord_bot::{db_init, get_config, Accounts, Config, DataBase}; use std::{process, sync::Arc}; use serde::Deserialize; use serenity::{ async_trait, client::{Context, EventHandler}, model::{ gateway::{GatewayIntents, Ready}, id::GuildId, }, Client, }; use sqlx::{Pool, Sqlite}; use tokio::sync::RwLock; #[tokio::main] async fn main() { let config = get_config(); let db = match db_init(&config).await { Ok(x) => x, Err(_) => return, }; // Intents are a bitflag, bitwise operations can be used to dictate which intents to use let intents = GatewayIntents::GUILDS | GatewayIntents::GUILD_MESSAGES | GatewayIntents::MESSAGE_CONTENT | GatewayIntents::GUILD_MEMBERS; // Build our client. let mut client = Client::builder(&config.discord_token, intents) .event_handler(Handler {}) .await .expect("Error creating client"); { let mut data = client.data.write().await; data.insert::(Arc::new(RwLock::new(config))); data.insert::(Arc::new(RwLock::new(db))); } // Finally, start a single shard, and start listening to events. // // Shards will automatically attempt to reconnect, and will perform // exponential backoff until it reconnects. if let Err(why) = client.start().await { println!("Client error: {:?}", why); } } struct Handler; #[async_trait] impl EventHandler for Handler { async fn ready(&self, ctx: Context, ready: Ready) { println!("{} is connected!", ready.user.name); fetch_accounts(&ctx).await; process::exit(0); } } #[derive(Debug, Deserialize)] pub struct DiscordResult { discord: String, wolves_id: String, } async fn fetch_accounts(ctx: &Context) { let config_lock = { let data_read = ctx.data.read().await; data_read.get::().expect("Expected Config in TypeMap.").clone() }; let config = config_lock.read().await; let db_lock = { let data_read = ctx.data.read().await; data_read.get::().expect("Expected Config in TypeMap.").clone() }; let db = db_lock.read().await; // handle wolves api here // get from skynet for the compsoc server only let url = format!("{}/ldap/discord?auth={}", &config.ldap_api, &config.auth); if let Ok(result) = surf::get(url).recv_json::>().await { for user in result { add_users_skynet(&db, &config.skynet_server, &user).await; } } } pub async fn add_users_skynet(db: &Pool, server: &GuildId, user: &DiscordResult) { match sqlx::query_as::<_, Accounts>( " UPDATE accounts SET discord = ? WHERE server = ? AND wolves_id = ? ", ) .bind(&user.discord) .bind(*server.as_u64() as i64) .bind(&user.wolves_id) .fetch_optional(db) .await { Ok(_) => {} Err(e) => { println!("Failure to insert into {} {:?}", server.as_u64(), user); println!("{:?}", e); } } }