forked from cadence/out-of-your-element
		
	Add anti-timeout system to reactions interaction
This commit is contained in:
		
							parent
							
								
									f3b0d01400
								
							
						
					
					
						commit
						1e4952f1b8
					
				
					 2 changed files with 51 additions and 28 deletions
				
			
		| 
						 | 
				
			
			@ -2,6 +2,8 @@
 | 
			
		|||
 | 
			
		||||
const DiscordTypes = require("discord-api-types/v10")
 | 
			
		||||
const {discord, sync, select, from} = require("../../passthrough")
 | 
			
		||||
const {id: botID} = require("../../../addbot")
 | 
			
		||||
const {InteractionMethods} = require("snowtransfer")
 | 
			
		||||
 | 
			
		||||
/** @type {import("../../matrix/api")} */
 | 
			
		||||
const api = sync.require("../../matrix/api")
 | 
			
		||||
| 
						 | 
				
			
			@ -11,21 +13,28 @@ const utils = sync.require("../../m2d/converters/utils")
 | 
			
		|||
/**
 | 
			
		||||
 * @param {DiscordTypes.APIMessageApplicationCommandGuildInteraction} interaction
 | 
			
		||||
 * @param {{api: typeof api}} di
 | 
			
		||||
 * @returns {Promise<DiscordTypes.APIInteractionResponse>}
 | 
			
		||||
 * @returns {AsyncGenerator<{[k in keyof InteractionMethods]?: Parameters<InteractionMethods[k]>[2]}>}
 | 
			
		||||
 */
 | 
			
		||||
async function _interact({data}, {api}) {
 | 
			
		||||
async function* _interact({data}, {api}) {
 | 
			
		||||
	const row = from("event_message").join("message_channel", "message_id").join("channel_room", "channel_id")
 | 
			
		||||
		.select("event_id", "room_id").where({message_id: data.target_id}).get()
 | 
			
		||||
	if (!row) {
 | 
			
		||||
		return {
 | 
			
		||||
		return yield {createInteractionResponse: {
 | 
			
		||||
			type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
 | 
			
		||||
			data: {
 | 
			
		||||
				content: "This message hasn't been bridged to Matrix.",
 | 
			
		||||
				flags: DiscordTypes.MessageFlags.Ephemeral
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		}}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	yield {createInteractionResponse: {
 | 
			
		||||
		type: DiscordTypes.InteractionResponseType.DeferredChannelMessageWithSource,
 | 
			
		||||
		data: {
 | 
			
		||||
			flags: DiscordTypes.MessageFlags.Ephemeral
 | 
			
		||||
		}
 | 
			
		||||
	}}
 | 
			
		||||
 | 
			
		||||
	const reactions = await api.getFullRelations(row.room_id, row.event_id, "m.annotation")
 | 
			
		||||
 | 
			
		||||
	/** @type {Map<string, string[]>} */
 | 
			
		||||
| 
						 | 
				
			
			@ -40,29 +49,27 @@ async function _interact({data}, {api}) {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if (inverted.size === 0) {
 | 
			
		||||
		return {
 | 
			
		||||
			type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
 | 
			
		||||
			data: {
 | 
			
		||||
				content: "Nobody from Matrix reacted to this message.",
 | 
			
		||||
				flags: DiscordTypes.MessageFlags.Ephemeral
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return yield {editOriginalInteractionResponse: {
 | 
			
		||||
			content: "Nobody from Matrix reacted to this message.",
 | 
			
		||||
		}}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return {
 | 
			
		||||
		type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
 | 
			
		||||
		data: {
 | 
			
		||||
			content: [...inverted.entries()].map(([key, value]) => `${key} ⮞ ${value.join(" ⬩ ")}`).join("\n"),
 | 
			
		||||
			flags: DiscordTypes.MessageFlags.Ephemeral
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return yield {editOriginalInteractionResponse: {
 | 
			
		||||
		content: [...inverted.entries()].map(([key, value]) => `${key} ⮞ ${value.join(" ⬩ ")}`).join("\n"),
 | 
			
		||||
	}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* c8 ignore start */
 | 
			
		||||
 | 
			
		||||
/** @param {DiscordTypes.APIMessageApplicationCommandGuildInteraction} interaction */
 | 
			
		||||
async function interact(interaction) {
 | 
			
		||||
	await discord.snow.interaction.createInteractionResponse(interaction.id, interaction.token, await _interact(interaction, {api}))
 | 
			
		||||
	for await (const response of _interact(interaction, {api})) {
 | 
			
		||||
		if (response.createInteractionResponse) {
 | 
			
		||||
			await discord.snow.interaction.createInteractionResponse(interaction.id, interaction.token, response.createInteractionResponse)
 | 
			
		||||
		} else if (response.editOriginalInteractionResponse) {
 | 
			
		||||
			await discord.snow.interaction.editOriginalInteractionResponse(botID, interaction.token, response.editOriginalInteractionResponse)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.interact = interact
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,17 +1,31 @@
 | 
			
		|||
const {test} = require("supertape")
 | 
			
		||||
const {_interact} = require("./reactions")
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @template T
 | 
			
		||||
 * @param {AsyncIterable<T>} ai
 | 
			
		||||
 * @returns {Promise<T[]>}
 | 
			
		||||
 */
 | 
			
		||||
async function fromAsync(ai) {
 | 
			
		||||
	const result = []
 | 
			
		||||
	for await (const value of ai) {
 | 
			
		||||
		result.push(value)
 | 
			
		||||
	}
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test("reactions: checks if message is bridged", async t => {
 | 
			
		||||
	const msg = await _interact({
 | 
			
		||||
	const msgs = await fromAsync(_interact({
 | 
			
		||||
		data: {
 | 
			
		||||
			target_id: "0"
 | 
			
		||||
		}
 | 
			
		||||
	}, {})
 | 
			
		||||
	t.equal(msg.data.content, "This message hasn't been bridged to Matrix.")
 | 
			
		||||
	}, {}))
 | 
			
		||||
	t.equal(msgs.length, 1)
 | 
			
		||||
	t.equal(msgs[0].createInteractionResponse.data.content, "This message hasn't been bridged to Matrix.")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test("reactions: different response if nobody reacted", async t => {
 | 
			
		||||
	const msg = await _interact({
 | 
			
		||||
	const msgs = await fromAsync(_interact({
 | 
			
		||||
		data: {
 | 
			
		||||
			target_id: "1126786462646550579"
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -23,13 +37,14 @@ test("reactions: different response if nobody reacted", async t => {
 | 
			
		|||
				return []
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	t.equal(msg.data.content, "Nobody from Matrix reacted to this message.")
 | 
			
		||||
	}))
 | 
			
		||||
	t.equal(msgs.length, 2)
 | 
			
		||||
	t.equal(msgs[1].editOriginalInteractionResponse.content, "Nobody from Matrix reacted to this message.")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test("reactions: shows reactions if there are some, ignoring discord users", async t => {
 | 
			
		||||
	let called = 1
 | 
			
		||||
	const msg = await _interact({
 | 
			
		||||
	const msgs = await fromAsync(_interact({
 | 
			
		||||
		data: {
 | 
			
		||||
			target_id: "1126786462646550579"
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -73,9 +88,10 @@ test("reactions: shows reactions if there are some, ignoring discord users", asy
 | 
			
		|||
				}]
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	}))
 | 
			
		||||
	t.equal(msgs.length, 2)
 | 
			
		||||
	t.equal(
 | 
			
		||||
		msg.data.content,
 | 
			
		||||
		msgs[1].editOriginalInteractionResponse.content,
 | 
			
		||||
		"🐈 ⮞ cadence [they] ⬩ @rnl:cadence.moe"
 | 
			
		||||
		+ "\n🐈⬛ ⮞ cadence [they]"
 | 
			
		||||
	)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue