use crate::database::Database; use twilight_cache_inmemory::DefaultInMemoryCache; use twilight_gateway::Event; use twilight_http::{Client as HttpClient, client::InteractionClient}; use twilight_model::{ channel::message::Embed, gateway::payload::incoming::InteractionCreate, http::interaction::{InteractionResponse, InteractionResponseData, InteractionResponseType}, id::{ Id, marker::{ChannelMarker, GuildMarker, MessageMarker, UserMarker}, }, }; const PROD_APP_ID: u64 = 1363055126264283136; const DEV_APP_ID: u64 = 1363494986699771984; const APP_ID: u64 = PROD_APP_ID; // A Absolutely Remarkably Terrible Thing macro_rules! aumau { ($meow:expr) => { $meow.await.unwrap().model().await.unwrap() }; } pub struct Brain { pub db: Database, http: HttpClient, cache: DefaultInMemoryCache, } impl Brain { pub fn new(db: Database, http: HttpClient, cache: DefaultInMemoryCache) -> Self { Self { db, http, cache } } pub fn update_cache(&self, event: &Event) { self.cache.update(event); } /// Get the interaction client. Used for responding to interactions pub fn interaction(&self) -> InteractionClient<'_> { self.http.interaction(Id::new(APP_ID)) } /// Respond to the interaction indicated by `create`. This method will /// respond as an `InteractionResponseType::ChannelMessageWithSource` pub async fn interaction_respond( &self, create: &InteractionCreate, data: InteractionResponseData, ) { self.interaction() .create_response( create.id, &create.token, &InteractionResponse { kind: InteractionResponseType::ChannelMessageWithSource, data: Some(data), }, ) .await .unwrap(); } pub async fn send_message_with_embed>( &self, channel: Id, msg: S, embed: Embed, ) -> Id { aumau!( self.http .create_message(channel) .embeds(&[embed]) .content(msg.as_ref()) ) .id } /// Retrieve information about a member of a guild. This method checks the /// cache first, and then makes a request if it isn't there pub async fn guild_member(&self, guild_id: Id, user_id: Id) -> Member { let user = self.cache.user(user_id); let member = self.cache.member(guild_id, user_id); match user.zip(member) { Some((user, member)) => Member { id: user_id, handle: user.name.clone(), global_name: user.global_name.clone(), nick: member.nick().map(<_>::to_owned), }, None => { let member = aumau!(self.http.guild_member(guild_id, user_id)); Member { id: user_id, handle: member.user.name, global_name: member.user.global_name, nick: member.nick, } } } } /// Check the database for a leaderboard belonging to this guild. If it /// does not exist, create one. Returns whether or not one existed before /// this function was called pub fn create_leaderboard_if_not_exists(&self, guild: Id) -> bool { if !self.db.leaderboard_exits(guild.get()) { self.db.create_leaderboard(guild.get()).unwrap(); false } else { true } } } pub struct Member { pub id: Id, pub handle: String, pub global_name: Option, pub nick: Option, }