rearranging and experiments

This commit is contained in:
Cadence Ember 2023-04-26 08:06:08 +12:00
parent 11e5cd7f77
commit 6990957c9e
12 changed files with 156 additions and 26 deletions

View file

View file

@ -0,0 +1,26 @@
// @ts-check
const markdown = require("discord-markdown")
/**
* @param {import("discord-api-types/v10").APIMessage} message
* @returns {import("../../types").M_Room_Message_content}
*/
module.exports = function(message) {
const body = message.content
const html = markdown.toHTML(body, {
discordCallback: {
user: Function,
channel: Function,
role: Function,
everyone: Function,
here: Function
}
}, null, null)
return {
msgtype: "m.text",
body: body,
format: "m.custom.html",
formatted_body: html
}
}

View file

@ -1,11 +1,13 @@
// @ts-check
const { SnowTransfer } = require("snowtransfer") const { SnowTransfer } = require("snowtransfer")
const { Client: CloudStorm } = require("cloudstorm") const { Client: CloudStorm } = require("cloudstorm")
const passthrough = require("../passthrough") const passthrough = require("../passthrough")
const { sync } = passthrough const { sync } = passthrough
/** @type {typeof import("./DiscordUtils")} */ /** @type {typeof import("./discord-packets")} */
const dUtils = sync.require("./DiscordUtils") const discordPackets = sync.require("./discord-packets")
class DiscordClient { class DiscordClient {
/** /**
@ -15,7 +17,7 @@ class DiscordClient {
this.discordToken = discordToken this.discordToken = discordToken
this.snow = new SnowTransfer(discordToken) this.snow = new SnowTransfer(discordToken)
this.cloud = new CloudStorm(discordToken, { this.cloud = new CloudStorm(discordToken, {
shards: "auto", shards: [0],
reconnect: true, reconnect: true,
snowtransferInstance: this.snow, snowtransferInstance: this.snow,
intents: [ intents: [
@ -41,7 +43,7 @@ class DiscordClient {
this.guilds = new Map() this.guilds = new Map()
/** @type {Map<string, Array<string>>} */ /** @type {Map<string, Array<string>>} */
this.guildChannelMap = new Map() this.guildChannelMap = new Map()
this.cloud.on("event", message => dUtils.onPacket(this, message)) this.cloud.on("event", message => discordPackets.onPacket(this, message))
this.cloud.on("error", console.error) this.cloud.on("error", console.error)
} }
} }

View file

@ -1,12 +1,14 @@
// @ts-check
const passthrough = require("../passthrough") const passthrough = require("../passthrough")
const { sync } = passthrough const { sync } = passthrough
/** @type {typeof import("./DiscordEvents")} */ /** @type {typeof import("./event-dispatcher")} */
const DiscordEvents = sync.require("./DiscordEvents") const eventDispatcher = sync.require("./event-dispatcher")
const utils = { const utils = {
/** /**
* @param {import("./DiscordClient")} client * @param {import("./discord-client")} client
* @param {import("cloudstorm").IGatewayMessage} message * @param {import("cloudstorm").IGatewayMessage} message
*/ */
onPacket(client, message) { onPacket(client, message) {
@ -56,7 +58,13 @@ const utils = {
} }
} else if (message.t === "MESSAGE_CREATE") DiscordEvents.onMessageCreate(client, message.d) } else if (message.t === "MESSAGE_CREATE") {
eventDispatcher.onMessageCreate(client, message.d)
} else if (message.t === "MESSAGE_REACTION_ADD") {
eventDispatcher.onReactionAdd(client, message.d)
}
} }
} }

23
d2m/event-dispatcher.js Normal file
View file

@ -0,0 +1,23 @@
// @ts-check
module.exports = {
/**
* @param {import("./discord-client")} client
* @param {import("discord-api-types/v10").GatewayMessageCreateDispatchData} message
*/
onMessageCreate(client, message) {
console.log(message)
console.log(message.guild_id)
console.log(message.member)
return {}
},
/**
* @param {import("./discord-client")} client
* @param {import("discord-api-types/v10").GatewayMessageReactionAddDispatchData} data
*/
onReactionAdd(client, data) {
console.log(data)
return {}
}
}

View file

@ -1,3 +1,5 @@
// @ts-check
const HeatSync = require("heatsync") const HeatSync = require("heatsync")
const config = require("./config") const config = require("./config")
@ -7,7 +9,7 @@ const sync = new HeatSync()
Object.assign(passthrough, { config, sync }) Object.assign(passthrough, { config, sync })
const DiscordClient = require("./modules/DiscordClient") const DiscordClient = require("./d2m/discord-client")
const discord = new DiscordClient(config.discordToken) const discord = new DiscordClient(config.discordToken)
passthrough.discord = discord passthrough.discord = discord
@ -19,5 +21,5 @@ passthrough.discord = discord
require("./stdin") require("./stdin")
})() })()
process.on("unhandledRejection", console.error) // process.on("unhandledRejection", console.error)
process.on("uncaughtException", console.error) // process.on("uncaughtException", console.error)

View file

@ -1,12 +0,0 @@
module.exports = {
/**
* Process Discord messages and convert to a message Matrix can understand
*
* @param {import("./DiscordClient")} client
* @param {import("discord-api-types/v10").APIMessage} message
* @returns {import("../types").MatrixMessage}
*/
onMessageCreate(client, message) {
return {}
}
}

63
notes.md Normal file
View file

@ -0,0 +1,63 @@
# d2m
Remember that a discord message may be transformed to multiple matrix messages.
A database will be used to store the discord id to matrix event id mapping. Table columns:
- discord id
- matrix id
- the "type" of the matrix id, used to update things properly next time. for example, whether it is the message text or an attachment
There needs to be a way to easily manually trigger something later. For example, it should be easy to manually retry sending a message, or check all members for changes, etc.
## Transforming content
1. Upload attachments to mxc if they are small enough.
2. Convert discord message text and embeds to matrix event.
1. Convert discord mentions, names, channel links, message links, and emojis to intermediate formats.
2. Convert discord text to body.
3. Convert discord text to formatted_body using custom discord-markdown npm module.
4. Convert discord embeds to quotes.
3. Gather relevant reply data.
4. Send reply+message.
5. Send attachments.
6. Store in database.
## Message sent
1. Transform content.
2. Send to matrix.
## Message deleted
1. Look up equivalents on matrix.
2. Delete on matrix.
## Message edited / embeds added
1. Look up equivalents on matrix.
2. Replace content on matrix.
## Reaction added
1. Add reaction on matrix.
## Reaction removed
1. Remove reaction on matrix.
## Member data changed
1. Compare current member against cached version in database.
2. Update member on matrix.
3. Update cached version in database.
## Channel created / updated
(but I should be able to manually call this function at any time to run the same code on any given channel)
1. Compare current channel against cached version in database.
2. If channel does not yet exist in database:
1. Create the corresponding room.
2. Add to database.
3. Update room details to match.
4. Add to space.

View file

@ -15,8 +15,16 @@
"author": "Cadence, PapiOphidian", "author": "Cadence, PapiOphidian",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"better-sqlite3": "^8.3.0",
"cloudstorm": "^0.7.0", "cloudstorm": "^0.7.0",
"discord-markdown": "git+https://git.sr.ht/~cadence/nodejs-discord-markdown#24508e701e91d5a00fa5e773ced874d9ee8c889b",
"heatsync": "^2.4.0", "heatsync": "^2.4.0",
"snowtransfer": "^0.7.0" "matrix-appservice": "^2.0.0",
"matrix-js-sdk": "^24.1.0",
"snowtransfer": "^0.7.0",
"supertape": "^8.3.0"
},
"devDependencies": {
"@types/node": "^18.16.0"
} }
} }

View file

@ -1,10 +1,13 @@
// @ts-check
/** /**
* @typedef {Object} Passthrough * @typedef {Object} Passthrough
* @property {import("repl").REPLServer} repl * @property {import("repl").REPLServer} repl
* @property {typeof import("./config")} config * @property {typeof import("./config")} config
* @property {import("./modules/DiscordClient")} discord * @property {import("./d2m/discord-client")} discord
* @property {import("heatsync")} sync * @property {import("heatsync")} sync
*/ */
/** @type {Passthrough} */ /** @type {Passthrough} */
// @ts-ignore
const pt = {} const pt = {}
module.exports = pt module.exports = pt

View file

@ -1,3 +1,5 @@
// @ts-check
const repl = require("repl") const repl = require("repl")
const util = require("util") const util = require("util")

7
types.d.ts vendored
View file

@ -1 +1,6 @@
export type MatrixMessage = {} export type M_Room_Message_content = {
msgtype: "m.text"
body: string
formatted_body?: "org.matrix.custom.html"
format?: string
}