1use std::sync::Arc;
2
3use twilight_gateway::Event;
4use twilight_model::gateway::payload::incoming::InteractionCreate;
5
6pub use context::{Context, EventContext, InteractionContext};
7pub use framework::Framework;
8pub use metadata::Metadata;
9pub use module::{Module, builder::ModuleBuilder, registry::Registry};
10
11pub mod context;
12pub mod framework;
13pub mod handler;
14pub mod interaction;
15pub mod macros;
16pub mod metadata;
17pub mod module;
18pub mod scheduler;
19
20pub type Error = Box<dyn std::error::Error + Send + Sync>;
21
22pub async fn handle_interaction<T: Clone + Send + Sync + 'static>(
23 event: InteractionCreate,
24 context: Context<T>,
25 meta: &Metadata,
26 registry: &Registry<T>,
27) -> Result<(), Error> {
28 tracing::info!("interaction");
29
30 match interaction::parse(&event, meta.clone(), context) {
31 Ok(InteractionContext::Command(ctx)) => {
32 let Some(command) = registry.find_command(&ctx.name) else {
33 return Err(format!("unknown command /{}", ctx.name).into());
34 };
35
36 if let Err(err) = command.run(ctx.clone()).await {
37 return Err(format!("error running command /{}: {}", ctx.name, err).into());
38 }
39 }
40 Ok(InteractionContext::ComponentInteraction(ctx)) => {
41 let Some(component_interaction) = registry.components.get(&ctx.interaction.custom_id)
42 else {
43 return Err(format!(
44 "no handler for component interaction {}",
45 ctx.interaction.custom_id
46 )
47 .into());
48 };
49
50 if let Err(err) = component_interaction.run(ctx.clone()).await {
51 return Err(format!(
52 "error handling component interaction {}: {}",
53 ctx.interaction.custom_id, err
54 )
55 .into());
56 }
57 }
58 Ok(InteractionContext::Modal(_modal_context)) => {
59 todo!()
60 }
61 Err(err) => return Err(format!("error handling interaction: {}", err).into()),
62 };
63
64 Ok(())
65}
66
67pub async fn handle<T: Clone + Send + Sync + 'static>(
68 meta: Metadata,
69 ctx: Context<T>,
70 registry: &Registry<T>,
71 event: Event,
72) {
73 if let twilight_gateway::Event::InteractionCreate(event) = event.clone()
74 && let Err(err) = handle_interaction(*event, ctx.clone(), &meta, registry).await
75 {
76 tracing::warn!(err);
77 }
78
79 if let Some(handlers) = registry.events.get(&event.kind()) {
80 tracing::info!("running event handlers for {:?}", event.kind());
81
82 for handler in handlers {
83 let event_ctx = EventContext {
84 meta: meta.clone(),
85 application_id: ctx.application_id,
86 client: Arc::clone(&ctx.client),
87 services: Arc::clone(&ctx.services),
88
89 event: event.clone(),
90 };
91
92 if let Err(err) = handler.run(event_ctx).await {
93 tracing::warn!("error running event handler {}: {}", handler.uuid, err);
94 }
95 }
96 }
97}