forked from cadence/out-of-your-element
Only offer to link channels the bridge can access
This commit is contained in:
parent
5631b7e956
commit
20dabf4ad5
4 changed files with 38 additions and 12 deletions
|
@ -1,5 +1,6 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
|
const DiscordTypes = require("discord-api-types/v10")
|
||||||
const {Endpoints, SnowTransfer} = require("snowtransfer")
|
const {Endpoints, SnowTransfer} = require("snowtransfer")
|
||||||
const {reg} = require("../matrix/read-registration")
|
const {reg} = require("../matrix/read-registration")
|
||||||
const {Client: CloudStorm} = require("cloudstorm")
|
const {Client: CloudStorm} = require("cloudstorm")
|
||||||
|
@ -36,15 +37,15 @@ class DiscordClient {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.ready = false
|
this.ready = false
|
||||||
/** @type {import("discord-api-types/v10").APIUser} */
|
/** @type {DiscordTypes.APIUser} */
|
||||||
// @ts-ignore avoid setting as or null because we know we need to wait for ready anyways
|
// @ts-ignore avoid setting as or null because we know we need to wait for ready anyways
|
||||||
this.user = null
|
this.user = null
|
||||||
/** @type {Pick<import("discord-api-types/v10").APIApplication, "id" | "flags">} */
|
/** @type {Pick<DiscordTypes.APIApplication, "id" | "flags">} */
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.application = null
|
this.application = null
|
||||||
/** @type {Map<string, import("discord-api-types/v10").APIChannel>} */
|
/** @type {Map<string, DiscordTypes.APIChannel>} */
|
||||||
this.channels = new Map()
|
this.channels = new Map()
|
||||||
/** @type {Map<string, import("discord-api-types/v10").APIGuild>} */
|
/** @type {Map<string, DiscordTypes.APIGuild & {members: DiscordTypes.APIGuildMember[]}>} */ // we get members from the GUILD_CREATE and we do maintain it
|
||||||
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()
|
||||||
|
|
|
@ -32,6 +32,7 @@ const utils = {
|
||||||
console.log(`Discord logged in as ${client.user.username}#${client.user.discriminator} (${client.user.id})`)
|
console.log(`Discord logged in as ${client.user.username}#${client.user.discriminator} (${client.user.id})`)
|
||||||
|
|
||||||
} else if (message.t === "GUILD_CREATE") {
|
} else if (message.t === "GUILD_CREATE") {
|
||||||
|
message.d.members = message.d.members.filter(m => m.user.id === client.user.id) // only keep the bot's own member - it's needed to determine private channels on web
|
||||||
client.guilds.set(message.d.id, message.d)
|
client.guilds.set(message.d.id, message.d)
|
||||||
const arr = []
|
const arr = []
|
||||||
client.guildChannelMap.set(message.d.id, arr)
|
client.guildChannelMap.set(message.d.id, arr)
|
||||||
|
@ -101,6 +102,13 @@ const utils = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (message.t === "GUILD_MEMBER_UPDATE") {
|
||||||
|
const guild = client.guilds.get(message.d.guild_id)
|
||||||
|
const member = guild?.members.find(m => m.user.id === message.d.user.id)
|
||||||
|
if (member) { // only update existing members (i.e. the bot's own member) - don't want to inflate the cache with new irrelevant ones
|
||||||
|
Object.assign(member, message.d)
|
||||||
|
}
|
||||||
|
|
||||||
} else if (message.t === "THREAD_CREATE") {
|
} else if (message.t === "THREAD_CREATE") {
|
||||||
client.channels.set(message.d.id, message.d)
|
client.channels.set(message.d.id, message.d)
|
||||||
if (message.d["guild_id"]) {
|
if (message.d["guild_id"]) {
|
||||||
|
|
|
@ -192,12 +192,17 @@ block body
|
||||||
.s-card.p0
|
.s-card.p0
|
||||||
ul.my8.ml24
|
ul.my8.ml24
|
||||||
each row in removedUncachedChannels
|
each row in removedUncachedChannels
|
||||||
li: a(href=`https://discord.com/channels/${guild_id}/${row.channel_id}`)= row.nick || row.name
|
li: a(href=`https://discord.com/channels/${guild_id}/${row.id}`)= row.nick || row.name
|
||||||
h3.mt24 Unavailable channels: Wrong type
|
h3.mt24 Unavailable channels: Wrong type
|
||||||
.s-card.p0
|
.s-card.p0
|
||||||
ul.my8.ml24
|
ul.my8.ml24
|
||||||
each row in removedWrongTypeChannels
|
each row in removedWrongTypeChannels
|
||||||
li: a(href=`https://discord.com/channels/${guild_id}/${row.channel_id}`) (#{row.type}) #{row.name}
|
li: a(href=`https://discord.com/channels/${guild_id}/${row.id}`) (#{row.type}) #{row.name}
|
||||||
|
h3.mt24 Unavailable channels: Bridge can't access
|
||||||
|
.s-card.p0
|
||||||
|
ul.my8.ml24
|
||||||
|
each row in removedPrivateChannels
|
||||||
|
li: a(href=`https://discord.com/channels/${guild_id}/${row.id}`)= row.name
|
||||||
div- // Rooms
|
div- // Rooms
|
||||||
h3.mt24 Unavailable rooms: Already linked
|
h3.mt24 Unavailable rooms: Already linked
|
||||||
.s-card.p0
|
.s-card.p0
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
|
const DiscordTypes = require("discord-api-types/v10")
|
||||||
const assert = require("assert/strict")
|
const assert = require("assert/strict")
|
||||||
const {z} = require("zod")
|
const {z} = require("zod")
|
||||||
const {H3Event, defineEventHandler, sendRedirect, createError, getValidatedQuery, readValidatedBody, setResponseHeader} = require("h3")
|
const {H3Event, defineEventHandler, sendRedirect, createError, getValidatedQuery, readValidatedBody, setResponseHeader} = require("h3")
|
||||||
|
@ -8,6 +9,7 @@ const {LRUCache} = require("lru-cache")
|
||||||
const Ty = require("../../types")
|
const Ty = require("../../types")
|
||||||
const uqr = require("uqr")
|
const uqr = require("uqr")
|
||||||
|
|
||||||
|
const {id: botID} = require("../../../addbot")
|
||||||
const {discord, as, sync, select, from, db} = require("../../passthrough")
|
const {discord, as, sync, select, from, db} = require("../../passthrough")
|
||||||
/** @type {import("../pug-sync")} */
|
/** @type {import("../pug-sync")} */
|
||||||
const pugSync = sync.require("../pug-sync")
|
const pugSync = sync.require("../pug-sync")
|
||||||
|
@ -15,6 +17,8 @@ const pugSync = sync.require("../pug-sync")
|
||||||
const createSpace = sync.require("../../d2m/actions/create-space")
|
const createSpace = sync.require("../../d2m/actions/create-space")
|
||||||
/** @type {import("../auth")} */
|
/** @type {import("../auth")} */
|
||||||
const auth = require("../auth")
|
const auth = require("../auth")
|
||||||
|
/** @type {import("../../discord/utils")} */
|
||||||
|
const utils = sync.require("../../discord/utils")
|
||||||
const {reg} = require("../../matrix/read-registration")
|
const {reg} = require("../../matrix/read-registration")
|
||||||
|
|
||||||
const schema = {
|
const schema = {
|
||||||
|
@ -68,10 +72,11 @@ function filterTo(xs, fn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} guildID
|
* @param {DiscordTypes.APIGuild} guild
|
||||||
* @param {Ty.R.Hierarchy[]} rooms
|
* @param {Ty.R.Hierarchy[]} rooms
|
||||||
|
* @param {string[]} roles
|
||||||
*/
|
*/
|
||||||
function getChannelRoomsLinks(guildID, rooms) {
|
function getChannelRoomsLinks(guild, rooms, roles) {
|
||||||
function getPosition(channel) {
|
function getPosition(channel) {
|
||||||
let position = 0
|
let position = 0
|
||||||
let looking = channel
|
let looking = channel
|
||||||
|
@ -83,7 +88,7 @@ function getChannelRoomsLinks(guildID, rooms) {
|
||||||
return position
|
return position
|
||||||
}
|
}
|
||||||
|
|
||||||
let channelIDs = discord.guildChannelMap.get(guildID)
|
let channelIDs = discord.guildChannelMap.get(guild.id)
|
||||||
assert(channelIDs)
|
assert(channelIDs)
|
||||||
|
|
||||||
let linkedChannels = select("channel_room", ["channel_id", "room_id", "name", "nick"], {channel_id: channelIDs}).all()
|
let linkedChannels = select("channel_room", ["channel_id", "room_id", "name", "nick"], {channel_id: channelIDs}).all()
|
||||||
|
@ -93,8 +98,13 @@ function getChannelRoomsLinks(guildID, rooms) {
|
||||||
linkedChannelsWithDetails.sort((a, b) => getPosition(a.channel) - getPosition(b.channel))
|
linkedChannelsWithDetails.sort((a, b) => getPosition(a.channel) - getPosition(b.channel))
|
||||||
|
|
||||||
let unlinkedChannelIDs = channelIDs.filter(c => !linkedChannelIDs.includes(c))
|
let unlinkedChannelIDs = channelIDs.filter(c => !linkedChannelIDs.includes(c))
|
||||||
|
/** @type {DiscordTypes.APIGuildChannel[]} */ // @ts-ignore
|
||||||
let unlinkedChannels = unlinkedChannelIDs.map(c => discord.channels.get(c))
|
let unlinkedChannels = unlinkedChannelIDs.map(c => discord.channels.get(c))
|
||||||
let removedWrongTypeChannels = filterTo(unlinkedChannels, c => c && [0, 5].includes(c.type))
|
let removedWrongTypeChannels = filterTo(unlinkedChannels, c => c && [0, 5].includes(c.type))
|
||||||
|
let removedPrivateChannels = filterTo(unlinkedChannels, c => {
|
||||||
|
const permissions = utils.getPermissions(roles, guild.roles, botID, c["permission_overwrites"])
|
||||||
|
return utils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.ViewChannel)
|
||||||
|
})
|
||||||
unlinkedChannels.sort((a, b) => getPosition(a) - getPosition(b))
|
unlinkedChannels.sort((a, b) => getPosition(a) - getPosition(b))
|
||||||
|
|
||||||
let linkedRoomIDs = linkedChannels.map(c => c.room_id)
|
let linkedRoomIDs = linkedChannels.map(c => c.room_id)
|
||||||
|
@ -107,7 +117,7 @@ function getChannelRoomsLinks(guildID, rooms) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
linkedChannelsWithDetails, unlinkedChannels, unlinkedRooms,
|
linkedChannelsWithDetails, unlinkedChannels, unlinkedRooms,
|
||||||
removedUncachedChannels, removedWrongTypeChannels, removedLinkedRooms, removedWrongTypeRooms, removedArchivedThreadRooms
|
removedUncachedChannels, removedWrongTypeChannels, removedPrivateChannels, removedLinkedRooms, removedWrongTypeRooms, removedArchivedThreadRooms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,16 +140,18 @@ as.router.get("/guild", defineEventHandler(async event => {
|
||||||
return pugSync.render(event, "guild_not_linked.pug", {guild, guild_id, spaces})
|
return pugSync.render(event, "guild_not_linked.pug", {guild, guild_id, spaces})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const roles = guild.members?.find(m => m.user.id === botID)?.roles || []
|
||||||
|
|
||||||
// Easy mode guild that hasn't been linked yet - need to remove elements that would require an existing space
|
// Easy mode guild that hasn't been linked yet - need to remove elements that would require an existing space
|
||||||
if (!row.space_id) {
|
if (!row.space_id) {
|
||||||
const links = getChannelRoomsLinks(guild_id, [])
|
const links = getChannelRoomsLinks(guild, [], roles)
|
||||||
return pugSync.render(event, "guild.pug", {guild, guild_id, ...links, ...row})
|
return pugSync.render(event, "guild.pug", {guild, guild_id, ...links, ...row})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Linked guild
|
// Linked guild
|
||||||
const api = getAPI(event)
|
const api = getAPI(event)
|
||||||
const rooms = await api.getFullHierarchy(row.space_id)
|
const rooms = await api.getFullHierarchy(row.space_id)
|
||||||
const links = getChannelRoomsLinks(guild_id, rooms)
|
const links = getChannelRoomsLinks(guild, rooms, roles)
|
||||||
return pugSync.render(event, "guild.pug", {guild, guild_id, ...links, ...row})
|
return pugSync.render(event, "guild.pug", {guild, guild_id, ...links, ...row})
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue