2021-11-12 12:02:22 +00:00
use std ::sync ::atomic ::AtomicBool ;
2023-08-23 17:37:42 +00:00
use poise ::{ Event , FrameworkContext } ;
use poise ::serenity_prelude ::model ::{
2021-11-12 12:02:22 +00:00
gateway ::Ready ,
} ;
2023-09-19 11:49:29 +00:00
use poise ::serenity_prelude ::{ ChannelId , Colour , Context , GuildId , Member , Message , MessageId , Role , RoleId , Timestamp , User } ;
2023-08-24 09:27:15 +00:00
use crate ::ManifoldData ;
2023-08-23 17:37:42 +00:00
use crate ::error ::{ ManifoldError , ManifoldResult } ;
use crate ::models ::user ::UserInfo ;
2021-11-12 12:02:22 +00:00
pub struct Handler {
2021-11-12 12:15:59 +00:00
pub timer_running : AtomicBool ,
2021-11-12 12:02:22 +00:00
}
impl Handler {
pub fn new ( ) -> Self {
Handler {
timer_running : AtomicBool ::from ( false )
}
}
2023-08-23 17:37:42 +00:00
pub async fn listen ( ctx : & Context , framework_ctx : FrameworkContext < '_ , ManifoldData , ManifoldError > , event : & Event < '_ > ) -> ManifoldResult < ( ) > {
match event {
Event ::Ready { data_about_bot } = > Handler ::standard_startup ( & ctx , & framework_ctx , data_about_bot ) . await ,
2023-09-19 11:49:29 +00:00
Event ::GuildBanAddition { guild_id , banned_user } = > Handler ::ban_add ( & ctx , & framework_ctx , guild_id , banned_user ) . await ,
Event ::GuildBanRemoval { guild_id , unbanned_user } = > Handler ::ban_remove ( & ctx , & framework_ctx , guild_id , unbanned_user ) . await ,
Event ::GuildMemberAddition { new_member } = > Handler ::new_member ( & ctx , & framework_ctx , & new_member ) . await ,
Event ::GuildMemberRemoval { guild_id , user , member_data_if_available } = > Handler ::member_leave ( & ctx , & framework_ctx , guild_id , user , member_data_if_available ) . await ,
Event ::GuildMemberUpdate { old_if_available , new } = > Handler ::member_update ( & ctx , & framework_ctx , old_if_available , new ) . await ,
Event ::GuildRoleCreate { new } = > Handler ::new_role ( & ctx , & framework_ctx , new ) . await ,
Event ::GuildRoleDelete { guild_id , removed_role_id , removed_role_data_if_available } = > Handler ::delete_role ( & ctx , & framework_ctx , guild_id , removed_role_id , removed_role_data_if_available ) . await ,
Event ::GuildRoleUpdate { old_data_if_available , new } = > Handler ::update_role ( & ctx , & framework_ctx , old_data_if_available , new ) . await ,
2023-08-23 17:37:42 +00:00
Event ::Message { new_message } = > Handler ::message ( & ctx , & framework_ctx , & new_message ) . await ,
2023-09-19 11:49:29 +00:00
Event ::MessageDelete { channel_id , deleted_message_id , guild_id } = > Handler ::message_deleted ( & ctx , & framework_ctx , channel_id , deleted_message_id , guild_id ) . await ,
2023-08-24 22:19:48 +00:00
Event ::MessageUpdate { old_if_available , new , event : _event } = > Handler ::message_edited ( & ctx , & framework_ctx , old_if_available , new ) . await ,
2023-08-23 17:37:42 +00:00
_ = > Ok ( ( ) )
}
}
2021-11-12 12:02:22 +00:00
2023-08-23 17:37:42 +00:00
pub async fn standard_startup ( ctx : & Context , framework_ctx : & FrameworkContext < '_ , ManifoldData , ManifoldError > , data_about_bot : & Ready ) -> ManifoldResult < ( ) > {
let config = & framework_ctx . user_data ( ) . await . bot_config ;
let responses = & framework_ctx . user_data ( ) . await . responses ;
2021-11-12 12:02:22 +00:00
2023-08-24 22:19:48 +00:00
2021-11-12 12:02:22 +00:00
let greeting = match responses . get_response ( & " bot startup " . to_string ( ) ) {
2023-08-23 17:37:42 +00:00
Some ( g ) = > g . to_owned ( ) ,
2021-11-12 12:02:22 +00:00
None = > " Manifold bot connected to discord and ready to begin broadcast operations. " . to_string ( ) ,
} ;
2023-08-23 17:37:42 +00:00
for guild in & data_about_bot . guilds {
2023-08-30 15:53:24 +00:00
match guild . id . edit_nickname ( & ctx , Some ( & * config . nickname ) ) . await {
2021-11-17 15:12:21 +00:00
Ok ( ( ) ) = > ( ) ,
Err ( e ) = > {
error! ( " Error setting bot nickname (lack permission?): {:?} " , e ) ;
}
}
}
2021-11-12 12:02:22 +00:00
2023-08-30 15:53:24 +00:00
config . channels . log . say ( & ctx , greeting ) . await . expect ( " Couldn't message log channel! " ) ;
2023-08-23 17:37:42 +00:00
Ok ( ( ) )
2021-11-12 12:02:22 +00:00
}
2021-11-19 23:37:59 +00:00
2023-09-19 11:49:29 +00:00
async fn ban_add ( ctx : & Context , fctx : & FrameworkContext < '_ , ManifoldData , ManifoldError > , _guild_id : & GuildId , banned_user : & User ) -> ManifoldResult < ( ) > {
let log_channel = fctx . user_data ( ) . await . bot_config . channels . log ;
log_channel . send_message ( ctx , | f | {
f
. content ( " " )
. embed ( | e | {
e
. title ( format! ( " {} was banned " , banned_user . name ) )
. colour ( Colour ::from_rgb ( 255 , 0 , 0 ) )
. timestamp ( Timestamp ::now ( ) )
} )
} ) . await ? ;
Ok ( ( ) )
}
async fn ban_remove ( ctx : & Context , fctx : & FrameworkContext < '_ , ManifoldData , ManifoldError > , _guild_id : & GuildId , unbanned_user : & User ) -> ManifoldResult < ( ) > {
let log_channel = fctx . user_data ( ) . await . bot_config . channels . log ;
log_channel . send_message ( ctx , | f | {
f
. content ( " " )
. embed ( | e | {
e
. title ( format! ( " Ban was lifted for {} " , unbanned_user . name ) )
. colour ( Colour ::from_rgb ( 0 , 255 , 0 ) )
. timestamp ( Timestamp ::now ( ) )
} )
} ) . await ? ;
Ok ( ( ) )
}
async fn new_member ( ctx : & Context , fctx : & FrameworkContext < '_ , ManifoldData , ManifoldError > , new_member : & Member ) -> ManifoldResult < ( ) > {
let log_channel = fctx . user_data ( ) . await . bot_config . channels . log ;
log_channel . send_message ( ctx , | f | {
f
. content ( " " )
. embed ( | e | {
e
. title ( format! ( " {} joined the server with nickname {} ( {} ) " , new_member . user . name , new_member . nick . as_ref ( ) . unwrap_or ( & new_member . user . name ) , new_member . user . id ) )
. colour ( Colour ::from_rgb ( 0 , 255 , 0 ) )
. timestamp ( new_member . joined_at . unwrap_or ( Timestamp ::now ( ) ) )
. field ( " Account creation date " , new_member . user . created_at ( ) , false )
} )
} ) . await ? ;
Ok ( ( ) )
}
async fn member_leave ( ctx : & Context , fctx : & FrameworkContext < '_ , ManifoldData , ManifoldError > , _guild_id : & GuildId , user : & User , _member_data_if_available : & Option < Member > ) -> ManifoldResult < ( ) > {
let log_channel = fctx . user_data ( ) . await . bot_config . channels . log ;
log_channel . send_message ( ctx , | f | {
f
. content ( " " )
. embed ( | e | {
e
. title ( format! ( " {} left the server " , user . name ) )
. colour ( Colour ::from_rgb ( 255 , 0 , 0 ) )
. timestamp ( Timestamp ::now ( ) )
} )
} ) . await ? ;
Ok ( ( ) )
}
async fn member_update ( _ctx : & Context , _fctx : & FrameworkContext < '_ , ManifoldData , ManifoldError > , _old_if_available : & Option < Member > , _new : & Member ) -> ManifoldResult < ( ) > {
Ok ( ( ) )
}
async fn new_role ( ctx : & Context , fctx : & FrameworkContext < '_ , ManifoldData , ManifoldError > , new : & Role ) -> ManifoldResult < ( ) > {
let log_channel = fctx . user_data ( ) . await . bot_config . channels . log ;
log_channel . send_message ( ctx , | f | {
f
. content ( " " )
. embed ( | e | {
e
. title ( format! ( " New role {} ( {} ) was created " , & new . name , & new . id ) )
. colour ( Colour ::from_rgb ( 0 , 255 , 0 ) )
. timestamp ( Timestamp ::now ( ) )
. field ( " Role Permissions " , & new . permissions , false )
. field ( " Hoist " , & new . hoist , true )
. field ( " Icon " , & new . icon . clone ( ) . unwrap_or ( " None set " . to_string ( ) ) , true )
. field ( " Mentionable " , & new . mentionable , true )
} )
} ) . await ? ;
Ok ( ( ) )
}
async fn delete_role ( ctx : & Context , fctx : & FrameworkContext < '_ , ManifoldData , ManifoldError > , _guild_id : & GuildId , removed_role_id : & RoleId , removed_role_data_if_available : & Option < Role > ) -> ManifoldResult < ( ) > {
let log_channel = fctx . user_data ( ) . await . bot_config . channels . log ;
log_channel . send_message ( ctx , | f | {
f
. content ( " " )
. embed ( | e | {
match removed_role_data_if_available {
Some ( role ) = > {
return e
. title ( format! ( " Role {} ( {} ) was deleted " , & role . name , & role . id ) )
. colour ( Colour ::from_rgb ( 255 , 0 , 0 ) )
. timestamp ( Timestamp ::now ( ) )
. field ( " Role Permissions " , & role . permissions , false )
. field ( " Hoist " , & role . hoist , true )
. field ( " Icon " , & role . icon . clone ( ) . unwrap_or ( " None set " . to_string ( ) ) , true )
. field ( " Mentionable " , & role . mentionable , true )
} ,
None = > {
return e
. title ( format! ( " Role {} was deleted (Role was not cached) " , removed_role_id ) )
. colour ( Colour ::from_rgb ( 255 , 0 , 0 ) )
. timestamp ( Timestamp ::now ( ) )
}
} ;
} )
} ) . await ? ;
Ok ( ( ) )
}
async fn update_role ( _ctx : & Context , _fctx : & FrameworkContext < '_ , ManifoldData , ManifoldError > , _old_data_if_available : & Option < Role > , _new : & Role ) -> ManifoldResult < ( ) > {
Ok ( ( ) )
}
2023-08-23 17:37:42 +00:00
async fn message ( _ctx : & Context , fctx : & FrameworkContext < '_ , ManifoldData , ManifoldError > , msg : & Message ) -> ManifoldResult < ( ) > {
let userinfo = & mut fctx . user_data ( ) . await . user_info . lock ( ) . await ;
if let Some ( u ) = userinfo . get_mut ( & msg . author . id . as_u64 ( ) ) {
u . last_seen = Some ( chrono ::Utc ::now ( ) . timestamp ( ) ) ;
} else {
let new_user = UserInfo {
user_id : msg . author . id . as_u64 ( ) . clone ( ) as i64 ,
username : msg . author . name . to_owned ( ) ,
weather_location : None ,
weather_units : None ,
timezone : None ,
last_seen : Some ( chrono ::Utc ::now ( ) . timestamp ( ) ) ,
} ;
userinfo . insert ( msg . author . id . as_u64 ( ) . clone ( ) , new_user ) ;
}
Ok ( ( ) )
}
2023-09-19 11:49:29 +00:00
async fn message_deleted ( ctx : & Context , fctx : & FrameworkContext < '_ , ManifoldData , ManifoldError > , channel_id : & ChannelId , deleted_message_id : & MessageId , _guild_id : & Option < GuildId > ) -> ManifoldResult < ( ) > {
let log_channel = fctx . user_data ( ) . await . bot_config . channels . log ;
let mut content : String = " Not Available / Not Cached " . to_string ( ) ;
let author ;
let channel = match ctx . cache . guild_channel ( channel_id ) {
Some ( c ) = > c . name ,
None = > format! ( " Not Available / Not Cached ( {} ) " , channel_id )
} ;
if let Some ( msg ) = ctx . cache . message ( channel_id , deleted_message_id ) {
content = msg . content_safe ( & ctx . cache ) ;
author = msg . author ;
} else {
author = User ::default ( ) ;
}
log_channel . send_message ( ctx , | f | {
f
. content ( " " )
. embed ( | e | {
e
. title ( format! ( " Message removed in # {} ( {} ) " , channel , channel_id ) )
. colour ( Colour ::from_rgb ( 255 , 0 , 0 ) )
. author ( | a | a . name ( author . name ) )
. field ( " Message Content " , content , false )
. timestamp ( Timestamp ::now ( ) )
. footer ( | f | f . text ( author . id ) )
} )
} ) . await ? ;
Ok ( ( ) )
}
2023-08-23 17:37:42 +00:00
async fn message_edited ( ctx : & Context , fctx : & FrameworkContext < '_ , ManifoldData , ManifoldError > , original : & Option < Message > , new_message : & Option < Message > ) -> ManifoldResult < ( ) > {
2023-08-30 15:53:24 +00:00
let log_channel = fctx . user_data ( ) . await . bot_config . channels . log ;
2023-08-23 17:37:42 +00:00
if let Some ( new ) = new_message . as_ref ( ) {
2023-09-19 11:49:29 +00:00
let message_channel = new . channel_id . name ( ctx ) . await . unwrap_or ( " Unknown Channel " . to_string ( ) ) ;
2023-08-23 17:37:42 +00:00
log_channel . send_message ( ctx , | f | {
f
. content ( " " )
. embed ( | e | {
e
2023-09-19 11:49:29 +00:00
. title ( format! ( " Message updated in # {} ( {} ) " , message_channel , new . channel_id ) )
. colour ( Colour ::from_rgb ( 255 , 153 , 0 ) )
2023-08-23 17:37:42 +00:00
. author ( | a | a . name ( new . author . name . clone ( ) ) )
2023-09-19 11:49:29 +00:00
. timestamp ( Timestamp ::now ( ) )
2023-08-23 17:37:42 +00:00
. field ( " Original Content " , match original . as_ref ( ) {
Some ( m ) = > m . content . clone ( ) ,
None = > " Not available " . to_string ( ) ,
} , false )
. field ( " New Content " , new . content . clone ( ) , false )
2023-09-19 11:49:29 +00:00
. field ( " Message created at " , new . timestamp , true )
. field ( " Message author " , & new . author . id , true )
2023-08-23 17:37:42 +00:00
} )
} ) . await ? ;
}
Ok ( ( ) )
2021-11-19 23:37:59 +00:00
}
}