forked from cadence/out-of-your-element
begin converting discord attachments and stickers
This commit is contained in:
parent
38d7db5071
commit
e1d7ced87d
6 changed files with 194 additions and 33 deletions
|
@ -19,16 +19,31 @@ const createRoom = sync.require("../actions/create-room")
|
|||
async function sendMessage(message) {
|
||||
assert.ok(message.member)
|
||||
|
||||
const event = messageToEvent.messageToEvent(message)
|
||||
const roomID = await createRoom.ensureRoom(message.channel_id)
|
||||
|
||||
let senderMxid = null
|
||||
if (!message.webhook_id) {
|
||||
senderMxid = await registerUser.ensureSimJoined(message.author, roomID)
|
||||
await registerUser.syncUser(message.author, message.member, message.guild_id, roomID)
|
||||
}
|
||||
const eventID = await api.sendEvent(roomID, "m.room.message", event, senderMxid)
|
||||
db.prepare("INSERT INTO event_message (event_id, message_id, part) VALUES (?, ?, ?)").run(eventID, message.id, 0) // 0 is primary, 1 is supporting
|
||||
return eventID
|
||||
|
||||
const events = await messageToEvent.messageToEvent(message)
|
||||
const eventIDs = []
|
||||
let eventPart = 0 // 0 is primary, 1 is supporting
|
||||
for (const event of events) {
|
||||
const eventType = event.$type
|
||||
/** @type {Pick<typeof event, Exclude<keyof event, "$type">> & { $type?: string }} */
|
||||
const eventWithoutType = {...event}
|
||||
delete eventWithoutType.$type
|
||||
|
||||
const eventID = await api.sendEvent(roomID, eventType, event, senderMxid)
|
||||
db.prepare("INSERT INTO event_message (event_id, message_id, part) VALUES (?, ?, ?)").run(eventID, message.id, eventPart)
|
||||
|
||||
eventPart = 1 // TODO: use more intelligent algorithm to determine whether primary or supporting
|
||||
eventIDs.push(eventID)
|
||||
}
|
||||
|
||||
return eventIDs
|
||||
}
|
||||
|
||||
module.exports.sendMessage = sendMessage
|
||||
|
|
|
@ -2,27 +2,93 @@
|
|||
|
||||
const markdown = require("discord-markdown")
|
||||
|
||||
const passthrough = require("../../passthrough")
|
||||
const { sync, db } = passthrough
|
||||
/** @type {import("../../matrix/file")} */
|
||||
const file = sync.require("../../matrix/file")
|
||||
|
||||
/**
|
||||
* @param {import("discord-api-types/v10").APIMessage} message
|
||||
* @returns {import("../../types").Event.M_Room_Message}
|
||||
*/
|
||||
function messageToEvent(message) {
|
||||
async function messageToEvent(message) {
|
||||
const events = []
|
||||
|
||||
// Text content appears first
|
||||
const body = message.content
|
||||
const html = markdown.toHTML(body, {
|
||||
/* discordCallback: {
|
||||
user: Function,
|
||||
channel: Function,
|
||||
role: Function,
|
||||
everyone: Function,
|
||||
here: Function
|
||||
} */
|
||||
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)
|
||||
return {
|
||||
msgtype: "m.text",
|
||||
body: body,
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: html
|
||||
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
|
||||
const attachmentEvents = await Promise.all(message.attachments.map(async attachment => {
|
||||
// TODO: handle large files differently - link them instead of uploading
|
||||
if (attachment.content_type?.startsWith("image/") && attachment.width && attachment.height) {
|
||||
return {
|
||||
$type: "m.room.message",
|
||||
msgtype: "m.image",
|
||||
url: await file.uploadDiscordFileToMxc(attachment.url),
|
||||
external_url: attachment.url,
|
||||
body: attachment.filename,
|
||||
// TODO: filename: attachment.filename and then use body as the caption
|
||||
info: {
|
||||
mimetype: attachment.content_type,
|
||||
w: attachment.width,
|
||||
h: attachment.height,
|
||||
size: attachment.size
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
$type: "m.room.message",
|
||||
msgtype: "m.text",
|
||||
body: "Unsupported attachment:\n" + JSON.stringify(attachment, null, 2)
|
||||
}
|
||||
}
|
||||
}))
|
||||
events.push(...attachmentEvents)
|
||||
|
||||
// Then stickers
|
||||
|
||||
return events
|
||||
}
|
||||
|
||||
module.exports.messageToEvent = messageToEvent
|
||||
|
|
28
d2m/converters/message-to-event.test.js
Normal file
28
d2m/converters/message-to-event.test.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
const {test} = require("supertape")
|
||||
const assert = require("assert")
|
||||
const {messageToEvent} = require("./message-to-event")
|
||||
const data = require("../../test/data")
|
||||
|
||||
test("message2event: stickers", async t => {
|
||||
const events = await messageToEvent(data.message.sticker)
|
||||
t.deepEqual(events, [{
|
||||
$type: "m.room.message",
|
||||
msgtype: "m.text",
|
||||
body: "can have attachments too"
|
||||
}, {
|
||||
$type: "m.room.message",
|
||||
msgtype: "m.image",
|
||||
url: "mxc://cadence.moe/ZDCNYnkPszxGKgObUIFmvjus",
|
||||
body: "image.png",
|
||||
external_url: "https://cdn.discordapp.com/attachments/122155380120748034/1106366167486038016/image.png",
|
||||
info: {
|
||||
mimetype: "image/png",
|
||||
w: 333,
|
||||
h: 287,
|
||||
size: 127373,
|
||||
},
|
||||
}, {
|
||||
$type: "m.sticker",
|
||||
todo: "todo"
|
||||
}])
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue