rearranging and experiments
This commit is contained in:
parent
11e5cd7f77
commit
6990957c9e
12 changed files with 156 additions and 26 deletions
0
d2m/actions/create-room.js
Normal file
0
d2m/actions/create-room.js
Normal file
26
d2m/converters/message-to-event.js
Normal file
26
d2m/converters/message-to-event.js
Normal 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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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
23
d2m/event-dispatcher.js
Normal 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 {}
|
||||||
|
}
|
||||||
|
}
|
8
index.js
8
index.js
|
@ -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)
|
||||||
|
|
|
@ -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
63
notes.md
Normal 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.
|
10
package.json
10
package.json
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
2
stdin.js
2
stdin.js
|
@ -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
7
types.d.ts
vendored
|
@ -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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue