miniflux-discord/src/discord.rs

83 lines
2.7 KiB
Rust

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<Cache>,
pub http: Arc<Http>,
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<CreateMessage, DiscordError> {
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::<String>());
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))
}
}