From 62c3c08adf190d43bf1e60213d09a02391019150 Mon Sep 17 00:00:00 2001 From: JandereDev Date: Mon, 18 Apr 2022 13:25:14 +0200 Subject: [PATCH] bridge replies from revolt --- bridge/src/revolt/events.ts | 46 +++++++++++++++++++++++--- bridge/src/util.ts | 66 +++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 bridge/src/util.ts diff --git a/bridge/src/revolt/events.ts b/bridge/src/revolt/events.ts index 812897d..f4f14cc 100644 --- a/bridge/src/revolt/events.ts +++ b/bridge/src/revolt/events.ts @@ -2,9 +2,10 @@ import axios from "axios"; import { BRIDGED_MESSAGES, BRIDGE_CONFIG, logger } from ".."; import { client } from "./client"; import { client as discordClient } from "../discord/client"; -import { WebhookClient } from "discord.js"; +import { MessageEmbed, WebhookClient } from "discord.js"; import GenericEmbed from "../types/GenericEmbed"; import { SendableEmbed } from "revolt-api"; +import { clipText, discordFetchMessage, discordFetchUser, revoltFetchMessage, revoltFetchUser } from "../util"; client.on('message', async message => { try { @@ -14,7 +15,7 @@ client.on('message', async message => { const [ bridgeCfg, bridgedMsg, ...repliedMessages ] = await Promise.all([ BRIDGE_CONFIG.findOne({ revolt: message.channel_id }), BRIDGED_MESSAGES.findOne({ "revolt.nonce": message.nonce }), - //...(message.reply_ids?.map(id => BRIDGED_MESSAGES.findOne({ "revolt.messageId": id })) ?? []) + ...(message.reply_ids?.map(id => BRIDGED_MESSAGES.findOne({ "revolt.messageId": id })) ?? []) ]); if (bridgedMsg) return logger.debug(`Revolt: Message has already been bridged; ignoring`); @@ -46,7 +47,7 @@ client.on('message', async message => { token: bridgeCfg.discordWebhook.token, }); - client.send({ + const payload = { content: `${message.content}`, username: message.author?.username ?? 'Unknown user', avatarURL: message.author?.generateAvatarURL({ max_side: 128 }), @@ -55,7 +56,44 @@ client.on('message', async message => { .filter(e => e.type == "Text") .map(e => new GenericEmbed(e as SendableEmbed).toDiscord()) : undefined, - }) + }; + + if (repliedMessages.length) { + const embed = new MessageEmbed().setColor('#2f3136'); + + if (repliedMessages.length == 1) { + const replyMsg = await discordFetchMessage(repliedMessages[0]?.discord.messageId, bridgeCfg.discord); + const author = replyMsg?.author; + + embed.setAuthor({ + name: `@${author?.username ?? 'Unknown'}`, // todo: check if @pinging was enabled for reply + iconURL: author?.displayAvatarURL({ size: 64, dynamic: true }), + url: replyMsg?.url, + }); + + if (replyMsg?.content) embed.setDescription('>>> ' + clipText(replyMsg.content, 200)); + } else { + const replyMsgs = await Promise.all( + repliedMessages.map(m => discordFetchMessage(m?.discord.messageId, bridgeCfg.discord)) + ); + + embed.setAuthor({ name: repliedMessages.length + ' replies' }); + + for (const msg of replyMsgs) { + embed.addField( + `@${msg?.author.username ?? 'Unknown'}`, + (msg ? `[Link](${msg.url})\n` : '') + + '>>> ' + clipText(msg?.content ?? '\u200b', 100), + true, + ); + } + } + + if (payload.embeds) payload.embeds.unshift(embed); + else payload.embeds = [ embed ]; + } + + client.send(payload) .then(async res => { await BRIDGED_MESSAGES.update({ "revolt.messageId": message._id diff --git a/bridge/src/util.ts b/bridge/src/util.ts new file mode 100644 index 0000000..76f781e --- /dev/null +++ b/bridge/src/util.ts @@ -0,0 +1,66 @@ +import { Channel } from "@janderedev/revolt.js/dist/maps/Channels"; +import { Message } from "@janderedev/revolt.js/dist/maps/Messages"; +import { User } from "@janderedev/revolt.js/dist/maps/Users"; +import { Message as DiscordMessage, TextChannel, User as DiscordUser } from "discord.js"; +import { client as discordClient } from "./discord/client"; +import { client as revoltClient } from "./revolt/client" + +// Grab user from cache or fetch, return undefined if error +async function revoltFetchUser(id?: string): Promise { + if (!id) return undefined; + + let user = revoltClient.users.get(id); + if (user) return user; + + try { user = await revoltClient.users.fetch(id) } catch(_) { } + + return user; +} + +async function revoltFetchMessage(id: string, channel: Channel): Promise { + let message = revoltClient.messages.get(id); + if (message) return message; + + try { message = await channel.fetchMessage(id) } catch(_) { } + + return message; +} + +async function discordFetchMessage(id?: string, channelId?: string): Promise { + if (!id || !channelId) return undefined; + + const channel = discordClient.channels.cache.get(channelId); + if (!channel || !(channel instanceof TextChannel)) return undefined; + + let message = channel.messages.cache.get(id); + if (message) return message; + + try { message = await channel.messages.fetch(id) } catch(_) { } + + return message; +} + +// doesnt seem to work idk +async function discordFetchUser(id?: string): Promise { + if (!id) return undefined; + + let user = discordClient.users.cache.get(id); + if (user) return user; + + try { user = await discordClient.users.fetch(id) } catch(_) { } + + return user; +} + +function clipText(text: string, limit: number) { + if (text.length < limit) return text; + else return text.substring(0, limit-4) + ' ...'; +} + +export { + revoltFetchUser, + revoltFetchMessage, + discordFetchMessage, + discordFetchUser, + clipText, +}