1- use std:: { collections:: HashMap , rc:: Rc , sync:: Arc } ;
1+ use std:: {
2+ collections:: HashMap ,
3+ fs:: File ,
4+ rc:: Rc ,
5+ sync:: { Arc , OnceLock } ,
6+ } ;
27
38use serenity:: {
4- all:: { Context , EventHandler , GatewayIntents , Message } ,
9+ all:: { ChannelId , Context , CreateMessage , Event , EventHandler , GatewayIntents , Message , Nonce , RawEventHandler } ,
510 async_trait,
611 futures:: SinkExt ,
712} ;
13+ use std:: io:: Write ;
814use tokio:: sync:: { broadcast, Mutex , RwLock } ;
915
1016use crate :: {
@@ -18,49 +24,84 @@ use crate::{
1824
1925#[ derive( Default ) ]
2026pub struct DiscordClient {
21- channel_message_event_handlers : HashMap < Snowflake , Vec < broadcast:: Sender < DiscordMessage > > > ,
27+ channel_message_event_handlers : RwLock < HashMap < Snowflake , Vec < broadcast:: Sender < DiscordMessage > > > > ,
28+ client : OnceLock < serenity:: Client > ,
29+ user : OnceLock < DiscordMessageAuthor > ,
2230}
2331
2432impl DiscordClient {
25- pub fn new ( token : String ) -> Arc < RwLock < DiscordClient > > {
26- let client = Arc :: new ( RwLock :: new ( DiscordClient :: default ( ) ) ) ;
27- let remote = RemoteDiscordClient ( client. clone ( ) ) ;
33+ pub async fn new ( token : String ) -> Arc < DiscordClient > {
34+ let client = Arc :: new ( DiscordClient :: default ( ) ) ;
2835
29- tokio:: spawn ( async {
30- let mut client = serenity:: Client :: builder ( token, GatewayIntents :: all ( ) ) . event_handler ( remote) . await . expect ( "Error creating client" ) ;
36+ let mut discord = serenity:: Client :: builder ( token, GatewayIntents :: all ( ) )
37+ . event_handler_arc ( client. clone ( ) )
38+ . raw_event_handler ( RawClient ( client. clone ( ) ) )
39+ . await
40+ . expect ( "Error creating client" ) ;
3141
32- if let Err ( why) = client. start ( ) . await {
33- panic ! ( "Client error: {why:?}" ) ;
34- }
35- } ) ;
42+ if let Err ( why) = discord. start ( ) . await {
43+ panic ! ( "Client error: {why:?}" ) ;
44+ }
45+
46+ let _ = client. client . set ( discord) ;
3647
3748 client
3849 }
3950
40- pub async fn add_channel_message_sender ( & mut self , channel : Snowflake , sender : broadcast:: Sender < DiscordMessage > ) {
41- self . channel_message_event_handlers . entry ( channel) . or_default ( ) . push ( sender) ;
51+ fn discord ( & self ) -> & serenity:: Client {
52+ self . client . get ( ) . unwrap ( )
53+ }
54+
55+ pub fn user ( & self ) -> & DiscordMessageAuthor {
56+ self . user . get ( ) . unwrap ( )
57+ }
58+
59+ pub async fn add_channel_message_sender ( & self , channel : Snowflake , sender : broadcast:: Sender < DiscordMessage > ) {
60+ self . channel_message_event_handlers . write ( ) . await . entry ( channel) . or_default ( ) . push ( sender) ;
61+ }
62+
63+ pub async fn send_message ( & self , channel_id : Snowflake , content : String , nonce : String ) {
64+ ChannelId :: new ( channel_id. content )
65+ . send_message (
66+ self . discord ( ) . http . clone ( ) ,
67+ CreateMessage :: new ( ) . content ( content) . enforce_nonce ( true ) . nonce ( serenity:: all:: Nonce :: String ( nonce) ) ,
68+ )
69+ . await
70+ . unwrap ( ) ;
4271 }
4372}
4473
45- struct RemoteDiscordClient ( Arc < RwLock < DiscordClient > > ) ;
74+ struct RawClient ( Arc < DiscordClient > ) ;
4675
4776#[ async_trait]
48- impl EventHandler for RemoteDiscordClient {
49- async fn ready ( & self , ctx : Context , data_about_bot : serenity:: model:: prelude:: Ready ) {
50- println ! ( "Ready! {:?}" , data_about_bot) ;
77+ impl RawEventHandler for RawClient {
78+ async fn raw_event ( & self , ctx : Context , ev : serenity:: model:: prelude:: Event ) {
79+ if let Event :: Unknown ( unk) = ev {
80+ if unk. kind == "READY" {
81+ let user = unk. value . as_object ( ) . unwrap ( ) . get ( "user" ) . unwrap ( ) . as_object ( ) . unwrap ( ) ;
82+
83+ self . 0 . user . get_or_init ( || DiscordMessageAuthor {
84+ display_name : DisplayName ( user. get ( "username" ) . unwrap ( ) . as_str ( ) . unwrap ( ) . to_owned ( ) ) ,
85+ icon : format ! (
86+ "https://cdn.discordapp.com/avatars/{}/{}" ,
87+ user. get( "id" ) . unwrap( ) . as_str( ) . unwrap( ) ,
88+ user. get( "avatar" ) . unwrap( ) . as_str( ) . unwrap( )
89+ ) ,
90+ } ) ;
91+ }
92+ }
5193 }
94+ }
5295
96+ #[ async_trait]
97+ impl EventHandler for DiscordClient {
5398 async fn message ( & self , _: Context , msg : Message ) {
54- println ! ( "Got message: {:?} {:?}" , msg. channel_id, msg. content) ;
55-
5699 let snowflake = Snowflake {
57100 content : msg. channel_id . get ( ) ,
58101 } ;
59102
60- if let Some ( vec) = self . 0 . read ( ) . await . channel_message_event_handlers . get ( & snowflake) {
103+ if let Some ( vec) = self . channel_message_event_handlers . read ( ) . await . get ( & snowflake) {
61104 for sender in vec {
62- println ! ( "Sending to sender!" ) ;
63-
64105 let _ = sender. send ( DiscordMessage {
65106 id : snowflake,
66107 author : DiscordMessageAuthor {
@@ -69,7 +110,12 @@ impl EventHandler for RemoteDiscordClient {
69110 } ,
70111 content : DiscordMessageContent {
71112 content : msg. content . clone ( ) ,
113+ is_pending : false ,
72114 } ,
115+ nonce : msg. nonce . clone ( ) . map ( |n| match n {
116+ Nonce :: Number ( n) => n. to_string ( ) ,
117+ Nonce :: String ( s) => s,
118+ } ) ,
73119 } ) ;
74120 }
75121 }
0 commit comments