Support /plu/ral webhook proxying
This commit is contained in:
@@ -1,7 +1,17 @@
|
||||
// @ts-check
|
||||
|
||||
const DiscordTypes = require("discord-api-types/v10")
|
||||
|
||||
const passthrough = require("../../passthrough")
|
||||
const {discord, select, db} = passthrough
|
||||
const {discord, from, select, db, sync} = passthrough
|
||||
|
||||
const {reg} = require("../../matrix/read-registration")
|
||||
/** @type {import("./register-pk-user")} */
|
||||
const registerPkUser = sync.require("./register-pk-user")
|
||||
/** @type {import("./register-plu-ral-user")} */
|
||||
const registerPluRalUser = sync.require("./register-plu-ral-user")
|
||||
/** @type {import("./register-webhook-user")} */
|
||||
const registerWebhookUser = sync.require("./register-webhook-user")
|
||||
|
||||
const DEBUG_SPEEDBUMP = false
|
||||
|
||||
@@ -16,14 +26,10 @@ const SPEEDBUMP_UPDATE_FREQUENCY = 2 * 60 * 60 // 2 hours
|
||||
|
||||
/** @type {Set<any>} */
|
||||
const KNOWN_BOTS = new Set([
|
||||
"466378653216014359" // PluralKit
|
||||
"466378653216014359", // PluralKit
|
||||
"1291501048493768784", // /plu/ral
|
||||
])
|
||||
|
||||
const CONTEXT_ENUM = {
|
||||
create: "create",
|
||||
update: "update"
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch new speedbump data for the channel and put it in the database as cache
|
||||
* @param {string} channelID
|
||||
@@ -33,10 +39,14 @@ async function updateCache(channelID, lastChecked) {
|
||||
const now = Math.floor(Date.now() / 1000)
|
||||
if (lastChecked && now - lastChecked < SPEEDBUMP_UPDATE_FREQUENCY) return
|
||||
const webhooks = await discord.snow.webhook.getChannelWebhooks(channelID)
|
||||
const found = webhooks.find(b => KNOWN_BOTS.has(b.application_id))
|
||||
const foundApplication = found?.application_id
|
||||
const foundWebhook = found?.id
|
||||
db.prepare("UPDATE channel_room SET speedbump_id = ?, speedbump_webhook_id = ?, speedbump_checked = ? WHERE channel_id = ?").run(foundApplication, foundWebhook, now, channelID)
|
||||
const found = webhooks.filter(b => KNOWN_BOTS.has(b.application_id))
|
||||
db.transaction(() => {
|
||||
db.prepare("DELETE FROM channel_speedbump WHERE channel_id = ?").run(channelID)
|
||||
for (const webhook of found) {
|
||||
db.prepare("INSERT INTO channel_speedbump (channel_id, speedbump_webhook_id, speedbump_user_id) VALUES (?, ?, ?)").run(channelID, webhook.id, webhook.application_id)
|
||||
}
|
||||
db.prepare("UPDATE channel_room SET speedbump_checked = ? WHERE channel_id = ?").run(now, channelID)
|
||||
})()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,11 +60,11 @@ const bumping = new Map()
|
||||
|
||||
/**
|
||||
* Slow down a message. After it passes the speedbump, return whether it's okay or if it's been deleted.
|
||||
* @param {keyof typeof CONTEXT_ENUM} context
|
||||
* @param {boolean} isCreate
|
||||
* @param {string} messageID
|
||||
* @returns whether it was deleted
|
||||
*/
|
||||
async function doSpeedbump(context, messageID) {
|
||||
async function doSpeedbump(isCreate, messageID) {
|
||||
const entry = bumping.get(messageID) ?? (() => {
|
||||
const entry = {number: 0, hasCreate: false}
|
||||
bumping.set(messageID, entry)
|
||||
@@ -62,7 +72,7 @@ async function doSpeedbump(context, messageID) {
|
||||
})()
|
||||
|
||||
entry.number++
|
||||
if (context === "create") entry.hasCreate = true
|
||||
entry.hasCreate ||= isCreate
|
||||
|
||||
debugSpeedbump(`[speedbump] WAIT ${messageID}++ =`, entry)
|
||||
|
||||
@@ -83,24 +93,27 @@ async function doSpeedbump(context, messageID) {
|
||||
}
|
||||
}
|
||||
|
||||
function getSpeedbumpRows(channelID) {
|
||||
return from("channel_room").join("channel_speedbump", "channel_id").select("thread_parent", "speedbump_user_id", "speedbump_webhook_id").where({channel_id: channelID}).all()
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether to slow down a message, and do it. After it passes the speedbump, return whether it's okay or if it's been deleted.
|
||||
* @param {keyof typeof CONTEXT_ENUM} context
|
||||
* @param {boolean} isCreate
|
||||
* @param {{id: string, channel_id: string, author: {id: string}, backfill?: boolean}} message uses the ID to identify, and the userID to only slow down the message when the user has used PK before
|
||||
* @returns whether it was deleted, and data about the channel's (not thread's) speedbump
|
||||
* @returns whether to skip this message, and whether the message should be created as a creation
|
||||
*/
|
||||
async function maybeDoSpeedbump(context, message) {
|
||||
let row = select("channel_room", ["room_id", "thread_parent", "speedbump_id", "speedbump_webhook_id"], {channel_id: message.channel_id}).get()
|
||||
if (row?.thread_parent) row = select("channel_room", ["room_id", "thread_parent", "speedbump_id", "speedbump_webhook_id"], {channel_id: row.thread_parent}).get() // webhooks belong to the channel, not the thread
|
||||
if (!row?.speedbump_webhook_id || !row?.speedbump_id) return {skip: false, proxyWebhook: null} // channel not affected, no speedbump
|
||||
async function maybeDoSpeedbump(isCreate, message) {
|
||||
let rows = getSpeedbumpRows(message.channel_id)
|
||||
if (rows[0]?.thread_parent) rows = getSpeedbumpRows(rows[0].thread_parent) // webhooks belong to the channel, not the thread
|
||||
if (!rows.length) return {skip: false} // channel not affected, no speedbump
|
||||
|
||||
let proxyWebhook = {userID: row.speedbump_id, webhookID: row.speedbump_webhook_id}
|
||||
if (message.backfill) return {skip: false, proxyWebhook} // don't slow messages during backfill
|
||||
if (proxyWebhook.webhookID === message.author.id) return {skip: false, proxyWebhook} // shortcut
|
||||
if (message.backfill) return {skip: false} // don't slow messages during backfill
|
||||
if (rows.some(r => r.speedbump_webhook_id === message.author.id)) return {skip: false} // shortcut
|
||||
const userHasProxy = select("sim_proxy", "user_id", {proxy_owner_id: message.author.id}).pluck().get()
|
||||
if (!userHasProxy) return {skip: false, proxyWebhook} // user has not used PK before, no speedbump
|
||||
const {skip, hasCreate} = await doSpeedbump(context, message.id)
|
||||
return {skip, hasCreate, proxyWebhook} // maybe affected, and there is a speedbump
|
||||
if (!userHasProxy) return {skip: false} // user has not used PK before, no speedbump
|
||||
const {skip, hasCreate} = await doSpeedbump(isCreate, message.id)
|
||||
return {skip, hasCreate} // maybe affected, and there is a speedbump
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,7 +123,25 @@ function onMessageDelete(messageID) {
|
||||
bumping.delete(messageID)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DiscordTypes.APIMessage} message
|
||||
* @param {string} guildID
|
||||
* @param {string} roomID
|
||||
*/
|
||||
async function getWebhookSenderId(message, guildID, roomID) {
|
||||
const speedbumpUserID = select("channel_speedbump", "speedbump_user_id", {channel_id: message.channel_id, speedbump_webhook_id: message.webhook_id}).pluck().get()
|
||||
const useWebhookProfile = select("guild_space", "webhook_profile", {guild_id: guildID}).pluck().get() ?? 0
|
||||
if (speedbumpUserID === "466378653216014359") { // PluralKit public instance
|
||||
return await registerPkUser.syncUser(message.id, message.author, roomID, true)
|
||||
} else if (speedbumpUserID === "1291501048493768784" && reg.ooye.plu_ral_api_key) { // /plu/ral public instance
|
||||
return await registerPluRalUser.syncUser(message.channel_id, message.id, message.author, roomID, true)
|
||||
} else if (useWebhookProfile) {
|
||||
return await registerWebhookUser.syncUser(message.author, roomID, true)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
module.exports.updateCache = updateCache
|
||||
module.exports.doSpeedbump = doSpeedbump
|
||||
module.exports.maybeDoSpeedbump = maybeDoSpeedbump
|
||||
module.exports.onMessageDelete = onMessageDelete
|
||||
module.exports.getWebhookSenderId = getWebhookSenderId
|
||||
|
||||
Reference in New Issue
Block a user