Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 80 additions & 8 deletions src/tasks/status_update_mirror.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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,
Expand Down Expand Up @@ -79,9 +81,11 @@ 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.discord_id.as_deref(),
member.track.clone().unwrap(),
member.group_id.unwrap(),
email.body.clone(),
Expand All @@ -92,9 +96,80 @@ pub async fn mirror_new_updates(ctx: ClientContext, client: GraphQLClient) -> an
Ok(())
}

async fn get_or_create_webhook(
ctx: &ClientContext,
channel_id: ChannelId,
) -> anyhow::Result<Webhook> {
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<String> {
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 get_bot_avatar_url(ctx: &ClientContext) -> anyhow::Result<String> {
let bot_user = ctx.http.get_current_user().await?;

Ok(bot_user
.avatar_url()
.unwrap_or_else(|| bot_user.default_avatar_url()))
}

async fn resolve_avatar_url(
ctx: &ClientContext,
discord_id: Option<&str>,
) -> anyhow::Result<String> {
match discord_id {
Some(id_str) => match id_str.parse::<u64>() {
Ok(id) => get_avatar_url(ctx, id).await,
Err(_) => get_bot_avatar_url(ctx).await,
},
None => get_bot_avatar_url(ctx).await,
}
}

async fn send_update(
ctx: &ClientContext,
name: String,
discord_id: Option<&str>,
track: String,
group: i32,
content: String,
Expand All @@ -111,14 +186,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 = resolve_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(())
}
Expand Down
Loading