summaryrefslogtreecommitdiff
path: root/src/events/pinboard.rs
blob: bb0dfe0a0fa7fa5717fedb4f47fba261b96670ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use crate::{client::Data, utils};

use eyre::{eyre, Context as _, OptionExt as _, Result};
use log::{debug, warn};
use poise::serenity_prelude::{
	ChannelId, Context, CreateAllowedMentions, CreateMessage, Message, MessageType, User,
};

pub async fn handle(ctx: &Context, message: &Message, data: &Data) -> Result<()> {
	if message.kind != MessageType::PinsAdd {
		return Ok(());
	}

	let gid = message.guild_id.unwrap_or_default();
	let Some(storage) = &data.storage else {
		warn!("Can't create PinBoard entry; no storage backend found!");
		return Ok(());
	};

	let settings = storage.get_guild_settings(&gid).await?;

	if !settings.pinboard_enabled {
		debug!("PinBoard is disabled in {gid}, ignoring");
		return Ok(());
	}

	let Some(target) = settings.pinboard_channel else {
		debug!("PinBoard is disabled in {gid}, ignoring");
		return Ok(());
	};

	if let Some(sources) = settings.pinboard_watch {
		if !sources.contains(&message.channel_id) {
			debug!(
				"{} not listed in PinBoard settings for {gid}, ignoring",
				message.channel_id
			);

			return Ok(());
		}
	}

	let reference_id = message
		.clone()
		.message_reference
		.ok_or_eyre("Couldn't get referenced message of pin!")?
		.message_id
		.ok_or_eyre("Couldn't get id of referenced message of pin!")?;

	let pins = message
		.channel_id
		.pins(ctx)
		.await
		.wrap_err("Couldn't get a list of pins!?")?;

	let pin = pins
		.iter()
		.find(|pin| pin.id == reference_id)
		.ok_or_else(|| eyre!("Couldn't find a pin for message {reference_id}!"))?;

	redirect(ctx, pin, &message.author, &target).await?;
	pin.unpin(ctx).await?;

	Ok(())
}

async fn redirect(ctx: &Context, pin: &Message, pinner: &User, target: &ChannelId) -> Result<()> {
	let embed = utils::resolve_message_to_embed(ctx, pin).await;
	let mentions = CreateAllowedMentions::new().empty_roles().empty_users();
	let message = CreateMessage::default()
		.allowed_mentions(mentions)
		.content(format!("📌'd by {pinner} in {}", pin.link()))
		.embed(embed);

	target
		.send_message(&ctx.http, message)
		.await
		.wrap_err("Couldn't redirect message")?;

	Ok(())
}