2023-05-04 20:25:00 +00:00
// @ts-check
2023-08-19 06:39:23 +00:00
const assert = require ( "assert" )
2023-08-22 05:11:07 +00:00
const DiscordTypes = require ( "discord-api-types/v10" )
2023-05-04 20:25:00 +00:00
const passthrough = require ( "../../passthrough" )
2023-08-23 00:31:31 +00:00
const { discord , sync , db } = passthrough
2023-05-08 11:37:51 +00:00
/** @type {import("../../matrix/api")} */
const api = sync . require ( "../../matrix/api" )
2023-08-22 05:11:07 +00:00
/** @type {import("../../matrix/file")} */
const file = sync . require ( "../../matrix/file" )
/** @type {import("./create-room")} */
const createRoom = sync . require ( "./create-room" )
2023-08-23 00:31:31 +00:00
/** @type {import("../../matrix/kstate")} */
const ks = sync . require ( "../../matrix/kstate" )
2023-05-04 20:25:00 +00:00
/ * *
* @ param { import ( "discord-api-types/v10" ) . RESTGetAPIGuildResult } guild
2023-08-22 05:11:07 +00:00
* @ param { any } kstate
2023-05-04 20:25:00 +00:00
* /
2023-08-22 05:11:07 +00:00
async function createSpace ( guild , kstate ) {
const name = kstate [ "m.room.name/" ] . name
const topic = kstate [ "m.room.topic/" ] ? . topic || undefined
assert ( name )
2023-07-01 13:40:54 +00:00
const roomID = await api . createRoom ( {
2023-08-22 05:11:07 +00:00
name ,
2023-08-19 06:39:23 +00:00
preset : "private_chat" , // cannot join space unless invited
2023-05-04 20:25:00 +00:00
visibility : "private" ,
power _level _content _override : {
2023-08-19 06:39:23 +00:00
events _default : 100 , // space can only be managed by bridge
invite : 0 // any existing member can invite others
2023-05-04 20:25:00 +00:00
} ,
invite : [ "@cadence:cadence.moe" ] , // TODO
2023-08-22 05:11:07 +00:00
topic ,
2023-05-04 20:25:00 +00:00
creation _content : {
type : "m.space"
} ,
2023-08-22 05:11:07 +00:00
initial _state : ks . kstateToState ( kstate )
2023-05-04 20:25:00 +00:00
} )
2023-05-08 12:58:46 +00:00
db . prepare ( "INSERT INTO guild_space (guild_id, space_id) VALUES (?, ?)" ) . run ( guild . id , roomID )
return roomID
2023-05-04 20:25:00 +00:00
}
2023-08-22 05:11:07 +00:00
/ * *
* @ param { DiscordTypes . APIGuild } guild ]
* /
async function guildToKState ( guild ) {
const avatarEventContent = { }
if ( guild . icon ) {
avatarEventContent . discord _path = file . guildIcon ( guild )
avatarEventContent . url = await file . uploadDiscordFileToMxc ( avatarEventContent . discord _path ) // TODO: somehow represent future values in kstate (callbacks?), while still allowing for diffing, so test cases don't need to touch the media API
}
let history _visibility = "invited"
if ( guild [ "thread_metadata" ] ) history _visibility = "world_readable"
const guildKState = {
"m.room.name/" : { name : guild . name } ,
"m.room.avatar/" : avatarEventContent ,
"m.room.guest_access/" : { guest _access : "can_join" } , // guests can join space if other conditions are met
2023-08-23 00:31:31 +00:00
"m.room.history_visibility/" : { history _visibility : "invited" } // any events sent after user was invited are visible
2023-08-22 05:11:07 +00:00
}
return guildKState
}
async function syncSpace ( guildID ) {
/** @ts-ignore @type {DiscordTypes.APIGuild} */
const guild = discord . guilds . get ( guildID )
assert . ok ( guild )
2023-08-23 00:31:31 +00:00
/** @type {string?} */
const spaceID = db . prepare ( "SELECT space_id from guild_space WHERE guild_id = ?" ) . pluck ( ) . get ( guildID )
2023-08-22 05:11:07 +00:00
const guildKState = await guildToKState ( guild )
2023-08-23 00:31:31 +00:00
if ( ! spaceID ) {
2023-08-22 05:11:07 +00:00
const spaceID = await createSpace ( guild , guildKState )
2023-08-23 00:31:31 +00:00
return spaceID // Naturally, the newly created space is already up to date, so we can always skip syncing here.
2023-08-22 05:11:07 +00:00
}
2023-08-23 00:31:31 +00:00
console . log ( ` [space sync] to matrix: ${ guild . name } ` )
2023-08-22 05:11:07 +00:00
2023-08-23 00:31:31 +00:00
// sync channel state to room
const spaceKState = await createRoom . roomToKState ( spaceID )
const spaceDiff = ks . diffKState ( spaceKState , guildKState )
await createRoom . applyKStateDiffToRoom ( spaceID , spaceDiff )
2023-08-22 05:11:07 +00:00
2023-08-23 00:31:31 +00:00
return spaceID
}
2023-08-22 05:11:07 +00:00
2023-05-04 20:25:00 +00:00
module . exports . createSpace = createSpace
2023-08-23 00:31:31 +00:00
module . exports . syncSpace = syncSpace
module . exports . guildToKState = guildToKState