get createRoom and ensureRoom interface working
This commit is contained in:
		
							parent
							
								
									1e7e66dc31
								
							
						
					
					
						commit
						7526d63690
					
				
					 4 changed files with 57 additions and 9 deletions
				
			
		| 
						 | 
					@ -124,13 +124,15 @@ async function channelToKState(channel, guild) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 | 
					 * Create a bridge room, store the relationship in the database, and add it to the guild's space.
 | 
				
			||||||
 * @param {import("discord-api-types/v10").APIGuildTextChannel} channel
 | 
					 * @param {import("discord-api-types/v10").APIGuildTextChannel} channel
 | 
				
			||||||
 * @param guild
 | 
					 * @param guild
 | 
				
			||||||
 * @param {string} spaceID
 | 
					 * @param {string} spaceID
 | 
				
			||||||
 * @param {any} kstate
 | 
					 * @param {any} kstate
 | 
				
			||||||
 | 
					 * @returns {Promise<string>} room ID
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async function createRoom(channel, guild, spaceID, kstate) {
 | 
					async function createRoom(channel, guild, spaceID, kstate) {
 | 
				
			||||||
	const root = await api.createRoom({
 | 
						const roomID = await api.createRoom({
 | 
				
			||||||
		name: channel.name,
 | 
							name: channel.name,
 | 
				
			||||||
		topic: channel.topic || undefined,
 | 
							topic: channel.topic || undefined,
 | 
				
			||||||
		preset: "private_chat",
 | 
							preset: "private_chat",
 | 
				
			||||||
| 
						 | 
					@ -139,12 +141,14 @@ async function createRoom(channel, guild, spaceID, kstate) {
 | 
				
			||||||
		initial_state: kstateToState(kstate)
 | 
							initial_state: kstateToState(kstate)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	db.prepare("INSERT INTO channel_room (channel_id, room_id) VALUES (?, ?)").run(channel.id, root.room_id)
 | 
						db.prepare("INSERT INTO channel_room (channel_id, room_id) VALUES (?, ?)").run(channel.id, roomID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Put the newly created child into the space
 | 
						// Put the newly created child into the space
 | 
				
			||||||
	await api.sendState(spaceID, "m.space.child", root.room_id, {
 | 
						await api.sendState(spaceID, "m.space.child", roomID, { // TODO: should I deduplicate with the equivalent code from syncRoom?
 | 
				
			||||||
		via: ["cadence.moe"] // TODO: use the proper server
 | 
							via: ["cadence.moe"] // TODO: use the proper server
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return roomID
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -158,22 +162,46 @@ function channelToGuild(channel) {
 | 
				
			||||||
	return guild
 | 
						return guild
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
						Ensure flow:
 | 
				
			||||||
 | 
						1. Get IDs
 | 
				
			||||||
 | 
						2. Does room exist? If so great!
 | 
				
			||||||
 | 
						(it doesn't, so it needs to be created)
 | 
				
			||||||
 | 
						3. Get kstate for channel
 | 
				
			||||||
 | 
						4. Create room, return new ID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						New combined flow with ensure / sync:
 | 
				
			||||||
 | 
						1. Get IDs
 | 
				
			||||||
 | 
						2. Does room exist?
 | 
				
			||||||
 | 
						2.5: If room does exist AND don't need to sync: return here
 | 
				
			||||||
 | 
						3. Get kstate for channel
 | 
				
			||||||
 | 
						4. Create room with kstate if room doesn't exist
 | 
				
			||||||
 | 
						5. Get and update room state with kstate if room does exist
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @param {string} channelID
 | 
					 * @param {string} channelID
 | 
				
			||||||
 | 
					 * @param {boolean} shouldActuallySync false if just need to ensure room exists (which is a quick database check), true if also want to sync room data when it does exist (slow)
 | 
				
			||||||
 | 
					 * @returns {Promise<string>} room ID
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async function syncRoom(channelID) {
 | 
					async function _syncRoom(channelID, shouldActuallySync) {
 | 
				
			||||||
	/** @ts-ignore @type {import("discord-api-types/v10").APIGuildChannel} */
 | 
						/** @ts-ignore @type {import("discord-api-types/v10").APIGuildChannel} */
 | 
				
			||||||
	const channel = discord.channels.get(channelID)
 | 
						const channel = discord.channels.get(channelID)
 | 
				
			||||||
	assert.ok(channel)
 | 
						assert.ok(channel)
 | 
				
			||||||
	const guild = channelToGuild(channel)
 | 
						const guild = channelToGuild(channel)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const {spaceID, channelKState} = await channelToKState(channel, guild)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/** @type {string?} */
 | 
						/** @type {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 from channel_room WHERE channel_id = ?").pluck().get(channel.id)
 | 
				
			||||||
	if (!existing) {
 | 
						if (!existing) {
 | 
				
			||||||
 | 
							const {spaceID, channelKState} = await channelToKState(channel, guild)
 | 
				
			||||||
		return createRoom(channel, guild, spaceID, channelKState)
 | 
							return createRoom(channel, guild, spaceID, channelKState)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
 | 
							if (!shouldActuallySync) {
 | 
				
			||||||
 | 
								return existing // only need to ensure room exists, and it does. return the room ID
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							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)
 | 
				
			||||||
		const roomDiff = diffKState(roomKState, channelKState)
 | 
							const roomDiff = diffKState(roomKState, channelKState)
 | 
				
			||||||
| 
						 | 
					@ -187,10 +215,20 @@ async function syncRoom(channelID) {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
		const spaceApply = applyKStateDiffToRoom(spaceID, spaceDiff)
 | 
							const spaceApply = applyKStateDiffToRoom(spaceID, spaceDiff)
 | 
				
			||||||
		return Promise.all([roomApply, spaceApply])
 | 
							await Promise.all([roomApply, spaceApply])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return existing
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function ensureRoom(channelID) {
 | 
				
			||||||
 | 
						return _syncRoom(channelID, false)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function syncRoom(channelID) {
 | 
				
			||||||
 | 
						return _syncRoom(channelID, true)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function createAllForGuild(guildID) {
 | 
					async function createAllForGuild(guildID) {
 | 
				
			||||||
	const channelIDs = discord.guildChannelMap.get(guildID)
 | 
						const channelIDs = discord.guildChannelMap.get(guildID)
 | 
				
			||||||
	assert.ok(channelIDs)
 | 
						assert.ok(channelIDs)
 | 
				
			||||||
| 
						 | 
					@ -200,6 +238,7 @@ async function createAllForGuild(guildID) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports.createRoom = createRoom
 | 
					module.exports.createRoom = createRoom
 | 
				
			||||||
 | 
					module.exports.ensureRoom = ensureRoom
 | 
				
			||||||
module.exports.syncRoom = syncRoom
 | 
					module.exports.syncRoom = syncRoom
 | 
				
			||||||
module.exports.createAllForGuild = createAllForGuild
 | 
					module.exports.createAllForGuild = createAllForGuild
 | 
				
			||||||
module.exports.kstateToState = kstateToState
 | 
					module.exports.kstateToState = kstateToState
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,13 +11,15 @@ const messageToEvent = sync.require("../converters/message-to-event")
 | 
				
			||||||
const api = sync.require("../../matrix/api")
 | 
					const api = sync.require("../../matrix/api")
 | 
				
			||||||
/** @type {import("./register-user")} */
 | 
					/** @type {import("./register-user")} */
 | 
				
			||||||
const registerUser = sync.require("./register-user")
 | 
					const registerUser = sync.require("./register-user")
 | 
				
			||||||
 | 
					/** @type {import("../actions/create-room")} */
 | 
				
			||||||
 | 
					const createRoom = sync.require("../actions/create-room")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @param {import("discord-api-types/v10").GatewayMessageCreateDispatchData} message
 | 
					 * @param {import("discord-api-types/v10").GatewayMessageCreateDispatchData} message
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async function sendMessage(message) {
 | 
					async function sendMessage(message) {
 | 
				
			||||||
	const event = messageToEvent.messageToEvent(message)
 | 
						const event = messageToEvent.messageToEvent(message)
 | 
				
			||||||
	const roomID = "!VwVlIAjOjejUpDhlbA:cadence.moe"
 | 
						const roomID = await createRoom.ensureRoom(message.channel_id)
 | 
				
			||||||
	let senderMxid = null
 | 
						let senderMxid = null
 | 
				
			||||||
	if (!message.webhook_id) {
 | 
						if (!message.webhook_id) {
 | 
				
			||||||
		senderMxid = await registerUser.ensureSimJoined(message.author, roomID)
 | 
							senderMxid = await registerUser.ensureSimJoined(message.author, roomID)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@ module.exports = {
 | 
				
			||||||
	 * @param {import("discord-api-types/v10").GatewayMessageCreateDispatchData} message
 | 
						 * @param {import("discord-api-types/v10").GatewayMessageCreateDispatchData} message
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	onMessageCreate(client, message) {
 | 
						onMessageCreate(client, message) {
 | 
				
			||||||
 | 
							if (message.guild_id !== "112760669178241024") return // TODO: activate on other servers (requires the space creation flow to be done first)
 | 
				
			||||||
		sendMessage.sendMessage(message)
 | 
							sendMessage.sendMessage(message)
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,12 @@ const file = sync.require("./file")
 | 
				
			||||||
/** @type {import("./txnid")} */
 | 
					/** @type {import("./txnid")} */
 | 
				
			||||||
const makeTxnId = sync.require("./txnid")
 | 
					const makeTxnId = sync.require("./txnid")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function path(p, mxid = null) {
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {string} p endpoint to access
 | 
				
			||||||
 | 
					 * @param {string} [mxid] optional: user to act as, for the ?user_id parameter
 | 
				
			||||||
 | 
					 * @returns {string} the new endpoint
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function path(p, mxid) {
 | 
				
			||||||
   if (!mxid) return p
 | 
					   if (!mxid) return p
 | 
				
			||||||
   const u = new URL(p, "http://localhost")
 | 
					   const u = new URL(p, "http://localhost")
 | 
				
			||||||
   u.searchParams.set("user_id", mxid)
 | 
					   u.searchParams.set("user_id", mxid)
 | 
				
			||||||
| 
						 | 
					@ -65,6 +70,7 @@ function getAllState(roomID) {
 | 
				
			||||||
 * @param {string} roomID
 | 
					 * @param {string} roomID
 | 
				
			||||||
 * @param {string} type
 | 
					 * @param {string} type
 | 
				
			||||||
 * @param {string} stateKey
 | 
					 * @param {string} stateKey
 | 
				
			||||||
 | 
					 * @param {string} [mxid]
 | 
				
			||||||
 * @returns {Promise<string>} event ID
 | 
					 * @returns {Promise<string>} event ID
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async function sendState(roomID, type, stateKey, content, mxid) {
 | 
					async function sendState(roomID, type, stateKey, content, mxid) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue