diff --git a/d2m/actions/create-space.js b/d2m/actions/create-space.js index 4218c1f..e3b6da7 100644 --- a/d2m/actions/create-space.js +++ b/d2m/actions/create-space.js @@ -9,7 +9,7 @@ const api = sync.require("../../matrix/api") * @param {import("discord-api-types/v10").RESTGetAPIGuildResult} guild */ async function createSpace(guild) { - const roomID = api.createRoom({ + const roomID = await api.createRoom({ name: guild.name, preset: "private_chat", visibility: "private", diff --git a/d2m/converters/message-to-event.js b/d2m/converters/message-to-event.js index 549d104..382e970 100644 --- a/d2m/converters/message-to-event.js +++ b/d2m/converters/message-to-event.js @@ -16,48 +16,50 @@ async function messageToEvent(message, guild) { const events = [] // Text content appears first - const body = message.content - const html = markdown.toHTML(body, { - discordCallback: { - user: node => { - const mxid = db.prepare("SELECT mxid FROM sim WHERE discord_id = ?").pluck().get(node.id) - if (mxid) { - return "https://matrix.to/#/" + mxid - } else { - return "@" + node.id - } - }, - channel: node => { - const roomID = db.prepare("SELECT room_id FROM channel_room WHERE channel_id = ?").pluck().get(node.id) - if (roomID) { - return "https://matrix.to/#/" + roomID - } else { - return "#" + node.id - } - }, - role: node => - "@&" + node.id, - everyone: node => - "@room", - here: node => - "@here" + if (message.content) { + const body = message.content + const html = markdown.toHTML(body, { + discordCallback: { + user: node => { + const mxid = db.prepare("SELECT mxid FROM sim WHERE discord_id = ?").pluck().get(node.id) + if (mxid) { + return "https://matrix.to/#/" + mxid + } else { + return "@" + node.id + } + }, + channel: node => { + const roomID = db.prepare("SELECT room_id FROM channel_room WHERE channel_id = ?").pluck().get(node.id) + if (roomID) { + return "https://matrix.to/#/" + roomID + } else { + return "#" + node.id + } + }, + role: node => + "@&" + node.id, + everyone: node => + "@room", + here: node => + "@here" + } + }, null, null) + const isPlaintext = body === html + if (isPlaintext) { + events.push({ + $type: "m.room.message", + msgtype: "m.text", + body: body + }) + } else { + events.push({ + $type: "m.room.message", + msgtype: "m.text", + body: body, + format: "org.matrix.custom.html", + formatted_body: html + }) } - }, null, null) - const isPlaintext = body === html - if (isPlaintext) { - events.push({ - $type: "m.room.message", - msgtype: "m.text", - body: body - }) - } else { - events.push({ - $type: "m.room.message", - msgtype: "m.text", - body: body, - format: "org.matrix.custom.html", - formatted_body: html - }) } // Then attachments diff --git a/d2m/converters/message-to-event.test.js b/d2m/converters/message-to-event.test.js index c92cd85..c318389 100644 --- a/d2m/converters/message-to-event.test.js +++ b/d2m/converters/message-to-event.test.js @@ -3,6 +3,23 @@ const assert = require("assert") const {messageToEvent} = require("./message-to-event") const data = require("../../test/data") +test("message2event: attachment with no content", async t => { + const events = await messageToEvent(data.message.attachment_no_content, data.guild.general) + t.deepEqual(events, [{ + $type: "m.room.message", + msgtype: "m.image", + url: "mxc://cadence.moe/qXoZktDqNtEGuOCZEADAMvhM", + body: "image.png", + external_url: "https://cdn.discordapp.com/attachments/497161332244742154/1124628646431297546/image.png", + info: { + mimetype: "image/png", + w: 466, + h: 85, + size: 12919, + }, + }]) +}) + test("message2event: stickers", async t => { const events = await messageToEvent(data.message.sticker, data.guild.general) t.deepEqual(events, [{ diff --git a/d2m/event-dispatcher.js b/d2m/event-dispatcher.js index fbcdca0..1a1e30a 100644 --- a/d2m/event-dispatcher.js +++ b/d2m/event-dispatcher.js @@ -17,7 +17,7 @@ module.exports = { /** @ts-ignore @type {import("discord-api-types/v10").APIGuildChannel} */ const channel = client.channels.get(message.channel_id) const guild = client.guilds.get(channel.guild_id) - if (message.guild_id !== "112760669178241024") return // TODO: activate on other servers (requires the space creation flow to be done first) + if (message.guild_id !== "112760669178241024" && message.guild_id !== "497159726455455754") return // TODO: activate on other servers (requires the space creation flow to be done first) sendMessage.sendMessage(message, guild) }, diff --git a/db/ooye.db b/db/ooye.db index be56505..c91e41f 100644 Binary files a/db/ooye.db and b/db/ooye.db differ diff --git a/matrix/api.js b/matrix/api.js index 3ec014d..ec85795 100644 --- a/matrix/api.js +++ b/matrix/api.js @@ -60,6 +60,10 @@ async function inviteToRoom(roomID, mxidToInvite, mxid) { }) } +async function leaveRoom(roomID, mxid) { + await mreq.mreq("POST", path(`/client/v3/rooms/${roomID}/leave`, mxid), {}) +} + /** * @param {string} roomID * @returns {Promise} @@ -108,6 +112,7 @@ module.exports.register = register module.exports.createRoom = createRoom module.exports.joinRoom = joinRoom module.exports.inviteToRoom = inviteToRoom +module.exports.leaveRoom = leaveRoom module.exports.getAllState = getAllState module.exports.sendState = sendState module.exports.sendEvent = sendEvent diff --git a/package-lock.json b/package-lock.json index e4baa2e..fecb682 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "better-sqlite3": "^8.3.0", - "cloudstorm": "^0.7.0", + "cloudstorm": "^0.8.0", "discord-markdown": "git+https://git.sr.ht/~cadence/nodejs-discord-markdown#24508e701e91d5a00fa5e773ced874d9ee8c889b", "heatsync": "^2.4.1", "js-yaml": "^4.1.0", @@ -18,7 +18,7 @@ "matrix-js-sdk": "^24.1.0", "mixin-deep": "^2.0.1", "node-fetch": "^2.6.7", - "snowtransfer": "^0.7.0", + "snowtransfer": "^0.8.0", "try-to-catch": "^3.0.1" }, "devDependencies": { @@ -605,6 +605,17 @@ "ieee754": "^1.2.1" } }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -625,11 +636,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/centra": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/centra/-/centra-2.6.0.tgz", - "integrity": "sha512-dgh+YleemrT8u85QL11Z6tYhegAs3MMxsaWAq/oXeAmYJ7VxL3SI9TZtnfaEvNDMAPolj25FXIb3S+HCI4wQaQ==" - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -679,11 +685,11 @@ } }, "node_modules/cloudstorm": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/cloudstorm/-/cloudstorm-0.7.4.tgz", - "integrity": "sha512-EBeLY+VFP21lObPm3EHAhmtnch7irBD/AfRd6p+glXpYMU4vaCXzA+e7TI4UA2GCoN6LnX/skw4tk6GKyT0gIg==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/cloudstorm/-/cloudstorm-0.8.0.tgz", + "integrity": "sha512-CT5/RKvSz1I0wmsf0SmZ2Jg9fPvqY67t9e2Y8n92vU0uEK5WmfPUyPOLZoYPMJwmktmsVCj4N6Pvka9gBIsY4g==", "dependencies": { - "snowtransfer": "0.7.2" + "snowtransfer": "0.8.0" }, "engines": { "node": ">=12.0.0" @@ -2458,13 +2464,13 @@ } }, "node_modules/snowtransfer": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/snowtransfer/-/snowtransfer-0.7.2.tgz", - "integrity": "sha512-EYFanl0T4yNul2WdBY/69+eo36eaKGkY4wEtMED+7wOFI70gdEsy4VQlToWb0WVm5/gvSiCMK4aLgA3EQGObAQ==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/snowtransfer/-/snowtransfer-0.8.0.tgz", + "integrity": "sha512-ang6qQsET4VX4u9mdZq6ynJvcm8HQfV6iZOHBh8Y3T0QkJLr6GAjzcv1et7BOXl1HDR/6NhD+j+ZGr8+imTclg==", "dependencies": { - "centra": "^2.6.0", - "discord-api-types": "^0.37.46", - "form-data": "^4.0.0" + "discord-api-types": "^0.37.47", + "form-data": "^4.0.0", + "undici": "^5.22.1" }, "engines": { "node": ">=12.0.0" @@ -2534,6 +2540,14 @@ "node": ">= 0.4" } }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -2791,6 +2805,17 @@ "node": ">= 0.6" } }, + "node_modules/undici": { + "version": "5.22.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.22.1.tgz", + "integrity": "sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw==", + "dependencies": { + "busboy": "^1.6.0" + }, + "engines": { + "node": ">=14.0" + } + }, "node_modules/unhomoglyph": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/unhomoglyph/-/unhomoglyph-1.0.6.tgz", diff --git a/package.json b/package.json index f483842..b3e19eb 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "license": "MIT", "dependencies": { "better-sqlite3": "^8.3.0", - "cloudstorm": "^0.7.0", + "cloudstorm": "^0.8.0", "discord-markdown": "git+https://git.sr.ht/~cadence/nodejs-discord-markdown#24508e701e91d5a00fa5e773ced874d9ee8c889b", "heatsync": "^2.4.1", "js-yaml": "^4.1.0", @@ -24,7 +24,7 @@ "matrix-js-sdk": "^24.1.0", "mixin-deep": "^2.0.1", "node-fetch": "^2.6.7", - "snowtransfer": "^0.7.0", + "snowtransfer": "^0.8.0", "try-to-catch": "^3.0.1" }, "devDependencies": { diff --git a/stdin.js b/stdin.js index 99345ab..1a5b8d1 100644 --- a/stdin.js +++ b/stdin.js @@ -11,6 +11,7 @@ const createRoom = sync.require("./d2m/actions/create-room") const registerUser = sync.require("./d2m/actions/register-user") const mreq = sync.require("./matrix/mreq") const api = sync.require("./matrix/api") +const sendMessage = sync.require("./m2d/actions/send-message") const guildID = "112760669178241024" const extraContext = {} diff --git a/test/data.js b/test/data.js index 85b3cd4..5efea36 100644 --- a/test/data.js +++ b/test/data.js @@ -140,6 +140,43 @@ module.exports = { }, message: { // Display order is text content, attachments, then stickers + attachment_no_content: { + id: "1124628646670389348", + type: 0, + content: "", + channel_id: "497161332244742154", + author: { + id: "320067006521147393", + username: "papiophidian", + global_name: "PapiOphidian", + avatar: "fb2b4535f7a108619e3edae12fcb16c5", + discriminator: "0", + public_flags: 4194880, + avatar_decoration: null + }, + attachments: [ + { + id: "1124628646431297546", + filename: "image.png", + size: 12919, + url: "https://cdn.discordapp.com/attachments/497161332244742154/1124628646431297546/image.png", + proxy_url: "https://media.discordapp.net/attachments/497161332244742154/1124628646431297546/image.png", + width: 466, + height: 85, + content_type: "image/png" + } + ], + embeds: [], + mentions: [], + mention_roles: [], + pinned: false, + mention_everyone: false, + tts: false, + timestamp: "2023-07-01T09:12:43.956000+00:00", + edited_timestamp: null, + flags: 0, + components: [] + }, sticker: { id: "1106366167788044450", type: 0, @@ -180,6 +217,6 @@ module.exports = { format_type: 1, name: "pomu puff" }] - } + } } }