Make invite command more testable

This commit is contained in:
Cadence Ember 2024-08-28 00:18:06 +12:00
parent 78a17b2de9
commit 4b7593d630

View file

@ -7,31 +7,34 @@ const {discord, sync, db, select, from} = require("../../passthrough")
/** @type {import("../../matrix/api")} */ /** @type {import("../../matrix/api")} */
const api = sync.require("../../matrix/api") const api = sync.require("../../matrix/api")
/** @param {DiscordTypes.APIChatInputApplicationCommandGuildInteraction} interaction */ /**
async function interact({id, token, data, channel, member, guild_id}) { * @param {DiscordTypes.APIChatInputApplicationCommandGuildInteraction} interaction
* @returns {Promise<DiscordTypes.APIInteractionResponse>}
*/
async function _interact({data, channel, guild_id}) {
// Check guild is bridged // Check guild is bridged
const spaceID = select("guild_space", "space_id", {guild_id}).pluck().get() const spaceID = select("guild_space", "space_id", {guild_id}).pluck().get()
const roomID = select("channel_room", "room_id", {channel_id: channel.id}).pluck().get() const roomID = select("channel_room", "room_id", {channel_id: channel.id}).pluck().get()
if (!spaceID || !roomID) return discord.snow.interaction.createInteractionResponse(id, token, { if (!spaceID || !roomID) return {
type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource, type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
data: { data: {
content: "This server isn't bridged to Matrix, so you can't invite Matrix users.", content: "This server isn't bridged to Matrix, so you can't invite Matrix users.",
flags: DiscordTypes.MessageFlags.Ephemeral flags: DiscordTypes.MessageFlags.Ephemeral
} }
}) }
// Get named MXID // Get named MXID
/** @type {DiscordTypes.APIApplicationCommandInteractionDataStringOption[] | undefined} */ // @ts-ignore /** @type {DiscordTypes.APIApplicationCommandInteractionDataStringOption[] | undefined} */ // @ts-ignore
const options = data.options const options = data.options
const input = options?.[0].value || "" const input = options?.[0].value || ""
const mxid = input.match(/@([^:]+):([a-z0-9:-]+\.[a-z0-9.:-]+)/)?.[0] const mxid = input.match(/@([^:]+):([a-z0-9:-]+\.[a-z0-9.:-]+)/)?.[0]
if (!mxid) return discord.snow.interaction.createInteractionResponse(id, token, { if (!mxid) return {
type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource, type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
data: { data: {
content: "You have to say the Matrix ID of the person you want to invite. Matrix IDs look like this: `@username:example.org`", content: "You have to say the Matrix ID of the person you want to invite. Matrix IDs look like this: `@username:example.org`",
flags: DiscordTypes.MessageFlags.Ephemeral flags: DiscordTypes.MessageFlags.Ephemeral
} }
}) }
// Check for existing invite to the space // Check for existing invite to the space
let spaceMember let spaceMember
@ -39,24 +42,24 @@ async function interact({id, token, data, channel, member, guild_id}) {
spaceMember = await api.getStateEvent(spaceID, "m.room.member", mxid) spaceMember = await api.getStateEvent(spaceID, "m.room.member", mxid)
} catch (e) {} } catch (e) {}
if (spaceMember && spaceMember.membership === "invite") { if (spaceMember && spaceMember.membership === "invite") {
return discord.snow.interaction.createInteractionResponse(id, token, { return {
type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource, type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
data: { data: {
content: `\`${mxid}\` already has an invite, which they haven't accepted yet.`, content: `\`${mxid}\` already has an invite, which they haven't accepted yet.`,
flags: DiscordTypes.MessageFlags.Ephemeral flags: DiscordTypes.MessageFlags.Ephemeral
} }
}) }
} }
// Invite Matrix user if not in space // Invite Matrix user if not in space
if (!spaceMember || spaceMember.membership !== "join") { if (!spaceMember || spaceMember.membership !== "join") {
await api.inviteToRoom(spaceID, mxid) await api.inviteToRoom(spaceID, mxid)
return discord.snow.interaction.createInteractionResponse(id, token, { return {
type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource, type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
data: { data: {
content: `You invited \`${mxid}\` to the server.` content: `You invited \`${mxid}\` to the server.`
} }
}) }
} }
// The Matrix user *is* in the space, maybe we want to invite them to this channel? // The Matrix user *is* in the space, maybe we want to invite them to this channel?
@ -65,7 +68,7 @@ async function interact({id, token, data, channel, member, guild_id}) {
roomMember = await api.getStateEvent(roomID, "m.room.member", mxid) roomMember = await api.getStateEvent(roomID, "m.room.member", mxid)
} catch (e) {} } catch (e) {}
if (!roomMember || (roomMember.membership !== "join" && roomMember.membership !== "invite")) { if (!roomMember || (roomMember.membership !== "join" && roomMember.membership !== "invite")) {
return discord.snow.interaction.createInteractionResponse(id, token, { return {
type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource, type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
data: { data: {
content: `\`${mxid}\` is already in this server. Would you like to additionally invite them to this specific channel?`, content: `\`${mxid}\` is already in this server. Would you like to additionally invite them to this specific channel?`,
@ -80,34 +83,49 @@ async function interact({id, token, data, channel, member, guild_id}) {
}] }]
}] }]
} }
}) }
} }
// The Matrix user *is* in the space and in the channel. // The Matrix user *is* in the space and in the channel.
return discord.snow.interaction.createInteractionResponse(id, token, { return {
type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource, type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
data: { data: {
content: `\`${mxid}\` is already in this server and this channel.`, content: `\`${mxid}\` is already in this server and this channel.`,
flags: DiscordTypes.MessageFlags.Ephemeral flags: DiscordTypes.MessageFlags.Ephemeral
} }
}) }
} }
/** @param {DiscordTypes.APIMessageComponentGuildInteraction} interaction */ /**
async function interactButton({id, token, data, channel, member, guild_id, message}) { * @param {DiscordTypes.APIMessageComponentGuildInteraction} interaction
* @returns {Promise<DiscordTypes.APIInteractionResponse>}
*/
async function _interactButton({channel, message}) {
const mxid = message.content.match(/`(@(?:[^:]+):(?:[a-z0-9:-]+\.[a-z0-9.:-]+))`/)?.[1] const mxid = message.content.match(/`(@(?:[^:]+):(?:[a-z0-9:-]+\.[a-z0-9.:-]+))`/)?.[1]
assert(mxid) assert(mxid)
const roomID = select("channel_room", "room_id", {channel_id: channel.id}).pluck().get() const roomID = select("channel_room", "room_id", {channel_id: channel.id}).pluck().get()
await api.inviteToRoom(roomID, mxid) await api.inviteToRoom(roomID, mxid)
return discord.snow.interaction.createInteractionResponse(id, token, { return {
type: DiscordTypes.InteractionResponseType.UpdateMessage, type: DiscordTypes.InteractionResponseType.UpdateMessage,
data: { data: {
content: `You invited \`${mxid}\` to the channel.`, content: `You invited \`${mxid}\` to the channel.`,
flags: DiscordTypes.MessageFlags.Ephemeral, flags: DiscordTypes.MessageFlags.Ephemeral,
components: [] components: []
} }
}) }
}
/** @param {DiscordTypes.APIChatInputApplicationCommandGuildInteraction} interaction */
async function interact(interaction) {
await discord.snow.interaction.createInteractionResponse(interaction.id, interaction.token, await _interact(interaction))
}
/** @param {DiscordTypes.APIMessageComponentGuildInteraction} interaction */
async function interactButton(interaction) {
await discord.snow.interaction.createInteractionResponse(interaction.id, interaction.token, await _interactButton(interaction))
} }
module.exports.interact = interact module.exports.interact = interact
module.exports.interactButton = interactButton module.exports.interactButton = interactButton
module.exports._interact = _interact
module.exports._interactButton = _interactButton