Compare commits
2 commits
f3b0d01400
...
6bb31deeaf
Author | SHA1 | Date | |
---|---|---|---|
6bb31deeaf | |||
1e4952f1b8 |
3 changed files with 60 additions and 31 deletions
|
@ -103,13 +103,19 @@ module.exports = {
|
||||||
async checkMissedMessages(client, guild) {
|
async checkMissedMessages(client, guild) {
|
||||||
if (guild.unavailable) return
|
if (guild.unavailable) return
|
||||||
const bridgedChannels = select("channel_room", "channel_id").pluck().all()
|
const bridgedChannels = select("channel_room", "channel_id").pluck().all()
|
||||||
const prepared = select("event_message", "event_id", {}, "WHERE message_id = ?").pluck()
|
const preparedExists = db.prepare("SELECT channel_id FROM message_channel WHERE channel_id = ? LIMIT 1")
|
||||||
|
const preparedGet = select("event_message", "event_id", {}, "WHERE message_id = ?").pluck()
|
||||||
for (const channel of guild.channels.concat(guild.threads)) {
|
for (const channel of guild.channels.concat(guild.threads)) {
|
||||||
if (!bridgedChannels.includes(channel.id)) continue
|
if (!bridgedChannels.includes(channel.id)) continue
|
||||||
if (!("last_message_id" in channel) || !channel.last_message_id) continue
|
if (!("last_message_id" in channel) || !channel.last_message_id) continue
|
||||||
const latestWasBridged = prepared.get(channel.last_message_id)
|
|
||||||
|
// Skip if channel is already up-to-date
|
||||||
|
const latestWasBridged = preparedGet.get(channel.last_message_id)
|
||||||
if (latestWasBridged) continue
|
if (latestWasBridged) continue
|
||||||
|
|
||||||
|
// Skip if channel was just added to the bridge (there's no place to resume from if it's brand new)
|
||||||
|
if (!preparedExists.get(channel.id)) continue
|
||||||
|
|
||||||
// Permissions check
|
// Permissions check
|
||||||
const member = guild.members.find(m => m.user?.id === client.user.id)
|
const member = guild.members.find(m => m.user?.id === client.user.id)
|
||||||
if (!member) return
|
if (!member) return
|
||||||
|
@ -131,7 +137,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let latestBridgedMessageIndex = messages.findIndex(m => {
|
let latestBridgedMessageIndex = messages.findIndex(m => {
|
||||||
return prepared.get(m.id)
|
return preparedGet.get(m.id)
|
||||||
})
|
})
|
||||||
// console.log(`[check missed messages] got ${messages.length} messages; last message that IS bridged is at position ${latestBridgedMessageIndex} in the channel`)
|
// console.log(`[check missed messages] got ${messages.length} messages; last message that IS bridged is at position ${latestBridgedMessageIndex} in the channel`)
|
||||||
if (latestBridgedMessageIndex === -1) latestBridgedMessageIndex = 1 // rather than crawling the ENTIRE channel history, let's just bridge the most recent 1 message to make it up to date.
|
if (latestBridgedMessageIndex === -1) latestBridgedMessageIndex = 1 // rather than crawling the ENTIRE channel history, let's just bridge the most recent 1 message to make it up to date.
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
const DiscordTypes = require("discord-api-types/v10")
|
const DiscordTypes = require("discord-api-types/v10")
|
||||||
const {discord, sync, select, from} = require("../../passthrough")
|
const {discord, sync, select, from} = require("../../passthrough")
|
||||||
|
const {id: botID} = require("../../../addbot")
|
||||||
|
const {InteractionMethods} = require("snowtransfer")
|
||||||
|
|
||||||
/** @type {import("../../matrix/api")} */
|
/** @type {import("../../matrix/api")} */
|
||||||
const api = sync.require("../../matrix/api")
|
const api = sync.require("../../matrix/api")
|
||||||
|
@ -11,20 +13,27 @@ const utils = sync.require("../../m2d/converters/utils")
|
||||||
/**
|
/**
|
||||||
* @param {DiscordTypes.APIMessageApplicationCommandGuildInteraction} interaction
|
* @param {DiscordTypes.APIMessageApplicationCommandGuildInteraction} interaction
|
||||||
* @param {{api: typeof api}} di
|
* @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")
|
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()
|
.select("event_id", "room_id").where({message_id: data.target_id}).get()
|
||||||
if (!row) {
|
if (!row) {
|
||||||
return {
|
return yield {createInteractionResponse: {
|
||||||
type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
|
type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
|
||||||
data: {
|
data: {
|
||||||
content: "This message hasn't been bridged to Matrix.",
|
content: "This message hasn't been bridged to Matrix.",
|
||||||
flags: DiscordTypes.MessageFlags.Ephemeral
|
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")
|
const reactions = await api.getFullRelations(row.room_id, row.event_id, "m.annotation")
|
||||||
|
|
||||||
|
@ -40,29 +49,27 @@ async function _interact({data}, {api}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inverted.size === 0) {
|
if (inverted.size === 0) {
|
||||||
return {
|
return yield {editOriginalInteractionResponse: {
|
||||||
type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
|
|
||||||
data: {
|
|
||||||
content: "Nobody from Matrix reacted to this message.",
|
content: "Nobody from Matrix reacted to this message.",
|
||||||
flags: DiscordTypes.MessageFlags.Ephemeral
|
}}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return yield {editOriginalInteractionResponse: {
|
||||||
type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
|
|
||||||
data: {
|
|
||||||
content: [...inverted.entries()].map(([key, value]) => `${key} ⮞ ${value.join(" ⬩ ")}`).join("\n"),
|
content: [...inverted.entries()].map(([key, value]) => `${key} ⮞ ${value.join(" ⬩ ")}`).join("\n"),
|
||||||
flags: DiscordTypes.MessageFlags.Ephemeral
|
}}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* c8 ignore start */
|
/* c8 ignore start */
|
||||||
|
|
||||||
/** @param {DiscordTypes.APIMessageApplicationCommandGuildInteraction} interaction */
|
/** @param {DiscordTypes.APIMessageApplicationCommandGuildInteraction} interaction */
|
||||||
async function interact(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
|
module.exports.interact = interact
|
||||||
|
|
|
@ -1,17 +1,31 @@
|
||||||
const {test} = require("supertape")
|
const {test} = require("supertape")
|
||||||
const {_interact} = require("./reactions")
|
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 => {
|
test("reactions: checks if message is bridged", async t => {
|
||||||
const msg = await _interact({
|
const msgs = await fromAsync(_interact({
|
||||||
data: {
|
data: {
|
||||||
target_id: "0"
|
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 => {
|
test("reactions: different response if nobody reacted", async t => {
|
||||||
const msg = await _interact({
|
const msgs = await fromAsync(_interact({
|
||||||
data: {
|
data: {
|
||||||
target_id: "1126786462646550579"
|
target_id: "1126786462646550579"
|
||||||
}
|
}
|
||||||
|
@ -23,13 +37,14 @@ test("reactions: different response if nobody reacted", async t => {
|
||||||
return []
|
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 => {
|
test("reactions: shows reactions if there are some, ignoring discord users", async t => {
|
||||||
let called = 1
|
let called = 1
|
||||||
const msg = await _interact({
|
const msgs = await fromAsync(_interact({
|
||||||
data: {
|
data: {
|
||||||
target_id: "1126786462646550579"
|
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(
|
t.equal(
|
||||||
msg.data.content,
|
msgs[1].editOriginalInteractionResponse.content,
|
||||||
"🐈 ⮞ cadence [they] ⬩ @rnl:cadence.moe"
|
"🐈 ⮞ cadence [they] ⬩ @rnl:cadence.moe"
|
||||||
+ "\n🐈⬛ ⮞ cadence [they]"
|
+ "\n🐈⬛ ⮞ cadence [they]"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue