support threads
This commit is contained in:
		
							parent
							
								
									213bf0a515
								
							
						
					
					
						commit
						0fc8e68f15
					
				
					 9 changed files with 172 additions and 63 deletions
				
			
		| 
						 | 
					@ -21,8 +21,8 @@ async function roomToKState(roomID) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @params {string} roomID
 | 
					 * @param {string} roomID
 | 
				
			||||||
 * @params {any} kstate
 | 
					 * @param {any} kstate
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
function applyKStateDiffToRoom(roomID, kstate) {
 | 
					function applyKStateDiffToRoom(roomID, kstate) {
 | 
				
			||||||
	const events = ks.kstateToState(kstate)
 | 
						const events = ks.kstateToState(kstate)
 | 
				
			||||||
| 
						 | 
					@ -51,7 +51,7 @@ function convertNameAndTopic(channel, guild, customName) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @param {DiscordTypes.APIGuildTextChannel} channel
 | 
					 * @param {DiscordTypes.APIGuildTextChannel | DiscordTypes.APIThreadChannel} channel
 | 
				
			||||||
 * @param {DiscordTypes.APIGuild} guild
 | 
					 * @param {DiscordTypes.APIGuild} guild
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async function channelToKState(channel, guild) {
 | 
					async function channelToKState(channel, guild) {
 | 
				
			||||||
| 
						 | 
					@ -98,21 +98,27 @@ async function channelToKState(channel, guild) {
 | 
				
			||||||
 * @returns {Promise<string>} room ID
 | 
					 * @returns {Promise<string>} room ID
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async function createRoom(channel, guild, spaceID, kstate) {
 | 
					async function createRoom(channel, guild, spaceID, kstate) {
 | 
				
			||||||
 | 
						const [convertedName, convertedTopic] = convertNameAndTopic(channel, guild, null)
 | 
				
			||||||
	const roomID = await api.createRoom({
 | 
						const roomID = await api.createRoom({
 | 
				
			||||||
		name: channel.name,
 | 
							name: convertedName,
 | 
				
			||||||
		topic: channel.topic || undefined,
 | 
							topic: convertedTopic,
 | 
				
			||||||
		preset: "private_chat",
 | 
							preset: "private_chat",
 | 
				
			||||||
		visibility: "private",
 | 
							visibility: "private",
 | 
				
			||||||
		invite: ["@cadence:cadence.moe"], // TODO
 | 
							invite: ["@cadence:cadence.moe"], // TODO
 | 
				
			||||||
		initial_state: ks.kstateToState(kstate)
 | 
							initial_state: ks.kstateToState(kstate)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	db.prepare("INSERT INTO channel_room (channel_id, room_id) VALUES (?, ?)").run(channel.id, roomID)
 | 
						let threadParent = null
 | 
				
			||||||
 | 
						if (channel.type === DiscordTypes.ChannelType.PublicThread) {
 | 
				
			||||||
 | 
							/** @type {DiscordTypes.APIThreadChannel} */ // @ts-ignore
 | 
				
			||||||
 | 
							const thread = channel
 | 
				
			||||||
 | 
							threadParent = thread.parent_id
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						db.prepare("INSERT INTO channel_room (channel_id, room_id, name, nick, thread_parent) VALUES (?, ?, ?, NULL, ?)").run(channel.id, roomID, channel.name, threadParent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Put the newly created child into the space
 | 
						// Put the newly created child into the space
 | 
				
			||||||
	await api.sendState(spaceID, "m.space.child", roomID, { // TODO: should I deduplicate with the equivalent code from syncRoom?
 | 
						_syncSpaceMember(channel, spaceID, roomID)
 | 
				
			||||||
		via: ["cadence.moe"] // TODO: use the proper server
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return roomID
 | 
						return roomID
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -156,14 +162,15 @@ async function _syncRoom(channelID, shouldActuallySync) {
 | 
				
			||||||
	assert.ok(channel)
 | 
						assert.ok(channel)
 | 
				
			||||||
	const guild = channelToGuild(channel)
 | 
						const guild = channelToGuild(channel)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/** @type {string?} */
 | 
						/** @type {{room_id: string, thread_parent: string?}} */
 | 
				
			||||||
	const existing = db.prepare("SELECT room_id from channel_room WHERE channel_id = ?").pluck().get(channel.id)
 | 
						const existing = db.prepare("SELECT room_id, thread_parent from channel_room WHERE channel_id = ?").get(channelID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!existing) {
 | 
						if (!existing) {
 | 
				
			||||||
		const {spaceID, channelKState} = await channelToKState(channel, guild)
 | 
							const {spaceID, channelKState} = await channelToKState(channel, guild)
 | 
				
			||||||
		return createRoom(channel, guild, spaceID, channelKState)
 | 
							return createRoom(channel, guild, spaceID, channelKState)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if (!shouldActuallySync) {
 | 
							if (!shouldActuallySync) {
 | 
				
			||||||
			return existing // only need to ensure room exists, and it does. return the room ID
 | 
								return existing.room_id // only need to ensure room exists, and it does. return the room ID
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		console.log(`[room sync] to matrix: ${channel.name}`)
 | 
							console.log(`[room sync] to matrix: ${channel.name}`)
 | 
				
			||||||
| 
						 | 
					@ -171,24 +178,41 @@ async function _syncRoom(channelID, shouldActuallySync) {
 | 
				
			||||||
		const {spaceID, channelKState} = await channelToKState(channel, guild)
 | 
							const {spaceID, channelKState} = await channelToKState(channel, guild)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// sync channel state to room
 | 
							// sync channel state to room
 | 
				
			||||||
		const roomKState = await roomToKState(existing)
 | 
							const roomKState = await roomToKState(existing.room_id)
 | 
				
			||||||
		const roomDiff = ks.diffKState(roomKState, channelKState)
 | 
							const roomDiff = ks.diffKState(roomKState, channelKState)
 | 
				
			||||||
		const roomApply = applyKStateDiffToRoom(existing, roomDiff)
 | 
							const roomApply = applyKStateDiffToRoom(existing.room_id, roomDiff)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// sync room as space member
 | 
							// sync room as space member
 | 
				
			||||||
		const spaceKState = await roomToKState(spaceID)
 | 
							const spaceApply = _syncSpaceMember(channel, spaceID, existing.room_id)
 | 
				
			||||||
		const spaceDiff = ks.diffKState(spaceKState, {
 | 
					 | 
				
			||||||
			[`m.space.child/${existing}`]: {
 | 
					 | 
				
			||||||
				via: ["cadence.moe"] // TODO: use the proper server
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
		const spaceApply = applyKStateDiffToRoom(spaceID, spaceDiff)
 | 
					 | 
				
			||||||
		await Promise.all([roomApply, spaceApply])
 | 
							await Promise.all([roomApply, spaceApply])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return existing
 | 
							return existing.room_id
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {DiscordTypes.APIGuildTextChannel} channel
 | 
				
			||||||
 | 
					 * @param {string} spaceID
 | 
				
			||||||
 | 
					 * @param {string} roomID
 | 
				
			||||||
 | 
					 * @returns {Promise<string[]>}
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					async function _syncSpaceMember(channel, spaceID, roomID) {
 | 
				
			||||||
 | 
						const spaceKState = await roomToKState(spaceID)
 | 
				
			||||||
 | 
						let spaceEventContent = {}
 | 
				
			||||||
 | 
						if (
 | 
				
			||||||
 | 
							channel.type !== DiscordTypes.ChannelType.PrivateThread // private threads do not belong in the space (don't offer people something they can't join)
 | 
				
			||||||
 | 
							|| channel["thread_metadata"]?.archived // archived threads do not belong in the space (don't offer people conversations that are no longer relevant)
 | 
				
			||||||
 | 
						) {
 | 
				
			||||||
 | 
							spaceEventContent = {
 | 
				
			||||||
 | 
								via: ["cadence.moe"] // TODO: use the proper server
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						const spaceDiff = ks.diffKState(spaceKState, {
 | 
				
			||||||
 | 
							[`m.space.child/${roomID}`]: spaceEventContent
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						return applyKStateDiffToRoom(spaceID, spaceDiff)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function ensureRoom(channelID) {
 | 
					function ensureRoom(channelID) {
 | 
				
			||||||
	return _syncRoom(channelID, false)
 | 
						return _syncRoom(channelID, false)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
// @ts-check
 | 
					// @ts-check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const assert = require("assert")
 | 
				
			||||||
const passthrough = require("../../passthrough")
 | 
					const passthrough = require("../../passthrough")
 | 
				
			||||||
const { sync, db } = passthrough
 | 
					const { sync, db } = passthrough
 | 
				
			||||||
/** @type {import("../../matrix/api")} */
 | 
					/** @type {import("../../matrix/api")} */
 | 
				
			||||||
| 
						 | 
					@ -9,13 +10,14 @@ const api = sync.require("../../matrix/api")
 | 
				
			||||||
 * @param {import("discord-api-types/v10").RESTGetAPIGuildResult} guild
 | 
					 * @param {import("discord-api-types/v10").RESTGetAPIGuildResult} guild
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async function createSpace(guild) {
 | 
					async function createSpace(guild) {
 | 
				
			||||||
 | 
						assert(guild.name)
 | 
				
			||||||
	const roomID = await api.createRoom({
 | 
						const roomID = await api.createRoom({
 | 
				
			||||||
		name: guild.name,
 | 
							name: guild.name,
 | 
				
			||||||
		preset: "private_chat",
 | 
							preset: "private_chat", // cannot join space unless invited
 | 
				
			||||||
		visibility: "private",
 | 
							visibility: "private",
 | 
				
			||||||
		power_level_content_override: {
 | 
							power_level_content_override: {
 | 
				
			||||||
			events_default: 100,
 | 
								events_default: 100, // space can only be managed by bridge
 | 
				
			||||||
			invite: 50
 | 
								invite: 0 // any existing member can invite others
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		invite: ["@cadence:cadence.moe"], // TODO
 | 
							invite: ["@cadence:cadence.moe"], // TODO
 | 
				
			||||||
		topic: guild.description || undefined,
 | 
							topic: guild.description || undefined,
 | 
				
			||||||
| 
						 | 
					@ -27,13 +29,13 @@ async function createSpace(guild) {
 | 
				
			||||||
				type: "m.room.guest_access",
 | 
									type: "m.room.guest_access",
 | 
				
			||||||
				state_key: "",
 | 
									state_key: "",
 | 
				
			||||||
				content: {
 | 
									content: {
 | 
				
			||||||
					guest_access: "can_join"
 | 
										guest_access: "can_join" // guests can join space if other conditions are met
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				type: "m.room.history_visibility",
 | 
									type: "m.room.history_visibility",
 | 
				
			||||||
				content: {
 | 
									content: {
 | 
				
			||||||
					history_visibility: "invited"
 | 
										history_visibility: "invited" // any events sent after user was invited are visible
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		]
 | 
							]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,12 @@ const utils = {
 | 
				
			||||||
				arr.push(channel.id)
 | 
									arr.push(channel.id)
 | 
				
			||||||
				client.channels.set(channel.id, channel)
 | 
									client.channels.set(channel.id, channel)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								for (const thread of message.d.threads || []) {
 | 
				
			||||||
 | 
									// @ts-ignore
 | 
				
			||||||
 | 
									thread.guild_id = message.d.id
 | 
				
			||||||
 | 
									arr.push(thread.id)
 | 
				
			||||||
 | 
									client.channels.set(thread.id, thread)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		} else if (message.t === "GUILD_DELETE") {
 | 
							} else if (message.t === "GUILD_DELETE") {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,10 @@ const api = sync.require("../matrix/api")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let lastReportedEvent = 0
 | 
					let lastReportedEvent = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function isGuildAllowed(guildID) {
 | 
				
			||||||
 | 
						return ["112760669178241024", "497159726455455754", "1100319549670301727"].includes(guildID)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Grab Discord events we care about for the bridge, check them, and pass them on
 | 
					// Grab Discord events we care about for the bridge, check them, and pass them on
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
| 
						 | 
					@ -29,11 +33,14 @@ module.exports = {
 | 
				
			||||||
		console.error(`while handling this ${gatewayMessage.t} gateway event:`)
 | 
							console.error(`while handling this ${gatewayMessage.t} gateway event:`)
 | 
				
			||||||
		console.dir(gatewayMessage.d, {depth: null})
 | 
							console.dir(gatewayMessage.d, {depth: null})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (Date.now() - lastReportedEvent > 5000) {
 | 
							if (Date.now() - lastReportedEvent < 5000) return
 | 
				
			||||||
		lastReportedEvent = Date.now()
 | 
							lastReportedEvent = Date.now()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const channelID = gatewayMessage.d.channel_id
 | 
							const channelID = gatewayMessage.d.channel_id
 | 
				
			||||||
			if (channelID) {
 | 
							if (!channelID) return
 | 
				
			||||||
		const roomID = db.prepare("SELECT room_id FROM channel_room WHERE channel_id = ?").pluck().get(channelID)
 | 
							const roomID = db.prepare("SELECT room_id FROM channel_room WHERE channel_id = ?").pluck().get(channelID)
 | 
				
			||||||
 | 
							if (!roomID) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let stackLines = e.stack.split("\n")
 | 
							let stackLines = e.stack.split("\n")
 | 
				
			||||||
		let cloudstormLine = stackLines.findIndex(l => l.includes("/node_modules/cloudstorm/"))
 | 
							let cloudstormLine = stackLines.findIndex(l => l.includes("/node_modules/cloudstorm/"))
 | 
				
			||||||
		if (cloudstormLine !== -1) {
 | 
							if (cloudstormLine !== -1) {
 | 
				
			||||||
| 
						 | 
					@ -45,15 +52,15 @@ module.exports = {
 | 
				
			||||||
			format: "org.matrix.custom.html",
 | 
								format: "org.matrix.custom.html",
 | 
				
			||||||
			formatted_body: "\u26a0 <strong>Bridged event from Discord not delivered</strong>"
 | 
								formatted_body: "\u26a0 <strong>Bridged event from Discord not delivered</strong>"
 | 
				
			||||||
				+ `<br>Gateway event: ${gatewayMessage.t}`
 | 
									+ `<br>Gateway event: ${gatewayMessage.t}`
 | 
				
			||||||
						+ `<pre>${stackLines.join("\n")}</pre>`
 | 
									+ `<br>${e.toString()}`
 | 
				
			||||||
 | 
									+ `<details><summary>Error trace</summary>`
 | 
				
			||||||
 | 
									+ `<pre>${stackLines.join("\n")}</pre></details>`
 | 
				
			||||||
				+ `<details><summary>Original payload</summary>`
 | 
									+ `<details><summary>Original payload</summary>`
 | 
				
			||||||
				+ `<pre>${util.inspect(gatewayMessage.d, false, 4, false)}</pre></details>`,
 | 
									+ `<pre>${util.inspect(gatewayMessage.d, false, 4, false)}</pre></details>`,
 | 
				
			||||||
			"m.mentions": {
 | 
								"m.mentions": {
 | 
				
			||||||
				user_ids: ["@cadence:cadence.moe"]
 | 
									user_ids: ["@cadence:cadence.moe"]
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
| 
						 | 
					@ -72,7 +79,7 @@ module.exports = {
 | 
				
			||||||
		const channel = client.channels.get(message.channel_id)
 | 
							const channel = client.channels.get(message.channel_id)
 | 
				
			||||||
		if (!channel.guild_id) return // Nothing we can do in direct messages.
 | 
							if (!channel.guild_id) return // Nothing we can do in direct messages.
 | 
				
			||||||
		const guild = client.guilds.get(channel.guild_id)
 | 
							const guild = client.guilds.get(channel.guild_id)
 | 
				
			||||||
		if (message.guild_id !== "112760669178241024" && message.guild_id !== "497159726455455754") return // TODO: activate on other servers (requires the space creation flow to be done first)
 | 
							if (!isGuildAllowed(guild.id)) return
 | 
				
			||||||
		await sendMessage.sendMessage(message, guild)
 | 
							await sendMessage.sendMessage(message, guild)
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -97,7 +104,7 @@ module.exports = {
 | 
				
			||||||
			const channel = client.channels.get(message.channel_id)
 | 
								const channel = client.channels.get(message.channel_id)
 | 
				
			||||||
			if (!channel.guild_id) return // Nothing we can do in direct messages.
 | 
								if (!channel.guild_id) return // Nothing we can do in direct messages.
 | 
				
			||||||
			const guild = client.guilds.get(channel.guild_id)
 | 
								const guild = client.guilds.get(channel.guild_id)
 | 
				
			||||||
			if (message.guild_id !== "112760669178241024" && message.guild_id !== "497159726455455754") return // TODO: activate on other servers (requires the space creation flow to be done first)
 | 
								if (!isGuildAllowed(guild.id)) return
 | 
				
			||||||
			await editMessage.editMessage(message, guild)
 | 
								await editMessage.editMessage(message, guild)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -109,7 +116,6 @@ module.exports = {
 | 
				
			||||||
	async onReactionAdd(client, data) {
 | 
						async onReactionAdd(client, data) {
 | 
				
			||||||
		if (data.user_id === client.user.id) return // m2d reactions are added by the discord bot user - do not reflect them back to matrix.
 | 
							if (data.user_id === client.user.id) return // m2d reactions are added by the discord bot user - do not reflect them back to matrix.
 | 
				
			||||||
		if (data.emoji.id !== null) return // TODO: image emoji reactions
 | 
							if (data.emoji.id !== null) return // TODO: image emoji reactions
 | 
				
			||||||
		console.log(data)
 | 
					 | 
				
			||||||
		await addReaction.addReaction(data)
 | 
							await addReaction.addReaction(data)
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,7 +124,6 @@ module.exports = {
 | 
				
			||||||
	 * @param {import("discord-api-types/v10").GatewayMessageDeleteDispatchData} data
 | 
						 * @param {import("discord-api-types/v10").GatewayMessageDeleteDispatchData} data
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	async onMessageDelete(client, data) {
 | 
						async onMessageDelete(client, data) {
 | 
				
			||||||
		console.log(data)
 | 
					 | 
				
			||||||
		await deleteMessage.deleteMessage(data)
 | 
							await deleteMessage.deleteMessage(data)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,10 +54,10 @@ BEGIN TRANSACTION;
 | 
				
			||||||
INSERT INTO guild_space (guild_id, space_id) VALUES
 | 
					INSERT INTO guild_space (guild_id, space_id) VALUES
 | 
				
			||||||
('112760669178241024', '!jjWAGMeQdNrVZSSfvz:cadence.moe');
 | 
					('112760669178241024', '!jjWAGMeQdNrVZSSfvz:cadence.moe');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
INSERT INTO channel_room (channel_id, room_id, name, nick) VALUES
 | 
					INSERT INTO channel_room (channel_id, room_id, name, nick, is_thread) VALUES
 | 
				
			||||||
('112760669178241024', '!kLRqKKUQXcibIMtOpl:cadence.moe', 'heave', 'main'),
 | 
					('112760669178241024', '!kLRqKKUQXcibIMtOpl:cadence.moe', 'heave', 'main', NULL, 0),
 | 
				
			||||||
('497161350934560778', '!edUxjVdzgUvXDUIQCK:cadence.moe', 'amanda-spam', NULL),
 | 
					('497161350934560778', '!edUxjVdzgUvXDUIQCK:cadence.moe', 'amanda-spam', NULL, 0),
 | 
				
			||||||
('160197704226439168', '!uCtjHhfGlYbVnPVlkG:cadence.moe', 'the-stanley-parable-channel', 'bots');
 | 
					('160197704226439168', '!uCtjHhfGlYbVnPVlkG:cadence.moe', 'the-stanley-parable-channel', 'bots', 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
INSERT INTO sim (discord_id, sim_name, localpart, mxid) VALUES
 | 
					INSERT INTO sim (discord_id, sim_name, localpart, mxid) VALUES
 | 
				
			||||||
('0', 'bot', '_ooye_bot', '@_ooye_bot:cadence.moe'),
 | 
					('0', 'bot', '_ooye_bot', '@_ooye_bot:cadence.moe'),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,10 +50,11 @@ async function withWebhook(channelID, callback) {
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @param {string} channelID
 | 
					 * @param {string} channelID
 | 
				
			||||||
 * @param {DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer}[]}} data
 | 
					 * @param {DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer}[]}} data
 | 
				
			||||||
 | 
					 * @param {string} [threadID]
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async function sendMessageWithWebhook(channelID, data) {
 | 
					async function sendMessageWithWebhook(channelID, data, threadID) {
 | 
				
			||||||
   const result = await withWebhook(channelID, async webhook => {
 | 
					   const result = await withWebhook(channelID, async webhook => {
 | 
				
			||||||
      return discord.snow.webhook.executeWebhook(webhook.id, webhook.token, data, {wait: true, disableEveryone: true})
 | 
					      return discord.snow.webhook.executeWebhook(webhook.id, webhook.token, data, {wait: true, thread_id: threadID, disableEveryone: true})
 | 
				
			||||||
   })
 | 
					   })
 | 
				
			||||||
   return result
 | 
					   return result
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,13 @@ const eventToMessage = sync.require("../converters/event-to-message")
 | 
				
			||||||
/** @param {import("../../types").Event.Outer<any>} event */
 | 
					/** @param {import("../../types").Event.Outer<any>} event */
 | 
				
			||||||
async function sendEvent(event) {
 | 
					async function sendEvent(event) {
 | 
				
			||||||
   // TODO: we just assume the bridge has already been created
 | 
					   // TODO: we just assume the bridge has already been created
 | 
				
			||||||
	const channelID = db.prepare("SELECT channel_id FROM channel_room WHERE room_id = ?").pluck().get(event.room_id)
 | 
						const row = db.prepare("SELECT channel_id, thread_parent FROM channel_room WHERE room_id = ?").get(event.room_id)
 | 
				
			||||||
 | 
						let channelID = row.channel_id
 | 
				
			||||||
 | 
						let threadID = undefined
 | 
				
			||||||
 | 
						if (row.thread_parent) {
 | 
				
			||||||
 | 
							threadID = channelID
 | 
				
			||||||
 | 
							channelID = row.thread_parent // it's the thread's parent... get with the times...
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   // no need to sync the matrix member to the other side. but if I did need to, this is where I'd do it
 | 
					   // no need to sync the matrix member to the other side. but if I did need to, this is where I'd do it
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +30,7 @@ async function sendEvent(event) {
 | 
				
			||||||
	const messageResponses = []
 | 
						const messageResponses = []
 | 
				
			||||||
	let eventPart = 0 // 0 is primary, 1 is supporting
 | 
						let eventPart = 0 // 0 is primary, 1 is supporting
 | 
				
			||||||
	for (const message of messages) {
 | 
						for (const message of messages) {
 | 
				
			||||||
      const messageResponse = await channelWebhook.sendMessageWithWebhook(channelID, message)
 | 
					      const messageResponse = await channelWebhook.sendMessageWithWebhook(channelID, message, threadID)
 | 
				
			||||||
		db.prepare("INSERT INTO event_message (event_id, event_type, event_subtype, message_id, channel_id, part, source) VALUES (?, ?, ?, ?, ?, ?, 0)").run(event.event_id, event.type, event.content.msgtype || null, messageResponse.id, channelID, eventPart) // source 0 = matrix
 | 
							db.prepare("INSERT INTO event_message (event_id, event_type, event_subtype, message_id, channel_id, part, source) VALUES (?, ?, ?, ?, ?, ?, 0)").run(event.event_id, event.type, event.content.msgtype || null, messageResponse.id, channelID, eventPart) // source 0 = matrix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		eventPart = 1 // TODO: use more intelligent algorithm to determine whether primary or supporting?
 | 
							eventPart = 1 // TODO: use more intelligent algorithm to determine whether primary or supporting?
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										7
									
								
								notes.md
									
										
									
									
									
								
							
							
						
						
									
										7
									
								
								notes.md
									
										
									
									
									
								
							| 
						 | 
					@ -9,6 +9,13 @@ A database will be used to store the discord id to matrix event id mapping. Tabl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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.
 | 
					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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Current manual process for setting up a server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Call createSpace.createSpace(discord.guilds.get(GUILD_ID))
 | 
				
			||||||
 | 
					2. Call createRoom.createAllForGuild(GUILD_ID)
 | 
				
			||||||
 | 
					3. Edit source code of event-dispatcher.js isGuildAllowed() and add the guild ID to the list
 | 
				
			||||||
 | 
					4. If developing, make sure SSH port forward is activated, then wait for events to sync over!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Transforming content
 | 
					## Transforming content
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. Upload attachments to mxc if they are small enough.
 | 
					1. Upload attachments to mxc if they are small enough.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										58
									
								
								test/data.js
									
										
									
									
									
								
							
							
						
						
									
										58
									
								
								test/data.js
									
										
									
									
									
								
							| 
						 | 
					@ -816,6 +816,64 @@ module.exports = {
 | 
				
			||||||
				format_type: 1,
 | 
									format_type: 1,
 | 
				
			||||||
				name: "pomu puff"
 | 
									name: "pomu puff"
 | 
				
			||||||
			}]
 | 
								}]
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							message_in_thread: {
 | 
				
			||||||
 | 
								type: 0,
 | 
				
			||||||
 | 
								tts: false,
 | 
				
			||||||
 | 
								timestamp: "2023-08-19T01:55:02.063000+00:00",
 | 
				
			||||||
 | 
								referenced_message: null,
 | 
				
			||||||
 | 
								position: 942,
 | 
				
			||||||
 | 
								pinned: false,
 | 
				
			||||||
 | 
								nonce: "1142275498206822400",
 | 
				
			||||||
 | 
								mentions: [],
 | 
				
			||||||
 | 
								mention_roles: [],
 | 
				
			||||||
 | 
								mention_everyone: false,
 | 
				
			||||||
 | 
								member: {
 | 
				
			||||||
 | 
									roles: [
 | 
				
			||||||
 | 
										"112767366235959296",  "118924814567211009",
 | 
				
			||||||
 | 
										"204427286542417920",  "199995902742626304",
 | 
				
			||||||
 | 
										"222168467627835392",  "238028326281805825",
 | 
				
			||||||
 | 
										"259806643414499328",  "265239342648131584",
 | 
				
			||||||
 | 
										"271173313575780353",  "287733611912757249",
 | 
				
			||||||
 | 
										"225744901915148298",  "305775031223320577",
 | 
				
			||||||
 | 
										"318243902521868288",  "348651574924541953",
 | 
				
			||||||
 | 
										"349185088157777920",  "378402925128712193",
 | 
				
			||||||
 | 
										"392141548932038658",  "393912152173576203",
 | 
				
			||||||
 | 
										"482860581670486028",  "495384759074160642",
 | 
				
			||||||
 | 
										"638988388740890635",  "373336013109461013",
 | 
				
			||||||
 | 
										"530220455085473813",  "454567553738473472",
 | 
				
			||||||
 | 
										"790724320824655873",  "1123518980456452097",
 | 
				
			||||||
 | 
										"1040735082610167858", "695946570482450442",
 | 
				
			||||||
 | 
										"1123460940935991296", "849737964090556488"
 | 
				
			||||||
 | 
									],
 | 
				
			||||||
 | 
									premium_since: null,
 | 
				
			||||||
 | 
									pending: false,
 | 
				
			||||||
 | 
									nick: null,
 | 
				
			||||||
 | 
									mute: false,
 | 
				
			||||||
 | 
									joined_at: "2015-11-11T09:55:40.321000+00:00",
 | 
				
			||||||
 | 
									flags: 0,
 | 
				
			||||||
 | 
									deaf: false,
 | 
				
			||||||
 | 
									communication_disabled_until: null,
 | 
				
			||||||
 | 
									avatar: null
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								id: "1142275501721911467",
 | 
				
			||||||
 | 
								flags: 0,
 | 
				
			||||||
 | 
								embeds: [],
 | 
				
			||||||
 | 
								edited_timestamp: null,
 | 
				
			||||||
 | 
								content: "don't mind me, posting something for cadence",
 | 
				
			||||||
 | 
								components: [],
 | 
				
			||||||
 | 
								channel_id: "910283343378120754",
 | 
				
			||||||
 | 
								author: {
 | 
				
			||||||
 | 
								  	username: "kumaccino",
 | 
				
			||||||
 | 
									public_flags: 128,
 | 
				
			||||||
 | 
									id: "113340068197859328",
 | 
				
			||||||
 | 
									global_name: "kumaccino",
 | 
				
			||||||
 | 
									discriminator: "0",
 | 
				
			||||||
 | 
									avatar_decoration_data: null,
 | 
				
			||||||
 | 
									avatar: "b48302623a12bc7c59a71328f72ccb39"
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								attachments: [],
 | 
				
			||||||
 | 
								guild_id: "112760669178241024"
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	message_update: {
 | 
						message_update: {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue