83 lines
2.7 KiB
Rust
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))
|
|
}
|
|
}
|