Migrate all legacy commands to interactions
This commit is contained in:
parent
b3daa6b84c
commit
6bc3eaf866
5 changed files with 92 additions and 281 deletions
|
@ -27,8 +27,6 @@ const updatePins = sync.require("./actions/update-pins")
|
||||||
const api = sync.require("../matrix/api")
|
const api = sync.require("../matrix/api")
|
||||||
/** @type {import("../discord/utils")} */
|
/** @type {import("../discord/utils")} */
|
||||||
const dUtils = sync.require("../discord/utils")
|
const dUtils = sync.require("../discord/utils")
|
||||||
/** @type {import("../discord/discord-command-handler")}) */
|
|
||||||
const discordCommandHandler = sync.require("../discord/discord-command-handler")
|
|
||||||
/** @type {import("../m2d/converters/utils")} */
|
/** @type {import("../m2d/converters/utils")} */
|
||||||
const mxUtils = require("../m2d/converters/utils")
|
const mxUtils = require("../m2d/converters/utils")
|
||||||
/** @type {import("./actions/speedbump")} */
|
/** @type {import("./actions/speedbump")} */
|
||||||
|
@ -266,7 +264,6 @@ module.exports = {
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
await sendMessage.sendMessage(message, channel, guild, row),
|
await sendMessage.sendMessage(message, channel, guild, row),
|
||||||
await discordCommandHandler.execute(message, channel, guild)
|
|
||||||
|
|
||||||
retrigger.messageFinishedBridging(message.id)
|
retrigger.messageFinishedBridging(message.id)
|
||||||
},
|
},
|
||||||
|
@ -313,7 +310,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.
|
||||||
discordCommandHandler.onReactionAdd(data)
|
|
||||||
await addReaction.addReaction(data)
|
await addReaction.addReaction(data)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,274 +0,0 @@
|
||||||
// @ts-check
|
|
||||||
|
|
||||||
const assert = require("assert").strict
|
|
||||||
const util = require("util")
|
|
||||||
const DiscordTypes = require("discord-api-types/v10")
|
|
||||||
const {reg} = require("../matrix/read-registration")
|
|
||||||
const {addbot} = require("../../addbot")
|
|
||||||
|
|
||||||
const {discord, sync, db, select} = require("../passthrough")
|
|
||||||
/** @type {import("../matrix/api")}) */
|
|
||||||
const api = sync.require("../matrix/api")
|
|
||||||
/** @type {import("../matrix/file")} */
|
|
||||||
const file = sync.require("../matrix/file")
|
|
||||||
/** @type {import("../m2d/converters/utils")} */
|
|
||||||
const mxUtils = sync.require("../m2d/converters/utils")
|
|
||||||
/** @type {import("../d2m/actions/create-space")} */
|
|
||||||
const createSpace = sync.require("../d2m/actions/create-space")
|
|
||||||
/** @type {import("./utils")} */
|
|
||||||
const utils = sync.require("./utils")
|
|
||||||
|
|
||||||
const PREFIX = "//"
|
|
||||||
|
|
||||||
let buttons = []
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} channelID where to add the button
|
|
||||||
* @param {string} messageID where to add the button
|
|
||||||
* @param {string} emoji emoji to add as a button
|
|
||||||
* @param {string} userID only listen for responses from this user
|
|
||||||
* @returns {Promise<import("discord-api-types/v10").GatewayMessageReactionAddDispatchData>}
|
|
||||||
*/
|
|
||||||
async function addButton(channelID, messageID, emoji, userID) {
|
|
||||||
await discord.snow.channel.createReaction(channelID, messageID, emoji)
|
|
||||||
return new Promise(resolve => {
|
|
||||||
buttons.push({channelID, messageID, userID, resolve, created: Date.now()})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear out old buttons every so often to free memory
|
|
||||||
setInterval(() => {
|
|
||||||
const now = Date.now()
|
|
||||||
buttons = buttons.filter(b => now - b.created < 2*60*60*1000)
|
|
||||||
}, 10*60*1000)
|
|
||||||
|
|
||||||
/** @param {import("discord-api-types/v10").GatewayMessageReactionAddDispatchData} data */
|
|
||||||
function onReactionAdd(data) {
|
|
||||||
const button = buttons.find(b => b.channelID === data.channel_id && b.messageID === data.message_id && b.userID === data.user_id)
|
|
||||||
if (button) {
|
|
||||||
buttons = buttons.filter(b => b !== button) // remove button data so it can't be clicked again
|
|
||||||
button.resolve(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @callback CommandExecute
|
|
||||||
* @param {DiscordTypes.GatewayMessageCreateDispatchData} message
|
|
||||||
* @param {DiscordTypes.APIGuildTextChannel} channel
|
|
||||||
* @param {DiscordTypes.APIGuild} guild
|
|
||||||
* @param {Partial<DiscordTypes.RESTPostAPIChannelMessageJSONBody>} [ctx]
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef Command
|
|
||||||
* @property {string[]} aliases
|
|
||||||
* @property {(message: DiscordTypes.GatewayMessageCreateDispatchData, channel: DiscordTypes.APIGuildTextChannel, guild: DiscordTypes.APIGuild) => Promise<any>} execute
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @param {CommandExecute} execute */
|
|
||||||
function replyctx(execute) {
|
|
||||||
/** @type {CommandExecute} */
|
|
||||||
return function(message, channel, guild, ctx = {}) {
|
|
||||||
ctx.message_reference = {
|
|
||||||
message_id: message.id,
|
|
||||||
channel_id: channel.id,
|
|
||||||
guild_id: guild.id,
|
|
||||||
fail_if_not_exists: false
|
|
||||||
}
|
|
||||||
return execute(message, channel, guild, ctx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @type {Command[]} */
|
|
||||||
const commands = [{
|
|
||||||
aliases: ["icon", "avatar", "roomicon", "roomavatar", "channelicon", "channelavatar"],
|
|
||||||
execute: replyctx(
|
|
||||||
async (message, channel, guild, ctx) => {
|
|
||||||
// Guard
|
|
||||||
const roomID = select("channel_room", "room_id", {channel_id: channel.id}).pluck().get()
|
|
||||||
if (!roomID) return discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: "This channel isn't bridged to the other side."
|
|
||||||
})
|
|
||||||
|
|
||||||
// Current avatar
|
|
||||||
const avatarEvent = await api.getStateEvent(roomID, "m.room.avatar", "")
|
|
||||||
let currentAvatarMessage =
|
|
||||||
( avatarEvent.url ? `Current room-specific avatar: ${mxUtils.getPublicUrlForMxc(avatarEvent.url)}`
|
|
||||||
: "No avatar. Now's your time to strike. Use `//icon` again with a link or upload to set the room-specific avatar.")
|
|
||||||
|
|
||||||
// Next potential avatar
|
|
||||||
const nextAvatarURL = message.attachments.find(a => a.content_type?.startsWith("image/"))?.url || message.content.match(/https?:\/\/[^ ]+\.[^ ]+\.(?:png|jpg|jpeg|webp)\b/)?.[0]
|
|
||||||
let nextAvatarMessage =
|
|
||||||
( nextAvatarURL ? `\nYou want to set it to: ${nextAvatarURL}\nHit ✅ to make it happen.`
|
|
||||||
: "")
|
|
||||||
|
|
||||||
const sent = await discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: currentAvatarMessage + nextAvatarMessage
|
|
||||||
})
|
|
||||||
|
|
||||||
if (nextAvatarURL) {
|
|
||||||
addButton(channel.id, sent.id, "✅", message.author.id).then(async data => {
|
|
||||||
const mxcUrl = await file.uploadDiscordFileToMxc(nextAvatarURL)
|
|
||||||
await api.sendState(roomID, "m.room.avatar", "", {
|
|
||||||
url: mxcUrl
|
|
||||||
})
|
|
||||||
db.prepare("UPDATE channel_room SET custom_avatar = ? WHERE channel_id = ?").run(mxcUrl, channel.id)
|
|
||||||
await discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: "Your creation is unleashed. Any complaints will be redirected to Grelbo."
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}, {
|
|
||||||
aliases: ["invite"],
|
|
||||||
execute: replyctx(
|
|
||||||
async (message, channel, guild, ctx) => {
|
|
||||||
// Check guild is bridged
|
|
||||||
const spaceID = select("guild_space", "space_id", {guild_id: guild.id}).pluck().get()
|
|
||||||
const roomID = select("channel_room", "room_id", {channel_id: channel.id}).pluck().get()
|
|
||||||
if (!spaceID || !roomID) return discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: "This server isn't bridged to Matrix, so you can't invite Matrix users."
|
|
||||||
})
|
|
||||||
|
|
||||||
// Check CREATE_INSTANT_INVITE permission
|
|
||||||
assert(message.member)
|
|
||||||
const guildPermissions = utils.getPermissions(message.member.roles, guild.roles)
|
|
||||||
if (!(guildPermissions & DiscordTypes.PermissionFlagsBits.CreateInstantInvite)) {
|
|
||||||
return discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: "You don't have permission to invite people to this Discord server."
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Guard against accidental mentions instead of the MXID
|
|
||||||
if (message.content.match(/<[@#:].*>/)) return discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: "You have to say the Matrix ID of the person you want to invite, but you mentioned a Discord user in your message.\nOne way to fix this is by writing `` ` `` backticks `` ` `` around the Matrix ID."
|
|
||||||
})
|
|
||||||
|
|
||||||
// Get named MXID
|
|
||||||
const mxid = message.content.match(/@([^:]+):([a-z0-9:-]+\.[a-z0-9.:-]+)/)?.[0]
|
|
||||||
if (!mxid) return discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: "You have to say the Matrix ID of the person you want to invite. Matrix IDs look like this: `@username:example.org`"
|
|
||||||
})
|
|
||||||
|
|
||||||
// Check for existing invite to the space
|
|
||||||
let spaceMember
|
|
||||||
try {
|
|
||||||
spaceMember = await api.getStateEvent(spaceID, "m.room.member", mxid)
|
|
||||||
} catch (e) {}
|
|
||||||
if (spaceMember && spaceMember.membership === "invite") {
|
|
||||||
return discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: `\`${mxid}\` already has an invite, which they haven't accepted yet.`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invite Matrix user if not in space
|
|
||||||
if (!spaceMember || spaceMember.membership !== "join") {
|
|
||||||
await api.inviteToRoom(spaceID, mxid)
|
|
||||||
return discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: `You invited \`${mxid}\` to the server.`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Matrix user *is* in the space, maybe we want to invite them to this channel?
|
|
||||||
let roomMember
|
|
||||||
try {
|
|
||||||
roomMember = await api.getStateEvent(roomID, "m.room.member", mxid)
|
|
||||||
} catch (e) {}
|
|
||||||
if (!roomMember || (roomMember.membership !== "join" && roomMember.membership !== "invite")) {
|
|
||||||
const sent = await discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: `\`${mxid}\` is already in this server. Would you like to additionally invite them to this specific channel?\nHit ✅ to make it happen.`
|
|
||||||
})
|
|
||||||
return addButton(channel.id, sent.id, "✅", message.author.id).then(async data => {
|
|
||||||
await api.inviteToRoom(roomID, mxid)
|
|
||||||
await discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: `You invited \`${mxid}\` to the channel.`
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Matrix user *is* in the space and in the channel.
|
|
||||||
await discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: `\`${mxid}\` is already in this server and this channel.`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}, {
|
|
||||||
aliases: ["addbot"],
|
|
||||||
execute: replyctx(
|
|
||||||
async (message, channel, guild, ctx) => {
|
|
||||||
return discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: addbot()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}, {
|
|
||||||
aliases: ["privacy", "discoverable", "publish", "published"],
|
|
||||||
execute: replyctx(
|
|
||||||
async (message, channel, guild, ctx) => {
|
|
||||||
const current = select("guild_space", "privacy_level", {guild_id: guild.id}).pluck().get()
|
|
||||||
if (current == null) {
|
|
||||||
return discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: "This server isn't bridged to the other side."
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const levels = ["invite", "link", "directory"]
|
|
||||||
const level = levels.findIndex(x => message.content.includes(x))
|
|
||||||
if (level === -1) {
|
|
||||||
return discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: "**Usage: `//privacy <level>`**. This will set who can join the space on Matrix-side. There are three levels:"
|
|
||||||
+ "\n`invite`: Can only join with a direct in-app invite from another Matrix user, or the //invite command."
|
|
||||||
+ "\n`link`: Matrix links can be created and shared like Discord's invite links. `invite` features also work."
|
|
||||||
+ "\n`directory`: Publishes to the Matrix in-app directory, like Server Discovery. Preview enabled. `invite` and `link` also work."
|
|
||||||
+ `\n**Current privacy level: \`${levels[current]}\`**`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(message.member)
|
|
||||||
const guildPermissions = utils.getPermissions(message.member.roles, guild.roles)
|
|
||||||
if (guild.owner_id !== message.author.id && !(guildPermissions & BigInt(0x28))) { // MANAGE_GUILD | ADMINISTRATOR
|
|
||||||
return discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: "You don't have permission to change the privacy level. You need Manage Server or Administrator."
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
db.prepare("UPDATE guild_space SET privacy_level = ? WHERE guild_id = ?").run(level, guild.id)
|
|
||||||
discord.snow.channel.createMessage(channel.id, {
|
|
||||||
...ctx,
|
|
||||||
content: `Privacy level updated to \`${levels[level]}\`. Changes will apply shortly.`
|
|
||||||
})
|
|
||||||
await createSpace.syncSpaceFully(guild.id)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}]
|
|
||||||
|
|
||||||
/** @type {CommandExecute} */
|
|
||||||
async function execute(message, channel, guild) {
|
|
||||||
if (!message.content.startsWith(PREFIX)) return
|
|
||||||
const words = message.content.slice(PREFIX.length).split(" ")
|
|
||||||
const commandName = words[0]
|
|
||||||
const command = commands.find(c => c.aliases.includes(commandName))
|
|
||||||
if (!command) return
|
|
||||||
|
|
||||||
await command.execute(message, channel, guild)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.execute = execute
|
|
||||||
module.exports.onReactionAdd = onReactionAdd
|
|
|
@ -5,7 +5,6 @@ const Ty = require("../../types")
|
||||||
const {discord, sync, db, select, from} = require("../../passthrough")
|
const {discord, sync, db, select, from} = require("../../passthrough")
|
||||||
const assert = require("assert/strict")
|
const assert = require("assert/strict")
|
||||||
|
|
||||||
|
|
||||||
/** @type {import("../../matrix/api")} */
|
/** @type {import("../../matrix/api")} */
|
||||||
const api = sync.require("../../matrix/api")
|
const api = sync.require("../../matrix/api")
|
||||||
|
|
||||||
|
|
59
src/discord/interactions/privacy.js
Normal file
59
src/discord/interactions/privacy.js
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
const DiscordTypes = require("discord-api-types/v10")
|
||||||
|
const {discord, sync, db, select} = require("../../passthrough")
|
||||||
|
const {id: botID} = require("../../../addbot")
|
||||||
|
|
||||||
|
/** @type {import("../../d2m/actions/create-space")} */
|
||||||
|
const createSpace = sync.require("../../d2m/actions/create-space")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {DiscordTypes.APIChatInputApplicationCommandGuildInteraction} interaction
|
||||||
|
*/
|
||||||
|
async function interact({id, token, data, guild_id}) {
|
||||||
|
// Check guild is bridged
|
||||||
|
const current = select("guild_space", "privacy_level", {guild_id}).pluck().get()
|
||||||
|
if (current == null) return {
|
||||||
|
type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
|
||||||
|
data: {
|
||||||
|
content: "This server isn't bridged to Matrix, so you can't set the Matrix privacy level.",
|
||||||
|
flags: DiscordTypes.MessageFlags.Ephemeral
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get input level
|
||||||
|
/** @type {DiscordTypes.APIApplicationCommandInteractionDataStringOption[] | undefined} */ // @ts-ignore
|
||||||
|
const options = data.options
|
||||||
|
const input = options?.[0].value || ""
|
||||||
|
const levels = ["invite", "link", "directory"]
|
||||||
|
const level = levels.findIndex(x => input === x)
|
||||||
|
if (level === -1) {
|
||||||
|
return discord.snow.interaction.createInteractionResponse(id, token, {
|
||||||
|
type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
|
||||||
|
data: {
|
||||||
|
content: "**Usage: `/privacy <level>`**. This will set who can join the space on Matrix-side. There are three levels:"
|
||||||
|
+ "\n`invite`: Can only join with a direct in-app invite from another user. No shareable invite links."
|
||||||
|
+ "\n`link`: Matrix links can be created and shared like Discord's invite links. In-app invites still work."
|
||||||
|
+ "\n`directory`: Publicly visible in the Matrix space directory, like Server Discovery. Invites and links still work."
|
||||||
|
+ `\n**Current privacy level: \`${levels[current]}\`**`,
|
||||||
|
flags: DiscordTypes.MessageFlags.Ephemeral
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
await discord.snow.interaction.createInteractionResponse(id, token, {
|
||||||
|
type: DiscordTypes.InteractionResponseType.DeferredChannelMessageWithSource,
|
||||||
|
data: {
|
||||||
|
flags: DiscordTypes.MessageFlags.Ephemeral
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
db.prepare("UPDATE guild_space SET privacy_level = ? WHERE guild_id = ?").run(level, guild_id)
|
||||||
|
await createSpace.syncSpaceFully(guild_id) // this is inefficient but OK to call infrequently on user request
|
||||||
|
|
||||||
|
await discord.snow.interaction.editOriginalInteractionResponse(botID, token, {
|
||||||
|
content: `Privacy level updated to \`${levels[level]}\`.`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.interact = interact
|
|
@ -9,6 +9,9 @@ const invite = sync.require("./interactions/invite.js")
|
||||||
const permissions = sync.require("./interactions/permissions.js")
|
const permissions = sync.require("./interactions/permissions.js")
|
||||||
const bridge = sync.require("./interactions/bridge.js")
|
const bridge = sync.require("./interactions/bridge.js")
|
||||||
const reactions = sync.require("./interactions/reactions.js")
|
const reactions = sync.require("./interactions/reactions.js")
|
||||||
|
const privacy = sync.require("./interactions/privacy.js")
|
||||||
|
|
||||||
|
// User must have EVERY permission in default_member_permissions to be able to use the command
|
||||||
|
|
||||||
discord.snow.interaction.bulkOverwriteApplicationCommands(id, [{
|
discord.snow.interaction.bulkOverwriteApplicationCommands(id, [{
|
||||||
name: "Matrix info",
|
name: "Matrix info",
|
||||||
|
@ -40,16 +43,42 @@ discord.snow.interaction.bulkOverwriteApplicationCommands(id, [{
|
||||||
name: "bridge",
|
name: "bridge",
|
||||||
contexts: [DiscordTypes.InteractionContextType.Guild],
|
contexts: [DiscordTypes.InteractionContextType.Guild],
|
||||||
type: DiscordTypes.ApplicationCommandType.ChatInput,
|
type: DiscordTypes.ApplicationCommandType.ChatInput,
|
||||||
description: "Start bridging this channel to a Matrix room.",
|
description: "Start bridging this channel to a Matrix room",
|
||||||
default_member_permissions: String(DiscordTypes.PermissionFlagsBits.ManageChannels),
|
default_member_permissions: String(DiscordTypes.PermissionFlagsBits.ManageChannels),
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
type: DiscordTypes.ApplicationCommandOptionType.String,
|
type: DiscordTypes.ApplicationCommandOptionType.String,
|
||||||
description: "Destination room to bridge to.",
|
description: "Destination room to bridge to",
|
||||||
name: "room",
|
name: "room",
|
||||||
autocomplete: true
|
autocomplete: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
}, {
|
||||||
|
name: "privacy",
|
||||||
|
contexts: [DiscordTypes.InteractionContextType.Guild],
|
||||||
|
type: DiscordTypes.ApplicationCommandType.ChatInput,
|
||||||
|
description: "Change whether Matrix users can join through direct invites, links, or the public directory.",
|
||||||
|
default_member_permissions: String(DiscordTypes.PermissionFlagsBits.ManageGuild),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
type: DiscordTypes.ApplicationCommandOptionType.String,
|
||||||
|
description: "Check or set the new privacy level",
|
||||||
|
name: "level",
|
||||||
|
choices: [{
|
||||||
|
name: "❓️ Check the current privacy level and get more information.",
|
||||||
|
value: "info"
|
||||||
|
}, {
|
||||||
|
name: "🤝 Only allow joining with a direct in-app invite from another user. No shareable invite links.",
|
||||||
|
value: "invite"
|
||||||
|
}, {
|
||||||
|
name: "🔗 Matrix links can be created and shared like Discord's invite links. In-app invites still work.",
|
||||||
|
value: "link",
|
||||||
|
}, {
|
||||||
|
name: "🌏️ Publicly visible in the Matrix directory, like Server Discovery. Invites and links still work.",
|
||||||
|
value: "directory"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
]
|
||||||
}])
|
}])
|
||||||
|
|
||||||
async function dispatchInteraction(interaction) {
|
async function dispatchInteraction(interaction) {
|
||||||
|
@ -69,6 +98,8 @@ async function dispatchInteraction(interaction) {
|
||||||
await bridge.interact(interaction)
|
await bridge.interact(interaction)
|
||||||
} else if (interactionId === "Reactions") {
|
} else if (interactionId === "Reactions") {
|
||||||
await reactions.interact(interaction)
|
await reactions.interact(interaction)
|
||||||
|
} else if (interactionId === "privacy") {
|
||||||
|
await privacy.interact(interaction)
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Unknown interaction ${interactionId}`)
|
throw new Error(`Unknown interaction ${interactionId}`)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue