Skip to main content

babyrite/
event.rs

1//! Event handling module for Discord events.
2//!
3//! This module implements the serenity [`EventHandler`] trait to handle
4//! Discord gateway events such as ready and message events.
5
6use crate::preview::{MessageLinkIDs, Preview};
7use serenity::all::{ActivityData, Context, EventHandler, Message, Ready};
8use serenity_builder::model::{
9    embed::SerenityEmbed,
10    message::{SerenityMessage, SerenityMessageMentionType},
11};
12
13/// Event handler for Babyrite bot.
14pub struct BabyriteEventHandler;
15
16#[serenity::async_trait]
17impl EventHandler for BabyriteEventHandler {
18    async fn ready(&self, ctx: Context, bot: Ready) {
19        ctx.set_activity(
20            ActivityData::custom(format!("Running v{}", env!("CARGO_PKG_VERSION"))).into(),
21        );
22        tracing::info!("{} is connected!", bot.user.name);
23    }
24
25    async fn message(&self, ctx: Context, request: Message) {
26        if request.author.bot {
27            return;
28        }
29
30        let request_guild_id = match request.guild_id {
31            Some(id) => id,
32            None => return,
33        };
34
35        let ids = match MessageLinkIDs::parse(&request.content) {
36            Some(ids) if ids.guild_id == request_guild_id => ids,
37            _ => return,
38        };
39
40        tracing::info!(
41            "Begin generating the preview. (Requester: {})",
42            &request.author.name
43        );
44
45        let preview = match Preview::get(ids, &ctx).await {
46            Ok(p) => p,
47            Err(e) => {
48                tracing::error!("{}", e);
49                return;
50            }
51        };
52
53        let (message, channel) = (preview.message, preview.channel);
54        let embed = SerenityEmbed::builder()
55            .description(message.content)
56            .author_name(message.author.name.clone())
57            .author_icon_url(message.author.avatar_url().unwrap_or_default())
58            .footer_text(channel.name)
59            .timestamp(message.timestamp)
60            .color(0x7A4AFFu32)
61            .image_url(
62                message
63                    .attachments
64                    .first()
65                    .map(|a| a.url.clone())
66                    .unwrap_or_default(),
67            )
68            .build();
69
70        let request_channel_id = request.channel_id;
71        let message_builder = SerenityMessage::builder()
72            .embeds(vec![embed])
73            .mention_type(SerenityMessageMentionType::Reply(Box::new(request)))
74            .build();
75
76        let converted_message = match message_builder.convert() {
77            Ok(m) => m,
78            Err(e) => {
79                tracing::error!(?e);
80                return;
81            }
82        };
83
84        if let Err(e) = request_channel_id
85            .send_message(&ctx.http, converted_message)
86            .await
87        {
88            tracing::error!("Failed to send preview: {:?}", e);
89        }
90
91        tracing::info!("Preview sent successfully.")
92    }
93}