diff --git a/d2m/converters/message-to-event.js b/d2m/converters/message-to-event.js index 92bc241..24c7f2d 100644 --- a/d2m/converters/message-to-event.js +++ b/d2m/converters/message-to-event.js @@ -107,7 +107,7 @@ async function attachmentToEvent(mentions, attachment) { msgtype: "m.text", body: `${emoji} Uploaded SPOILER file: ${attachment.url} (${pb(attachment.size)})`, format: "org.matrix.custom.html", - formatted_body: `
${emoji} Uploaded SPOILER file: ${attachment.url} (${pb(attachment.size)})
` + formatted_body: `
${emoji} Uploaded SPOILER file: ${attachment.url} (${pb(attachment.size)})
` } } // for large files, always link them instead of uploading so I don't use up all the space in the content repo diff --git a/d2m/converters/message-to-event.test.js b/d2m/converters/message-to-event.test.js index 9c28f0b..f3ac895 100644 --- a/d2m/converters/message-to-event.test.js +++ b/d2m/converters/message-to-event.test.js @@ -176,7 +176,7 @@ test("message2event: spoiler attachment", async t => { msgtype: "m.text", body: "📄 Uploaded SPOILER file: https://cdn.discordapp.com/attachments/1100319550446252084/1147465564307079258/SPOILER_69-GNDP-CADENCE.nfs.gci (74 KB)", format: "org.matrix.custom.html", - formatted_body: "
📄 Uploaded SPOILER file: https://cdn.discordapp.com/attachments/1100319550446252084/1147465564307079258/SPOILER_69-GNDP-CADENCE.nfs.gci (74 KB)
" + formatted_body: "
📄 Uploaded SPOILER file: View (74 KB)
" }]) }) diff --git a/d2m/converters/user-to-mxid.js b/d2m/converters/user-to-mxid.js index 4d53a9c..35a3b5e 100644 --- a/d2m/converters/user-to-mxid.js +++ b/d2m/converters/user-to-mxid.js @@ -5,10 +5,6 @@ const assert = require("assert") const passthrough = require("../../passthrough") const {select} = passthrough -const SPECIAL_USER_MAPPINGS = new Map([ - ["1081004946872352958", ["clyde_ai", "clyde"]] -]) - /** * Downcased and stripped username. Can only include a basic set of characters. * https://spec.matrix.org/v1.6/appendices/#user-identifiers @@ -34,7 +30,7 @@ function downcaseUsername(user) { /** @param {string[]} preferences */ function* generateLocalpartAlternatives(preferences) { const best = preferences[0] - assert(best) + assert.ok(best) // First, suggest the preferences... for (const localpart of preferences) { yield localpart @@ -54,18 +50,15 @@ function* generateLocalpartAlternatives(preferences) { * @returns {string} */ function userToSimName(user) { - if (!SPECIAL_USER_MAPPINGS.has(user.id)) { // skip this check for known special users - assert.notEqual(user.discriminator, "0000", `cannot create user for a webhook: ${JSON.stringify(user)}`) - } + assert.notEqual(user.discriminator, "0000", "cannot create user for a webhook") // 1. Is sim user already registered? const existing = select("sim", "sim_name", {user_id: user.id}).pluck().get() if (existing) return existing // 2. Register based on username (could be new or old format) - // (Unless it's a special user, in which case copy their provided mappings.) const downcased = downcaseUsername(user) - const preferences = SPECIAL_USER_MAPPINGS.get(user.id) || [downcased] + const preferences = [downcased] if (user.discriminator.length === 4) { // Old style tag? If user.username is unavailable, try the full tag next preferences.push(downcased + user.discriminator) } diff --git a/d2m/converters/user-to-mxid.test.js b/d2m/converters/user-to-mxid.test.js index b080115..e709473 100644 --- a/d2m/converters/user-to-mxid.test.js +++ b/d2m/converters/user-to-mxid.test.js @@ -1,7 +1,6 @@ const {test} = require("supertape") const tryToCatch = require("try-to-catch") const assert = require("assert") -const data = require("../../test/data") const {userToSimName} = require("./user-to-mxid") test("user2name: cannot create user for a webhook", async t => { @@ -40,7 +39,3 @@ test("user2name: uses ID if name becomes too short", t => { test("user2name: uses ID when name has only disallowed characters", t => { t.equal(userToSimName({username: "!@#$%^&*", discriminator: "0001", id: "9"}), "9") }) - -test("user2name: works on special user", t => { - t.equal(userToSimName(data.user.clyde_ai), "clyde_ai") -}) diff --git a/m2d/actions/send-event.js b/m2d/actions/send-event.js index 1b60ffe..f26abb0 100644 --- a/m2d/actions/send-event.js +++ b/m2d/actions/send-event.js @@ -15,8 +15,6 @@ const channelWebhook = sync.require("./channel-webhook") const eventToMessage = sync.require("../converters/event-to-message") /** @type {import("../../matrix/api")}) */ const api = sync.require("../../matrix/api") -/** @type {import("../../d2m/actions/register-user")} */ -const registerUser = sync.require("../../d2m/actions/register-user") /** * @param {DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer | Readable}[], pendingFiles?: ({name: string, url: string} | {name: string, url: string, key: string, iv: string} | {name: string, buffer: Buffer | Readable})[]}} message @@ -75,7 +73,7 @@ async function sendEvent(event) { // no need to sync the matrix member to the other side. but if I did need to, this is where I'd do it - let {messagesToEdit, messagesToSend, messagesToDelete, ensureJoined} = await eventToMessage.eventToMessage(event, guild, {api, snow: discord.snow}) + let {messagesToEdit, messagesToSend, messagesToDelete} = await eventToMessage.eventToMessage(event, guild, {api, snow: discord.snow}) messagesToEdit = await Promise.all(messagesToEdit.map(async e => { e.message = await resolvePendingFiles(e.message) @@ -109,10 +107,6 @@ async function sendEvent(event) { messageResponses.push(messageResponse) } - for (const user of ensureJoined) { - registerUser.ensureSimJoined(user, event.room_id) - } - return messageResponses } diff --git a/m2d/converters/event-to-message.js b/m2d/converters/event-to-message.js index cf51d86..ae40abf 100644 --- a/m2d/converters/event-to-message.js +++ b/m2d/converters/event-to-message.js @@ -505,13 +505,12 @@ async function eventToMessage(event, guild, di) { content = displayNameRunoff + replyLine + content // Handling written @mentions: we need to look for candidate Discord members to join to the room - let writtenMentionMatch = content.match(/(?:^|[^"<>/A-Za-z0-9])@([A-Za-z][A-Za-z0-9._\[\]\(\)-]+):?/d) // /d flag for indices requires node.js 16+ + let writtenMentionMatch = content.match(/(?:^|[^"<>/A-Za-z0-9])@([A-Za-z][A-Za-z0-9._\[\]\(\)-]+):?/) if (writtenMentionMatch) { const results = await di.snow.guild.searchGuildMembers(guild.id, {query: writtenMentionMatch[1]}) if (results[0]) { assert(results[0].user) - // @ts-ignore - typescript doesn't know about indices yet - content = content.slice(0, writtenMentionMatch.indices[1][0]-1) + `<@${results[0].user.id}>` + content.slice(writtenMentionMatch.indices[1][1]) + content = content.slice(0, writtenMentionMatch.index) + `<@${results[0].user.id}>` + content.slice(writtenMentionMatch.index + writtenMentionMatch[0].length) ensureJoined.push(results[0].user) } } diff --git a/m2d/converters/event-to-message.test.js b/m2d/converters/event-to-message.test.js index 40eb83e..1af5e42 100644 --- a/m2d/converters/event-to-message.test.js +++ b/m2d/converters/event-to-message.test.js @@ -2179,7 +2179,7 @@ test("event2message: guessed @mentions may join members to mention", async t => sender: "@cadence:cadence.moe", content: { msgtype: "m.text", - body: "hey @subtext, what food would you like to order?" + body: "@subtext: what food would you like to order?" }, event_id: "$u5gSwSzv_ZQS3eM00mnTBCor8nx_A_AwuQz7e59PZk8", room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe" @@ -2202,7 +2202,7 @@ test("event2message: guessed @mentions may join members to mention", async t => messagesToEdit: [], messagesToSend: [{ username: "cadence [they]", - content: "hey <@321876634777218072>, what food would you like to order?", + content: "<@321876634777218072> what food would you like to order?", avatar_url: undefined }], ensureJoined: [subtext.user] diff --git a/matrix/api.js b/matrix/api.js index b59d6ef..d6fd28b 100644 --- a/matrix/api.js +++ b/matrix/api.js @@ -19,17 +19,15 @@ const makeTxnId = sync.require("./txnid") * @returns {string} the new endpoint */ function path(p, mxid, otherParams = {}) { + if (!mxid) return p const u = new URL(p, "http://localhost") - if (mxid) u.searchParams.set("user_id", mxid) + u.searchParams.set("user_id", mxid) for (const entry of Object.entries(otherParams)) { if (entry[1] != undefined) { u.searchParams.set(entry[0], entry[1]) } } - let result = u.pathname - const str = u.searchParams.toString() - if (str) result += "?" + str - return result + return u.pathname + "?" + u.searchParams.toString() } /** @@ -90,7 +88,7 @@ async function getEvent(roomID, eventID) { */ async function getEventForTimestamp(roomID, ts) { /** @type {{event_id: string, origin_server_ts: number}} */ - const root = await mreq.mreq("GET", path(`/client/v1/rooms/${roomID}/timestamp_to_event`, null, {ts})) + const root = await mreq.mreq("GET", path(`/client/v3/rooms/${roomID}/timestamp_to_event`, null, {ts})) return root } diff --git a/matrix/api.test.js b/matrix/api.test.js index 82565eb..6c74e50 100644 --- a/matrix/api.test.js +++ b/matrix/api.test.js @@ -20,7 +20,3 @@ test("api path: existing query parameters with mxid", t => { test("api path: real world mxid", t => { t.equal(path("/hello/world", "@cookie_monster:cadence.moe"), "/hello/world?user_id=%40cookie_monster%3Acadence.moe") }) - -test("api path: extras number works", t => { - t.equal(path(`/client/v3/rooms/!example/timestamp_to_event`, null, {ts: 1687324651120}), "/client/v3/rooms/!example/timestamp_to_event?ts=1687324651120") -}) diff --git a/package-lock.json b/package-lock.json index 3367e93..d50f151 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@chriscdn/promise-semaphore": "^2.0.1", "better-sqlite3": "^9.0.0", "chunk-text": "^2.0.1", - "cloudstorm": "^0.9.5", + "cloudstorm": ">=0.9.0", "discord-markdown": "git+https://git.sr.ht/~cadence/nodejs-discord-markdown#de519353668c87ecc8c543e9749093481bc72ff8", "entities": "^4.5.0", "giframe": "github:cloudrac3r/giframe#v0.4.1", @@ -783,9 +783,9 @@ } }, "node_modules/cloudstorm": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/cloudstorm/-/cloudstorm-0.9.5.tgz", - "integrity": "sha512-WKaCsTDobR5c3YOmAchIa4QhPyWkUtYP3wNC/h6iE4bXE1DdN432FD3u3cuD3fX1Km9fPgpGBi4m6KYf5GFkJg==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/cloudstorm/-/cloudstorm-0.9.2.tgz", + "integrity": "sha512-dXyK8/SseyhAvblPDbDILCb6ghpoJnBAiBx1ig5/yQ54TvOXlZJ4MC+So7EJDdaHkTgnf38F8qNyBNN29sMMcQ==", "dependencies": { "snowtransfer": "^0.9.0" }, diff --git a/package.json b/package.json index 01070d2..ceb6c96 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "@chriscdn/promise-semaphore": "^2.0.1", "better-sqlite3": "^9.0.0", "chunk-text": "^2.0.1", - "cloudstorm": "^0.9.5", + "cloudstorm": ">=0.9.0", "discord-markdown": "git+https://git.sr.ht/~cadence/nodejs-discord-markdown#de519353668c87ecc8c543e9749093481bc72ff8", "entities": "^4.5.0", "giframe": "github:cloudrac3r/giframe#v0.4.1", diff --git a/test/data.js b/test/data.js index 3e78802..648c2c8 100644 --- a/test/data.js +++ b/test/data.js @@ -183,23 +183,6 @@ module.exports = { safety_alerts_channel_id: null } }, - user: { - clyde_ai: { - id: "1081004946872352958", - username: "clyde", - avatar: "a_6170487d32fdfe9f988720ad80e6ab8c", - discriminator: "0000", - public_flags: 0, - premium_type: 2, - flags: 0, - bot: true, - banner: null, - accent_color: null, - global_name: "Clyde", - avatar_decoration_data: null, - banner_color: null - } - }, member: { kumaccino: { avatar: null,