diff --git a/src/tasks/status_update_mirror.rs b/src/tasks/status_update_mirror.rs index 997e698..30ef712 100644 --- a/src/tasks/status_update_mirror.rs +++ b/src/tasks/status_update_mirror.rs @@ -19,7 +19,11 @@ use super::Task; use crate::graphql::GraphQLClient; use anyhow::Context; use async_trait::async_trait; +use serenity::builder::CreateWebhook; +use serenity::builder::ExecuteWebhook; use serenity::client::Context as ClientContext; +use serenity::model::id::UserId; +use serenity::model::webhook::Webhook; use serenity::prelude::CacheHttp; use std::collections::HashMap; @@ -30,8 +34,6 @@ use chrono::{Datelike, Duration, Local, Timelike}; use chrono_tz::Asia::Kolkata; use mailparse::{MailHeaderMap, ParsedMail}; use poise::serenity_prelude::ChannelId; -use poise::serenity_prelude::CreateEmbed; -use poise::serenity_prelude::CreateMessage; pub struct EmailDetails { pub from: String, @@ -79,22 +81,77 @@ pub async fn mirror_new_updates(ctx: ClientContext, client: GraphQLClient) -> an if member.track.is_none() || member.group_id.is_none() { continue; } - send_update( - &ctx, - member.name.clone(), - member.track.clone().unwrap(), - member.group_id.unwrap(), - email.body.clone(), - ) - .await?; + if let Some(discord_id) = &member.discord_id { + let discord_id: u64 = discord_id.parse()?; + + send_update( + &ctx, + member.name.clone(), + discord_id, + member.track.clone().unwrap(), + member.group_id.unwrap(), + email.body.clone(), + ) + .await?; + } } } Ok(()) } +async fn get_or_create_webhook( + ctx: &ClientContext, + channel_id: ChannelId, +) -> anyhow::Result { + let hooks = channel_id.webhooks(ctx.http()).await?; + + if let Some(hook) = hooks + .into_iter() + .find(|h| h.name == Some("amD Updates".to_string())) + { + return Ok(hook); + } + + let webhook = channel_id + .create_webhook(ctx.http(), CreateWebhook::new("amD Updates")) + .await?; + + Ok(webhook) +} + +async fn send_webhook_message( + ctx: &ClientContext, + channel_id: ChannelId, + username: String, + avatar_url: String, + content: String, +) -> anyhow::Result<()> { + let webhook = get_or_create_webhook(ctx, channel_id).await?; + + let builder = ExecuteWebhook::new() + .username(username) + .avatar_url(avatar_url) + .content(content); + + webhook.execute(ctx.http(), false, builder).await?; + + Ok(()) +} + +async fn get_avatar_url(ctx: &ClientContext, discord_id: u64) -> anyhow::Result { + let user = ctx.http.get_user(UserId::new(discord_id)).await?; + + let avatar = user + .avatar_url() + .unwrap_or_else(|| user.default_avatar_url()); + + Ok(avatar) +} + async fn send_update( ctx: &ClientContext, name: String, + discord_id: u64, track: String, group: i32, content: String, @@ -111,14 +168,11 @@ async fn send_update( _ => STATUS_UPDATE_CHANNEL_ID, }; - let embed = CreateEmbed::new() - .title(format!("Status Update: {}", name)) - .description(content); + let channel = ChannelId::new(channel_id); - let msg = CreateMessage::new().embed(embed); + let avatar_url = get_avatar_url(ctx, discord_id).await?; - let channel = ChannelId::new(channel_id); - channel.send_message(ctx.http(), msg).await?; + send_webhook_message(ctx, channel, name, avatar_url, content).await?; Ok(()) }