2023-06-30 03:15:34 +00:00
// @ts-check
const assert = require ( "assert" ) . strict
2023-07-03 05:20:24 +00:00
const DiscordTypes = require ( "discord-api-types/v10" )
2023-06-30 03:15:34 +00:00
const passthrough = require ( "../../passthrough" )
const { discord , db } = passthrough
/ * *
* Look in the database to find webhook credentials for a channel .
* ( Note that the credentials may be invalid and need to be re - created if the webhook was interfered with from outside . )
* @ param { string } channelID
* @ param { boolean } forceCreate create a new webhook no matter what the database says about the state
* @ returns id and token for a webhook for that channel
* /
async function ensureWebhook ( channelID , forceCreate = false ) {
if ( ! forceCreate ) {
/** @type {{id: string, token: string} | null} */
const row = db . prepare ( "SELECT webhook_id as id, webhook_token as token FROM webhook WHERE channel_id = ?" ) . get ( channelID )
if ( row ) {
return { created : false , ... row }
}
}
// If we got here, we need to create a new webhook.
const webhook = await discord . snow . webhook . createWebhook ( channelID , { name : "Out Of Your Element: Matrix Bridge" } )
assert ( webhook . token )
db . prepare ( "REPLACE INTO webhook (channel_id, webhook_id, webhook_token) VALUES (?, ?, ?)" ) . run ( channelID , webhook . id , webhook . token )
return {
id : webhook . id ,
token : webhook . token ,
created : true
}
}
/ * *
* @ param { string } channelID
* @ param { ( webhook : import ( "../../types" ) . WebhookCreds ) => Promise < T > } callback
* @ returns Promise < T >
* @ template T
* /
async function withWebhook ( channelID , callback ) {
const webhook = await ensureWebhook ( channelID , false )
return callback ( webhook ) . catch ( e => {
// TODO: check if the error was webhook-related and if webhook.created === false, then: const webhook = ensureWebhook(channelID, true); return callback(webhook)
2023-08-19 10:54:23 +00:00
throw e
2023-06-30 03:15:34 +00:00
} )
}
2023-07-03 05:20:24 +00:00
/ * *
* @ param { string } channelID
2023-07-03 12:39:42 +00:00
* @ param { DiscordTypes . RESTPostAPIWebhookWithTokenJSONBody & { files ? : { name : string , file : Buffer } [ ] } } data
2023-08-19 06:39:23 +00:00
* @ param { string } [ threadID ]
2023-07-03 05:20:24 +00:00
* /
2023-08-19 06:39:23 +00:00
async function sendMessageWithWebhook ( channelID , data , threadID ) {
2023-07-03 05:20:24 +00:00
const result = await withWebhook ( channelID , async webhook => {
2023-08-19 06:39:23 +00:00
return discord . snow . webhook . executeWebhook ( webhook . id , webhook . token , data , { wait : true , thread _id : threadID , disableEveryone : true } )
2023-07-03 05:20:24 +00:00
} )
return result
}
2023-06-30 03:15:34 +00:00
module . exports . ensureWebhook = ensureWebhook
module . exports . withWebhook = withWebhook
2023-07-03 05:20:24 +00:00
module . exports . sendMessageWithWebhook = sendMessageWithWebhook