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…
Reference in a new issue