diff --git a/bridge/package.json b/bridge/package.json index 51a962a..97b3d9e 100644 --- a/bridge/package.json +++ b/bridge/package.json @@ -17,6 +17,7 @@ "axios": "^0.26.1", "discord.js": "^13.6.0", "dotenv": "^16.0.0", + "form-data": "^4.0.0", "log75": "^2.2.0", "monk": "^7.3.4", "revolt-api": "^0.5.3-rc.8", diff --git a/bridge/src/discord/events.ts b/bridge/src/discord/events.ts index 1313e8a..8aa320f 100644 --- a/bridge/src/discord/events.ts +++ b/bridge/src/discord/events.ts @@ -1,15 +1,16 @@ import { BRIDGED_MESSAGES, BRIDGE_CONFIG, logger } from ".."; import { client } from "./client"; -import { client as revoltClient } from "../revolt/client"; +import { AUTUMN_URL, client as revoltClient } from "../revolt/client"; import { ChannelPermission } from "@janderedev/revolt.js"; import axios from 'axios'; import { ulid } from "ulid"; import GenericEmbed from "../types/GenericEmbed"; +import FormData from 'form-data'; + +const MAX_BRIDGED_FILE_SIZE = 1_048_576; // 1 MiB client.on('messageCreate', async message => { try { - if (!message.content) return; - logger.debug(`[M] Discord: ${message.content}`); const [ bridgeCfg, bridgedReply ] = await Promise.all([ BRIDGE_CONFIG.findOne({ discord: message.channelId }), @@ -55,23 +56,62 @@ client.on('messageCreate', async message => { { upsert: true } ); + const autumnUrls: string[] = []; + + // todo: upload all attachments at once instead of sequentially + for (const a of message.attachments) { + try { + if (a[1].size > MAX_BRIDGED_FILE_SIZE) { + logger.debug(`Skipping attachment ${a[0]} ${a[1].name}: Size ${a[1].size} > max (${MAX_BRIDGED_FILE_SIZE})`); + continue; + } + + logger.debug(`Downloading attachment ${a[0]} ${a[1].name} (Size ${a[1].size})`); + + const formData = new FormData(); + const file = await axios.get(a[1].url, { responseType: 'arraybuffer' }); + + logger.debug(`Downloading attachment ${a[0]} finished, uploading to autumn`); + + formData.append( + a[0], + file.data, + { + filename: a[1].name || a[0], + contentType: a[1].contentType || undefined + } + ); + + const res = await axios.post( + `${AUTUMN_URL}/attachments`, formData, { headers: formData.getHeaders() } + ); + + logger.debug(`Uploading attachment ${a[0]} finished`); + + autumnUrls.push(res.data.id); + } catch(e) { console.error(e) } + } + const sendBridgeMessage = async (reply?: string) => { + const payload = { + content: message.content, + //attachments: [], + //embeds: [], + nonce: nonce, + replies: reply ? [ { id: reply, mention: !!message.mentions.repliedUser } ] : undefined, + masquerade: { + name: message.author.username, + avatar: message.author.displayAvatarURL({ size: 128 }), + }, + embeds: message.embeds.length + ? message.embeds.map(e => new GenericEmbed(e).toRevolt()) + : undefined, + attachments: autumnUrls.length ? autumnUrls : undefined, + }; + await axios.post( `${revoltClient.apiURL}/channels/${channel._id}/messages`, - { - content: message.content, - //attachments: [], - //embeds: [], - nonce: nonce, - replies: reply ? [ { id: reply, mention: !!message.mentions.repliedUser } ] : undefined, - masquerade: { - name: message.author.username, - avatar: message.author.displayAvatarURL({ size: 128 }), - }, - embeds: message.embeds.length - ? message.embeds.map(e => new GenericEmbed(e).toRevolt()) - : undefined, - }, + payload, { headers: { 'x-bot-token': process.env['REVOLT_TOKEN']!