use std::sync::Arc; use super::config::Config; use super::miniflux_requests::{Entry, Feed, MinifluxEvent, NewEntries}; use serenity::all::{ Cache, Color, CreateButton, CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter, CreateMessage, Http, UserId, }; use thiserror::Error; #[derive(Clone)] pub struct DiscordHolder { pub cache: Arc, pub http: Arc, pub config: Config, } #[derive(Error, Debug)] pub enum DiscordError { #[error("Discord API error: {0}")] DiscordApiError(#[from] serenity::Error), } impl DiscordHolder { pub async fn send(&self, userid: u64, event: MinifluxEvent) -> Result<(), DiscordError> { let user = self.http.get_user(UserId::new(userid)).await?; match event { MinifluxEvent::New(NewEntries { feed, entries }) => { for entry in entries { user.direct_message( (&self.cache, self.http.as_ref()), self.message_from_entry(&entry, &feed)?, ) .await?; log::info!("Entry {} sent to user {}", entry.id, user.name); } } _ => {} }; Ok(()) } fn message_from_entry( &self, entry: &Entry, feed: &Feed, ) -> Result { let author = CreateEmbedAuthor::new(&feed.title).url(&feed.site_url); let footer = CreateEmbedFooter::new(format!("{} minutes", entry.reading_time.to_string())); let miniflux_url = format!("{}/feed/{}/entry/{}", self.config.miniflux_base_url, feed.id, entry.id); let mut embed = CreateEmbed::new() .title(&entry.title) .url(&entry.url) .footer(footer) .timestamp(entry.published_at) .author(author) .color(Color::from_rgb( (feed.id % 256) as u8, ((feed.id * feed.id) % 256) as u8, ((feed.id * feed.id * feed.id) % 256) as u8, )) .description(&entry.content.chars().take(200).collect::()); if entry.tags.len() > 0 { embed = embed.field("Tags", entry.tags.join(","), true) } if let Some(enclosure) = entry.enclosures.iter().find(|e| e.mime_type.starts_with("image/")) { embed = embed.image(&enclosure.url); } let external_button = CreateButton::new_link(&entry.url).label("external").emoji('📤'); let miniflux_button = CreateButton::new_link(miniflux_url).label("miniflux").emoji('📩'); Ok(CreateMessage::new().embed(embed).button(external_button).button(miniflux_button)) } }