add error handler and message deleter
This commit is contained in:
parent
e3737997ec
commit
6de13338a8
3 changed files with 100 additions and 8 deletions
29
d2m/actions/delete-message.js
Normal file
29
d2m/actions/delete-message.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
const passthrough = require("../../passthrough")
|
||||||
|
const { sync, db } = passthrough
|
||||||
|
/** @type {import("../converters/edit-to-changes")} */
|
||||||
|
const editToChanges = sync.require("../converters/edit-to-changes")
|
||||||
|
/** @type {import("../../matrix/api")} */
|
||||||
|
const api = sync.require("../../matrix/api")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import("discord-api-types/v10").GatewayMessageDeleteDispatchData} data
|
||||||
|
*/
|
||||||
|
async function deleteMessage(data) {
|
||||||
|
/** @type {string?} */
|
||||||
|
const roomID = db.prepare("SELECT channel_id FROM channel_room WHERE channel_id = ?").pluck().get(data.channel_id)
|
||||||
|
if (!roomID) return
|
||||||
|
|
||||||
|
/** @type {string[]} */
|
||||||
|
const eventsToRedact = db.prepare("SELECT event_id FROM event_message WHERE message_id = ?").pluck().all(data.id)
|
||||||
|
|
||||||
|
for (const eventID of eventsToRedact) {
|
||||||
|
// Unfortuately, we can't specify a sender to do the redaction as, unless we find out that info via the audit logs
|
||||||
|
await api.redactEvent(roomID, eventID)
|
||||||
|
db.prepare("DELETE from event_message WHERE event_id = ?").run(eventID)
|
||||||
|
// TODO: Consider whether this code could be reused between edited messages and deleted messages.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.deleteMessage = deleteMessage
|
|
@ -16,6 +16,7 @@ const utils = {
|
||||||
/** @type {typeof import("./event-dispatcher")} */
|
/** @type {typeof import("./event-dispatcher")} */
|
||||||
const eventDispatcher = sync.require("./event-dispatcher")
|
const eventDispatcher = sync.require("./event-dispatcher")
|
||||||
|
|
||||||
|
// Client internals, keep track of the state we need
|
||||||
if (message.t === "READY") {
|
if (message.t === "READY") {
|
||||||
if (client.ready) return
|
if (client.ready) return
|
||||||
client.ready = true
|
client.ready = true
|
||||||
|
@ -62,16 +63,25 @@ const utils = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event dispatcher for OOYE bridge operations
|
||||||
|
try {
|
||||||
|
if (message.t === "MESSAGE_CREATE") {
|
||||||
|
eventDispatcher.onMessageCreate(client, message.d)
|
||||||
|
|
||||||
} else if (message.t === "MESSAGE_CREATE") {
|
} else if (message.t === "MESSAGE_UPDATE") {
|
||||||
eventDispatcher.onMessageCreate(client, message.d)
|
eventDispatcher.onMessageUpdate(client, message.d)
|
||||||
|
|
||||||
} else if (message.t === "MESSAGE_UPDATE") {
|
} else if (message.t === "MESSAGE_DELETE") {
|
||||||
eventDispatcher.onMessageUpdate(client, message.d)
|
eventDispatcher.onMessageDelete(client, message.d)
|
||||||
|
|
||||||
} else if (message.t === "MESSAGE_REACTION_ADD") {
|
} else if (message.t === "MESSAGE_REACTION_ADD") {
|
||||||
eventDispatcher.onReactionAdd(client, message.d)
|
eventDispatcher.onReactionAdd(client, message.d)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Let OOYE try to handle errors too
|
||||||
|
eventDispatcher.onError(client, e, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,61 @@
|
||||||
const assert = require("assert").strict
|
const assert = require("assert").strict
|
||||||
|
const util = require("util")
|
||||||
const {sync, db} = require("../passthrough")
|
const {sync, db} = require("../passthrough")
|
||||||
|
|
||||||
/** @type {import("./actions/send-message")}) */
|
/** @type {import("./actions/send-message")}) */
|
||||||
const sendMessage = sync.require("./actions/send-message")
|
const sendMessage = sync.require("./actions/send-message")
|
||||||
/** @type {import("./actions/edit-message")}) */
|
/** @type {import("./actions/edit-message")}) */
|
||||||
const editMessage = sync.require("./actions/edit-message")
|
const editMessage = sync.require("./actions/edit-message")
|
||||||
|
/** @type {import("./actions/delete-message")}) */
|
||||||
|
const deleteMessage = sync.require("./actions/delete-message")
|
||||||
/** @type {import("./actions/add-reaction")}) */
|
/** @type {import("./actions/add-reaction")}) */
|
||||||
const addReaction = sync.require("./actions/add-reaction")
|
const addReaction = sync.require("./actions/add-reaction")
|
||||||
|
/** @type {import("../matrix/api")}) */
|
||||||
|
const api = sync.require("../matrix/api")
|
||||||
|
|
||||||
|
let lastReportedEvent = 0
|
||||||
|
|
||||||
// Grab Discord events we care about for the bridge, check them, and pass them on
|
// Grab Discord events we care about for the bridge, check them, and pass them on
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
/**
|
||||||
|
* @param {import("./discord-client")} client
|
||||||
|
* @param {Error} e
|
||||||
|
* @param {import("cloudstorm").IGatewayMessage} gatewayMessage
|
||||||
|
*/
|
||||||
|
onError(client, e, gatewayMessage) {
|
||||||
|
console.error("hit event-dispatcher's error handler with this exception:")
|
||||||
|
console.error(e) // TODO: also log errors into a file or into the database, maybe use a library for this? or just wing it? definitely need to be able to store the formatted event body to load back in later
|
||||||
|
console.error(`while handling this ${gatewayMessage.t} gateway event:`)
|
||||||
|
console.dir(gatewayMessage.d)
|
||||||
|
|
||||||
|
if (Date.now() - lastReportedEvent > 5000) {
|
||||||
|
lastReportedEvent = Date.now()
|
||||||
|
const channelID = gatewayMessage.d.channel_id
|
||||||
|
if (channelID) {
|
||||||
|
const roomID = db.prepare("SELECT room_id FROM channel_room WHERE channel_id = ?").pluck().get(channelID)
|
||||||
|
let stackLines = e.stack.split("\n")
|
||||||
|
let cloudstormLine = stackLines.findIndex(l => l.includes("/node_modules/cloudstorm/"))
|
||||||
|
if (cloudstormLine !== -1) {
|
||||||
|
stackLines = stackLines.slice(0, cloudstormLine - 2)
|
||||||
|
}
|
||||||
|
api.sendEvent(roomID, "m.room.message", {
|
||||||
|
msgtype: "m.text",
|
||||||
|
body: "\u26a0 Bridged event from Discord not delivered. See formatted content for full details.",
|
||||||
|
format: "org.matrix.custom.html",
|
||||||
|
formatted_body: "\u26a0 <strong>Bridged event from Discord not delivered</strong>"
|
||||||
|
+ `<br>Gateway event: ${gatewayMessage.t}`
|
||||||
|
+ `<pre>${stackLines.join("\n")}</pre>`
|
||||||
|
+ `<details><summary>Original payload</summary>`
|
||||||
|
+ `<pre>${util.inspect(gatewayMessage.d, false, 4, false)}</pre></details>`,
|
||||||
|
"m.mentions": {
|
||||||
|
user_ids: ["@cadence:cadence.moe"]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("./discord-client")} client
|
* @param {import("./discord-client")} client
|
||||||
* @param {import("discord-api-types/v10").GatewayMessageCreateDispatchData} message
|
* @param {import("discord-api-types/v10").GatewayMessageCreateDispatchData} message
|
||||||
|
@ -38,7 +82,7 @@ module.exports = {
|
||||||
*/
|
*/
|
||||||
onMessageUpdate(client, data) {
|
onMessageUpdate(client, data) {
|
||||||
if (data.webhook_id) {
|
if (data.webhook_id) {
|
||||||
const row = db.prepare("SELECT webhook_id FROM webhook WHERE webhook_id = ?").pluck().get(message.webhook_id)
|
const row = db.prepare("SELECT webhook_id FROM webhook WHERE webhook_id = ?").pluck().get(data.webhook_id)
|
||||||
if (row) {
|
if (row) {
|
||||||
// The update was sent by the bridge's own webhook on discord. We don't want to reflect this back, so just drop it.
|
// The update was sent by the bridge's own webhook on discord. We don't want to reflect this back, so just drop it.
|
||||||
return
|
return
|
||||||
|
@ -67,5 +111,14 @@ module.exports = {
|
||||||
if (data.emoji.id !== null) return // TODO: image emoji reactions
|
if (data.emoji.id !== null) return // TODO: image emoji reactions
|
||||||
console.log(data)
|
console.log(data)
|
||||||
addReaction.addReaction(data)
|
addReaction.addReaction(data)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import("./discord-client")} client
|
||||||
|
* @param {import("discord-api-types/v10").GatewayMessageDeleteDispatchData} data
|
||||||
|
*/
|
||||||
|
onMessageDelete(client, data) {
|
||||||
|
console.log(data)
|
||||||
|
deleteMessage.deleteMessage(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue