add webhook creation utility
This commit is contained in:
		
							parent
							
								
									cc1210729f
								
							
						
					
					
						commit
						5bd1bc9a5b
					
				
					 4 changed files with 79 additions and 0 deletions
				
			
		
							
								
								
									
										50
									
								
								m2d/actions/register-webhook.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								m2d/actions/register-webhook.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,50 @@
 | 
				
			||||||
 | 
					// @ts-check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const assert = require("assert").strict
 | 
				
			||||||
 | 
					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 => {
 | 
				
			||||||
 | 
							console.error(e)
 | 
				
			||||||
 | 
							// TODO: check if the error was webhook-related and if webhook.created === false, then: const webhook = ensureWebhook(channelID, true); return callback(webhook)
 | 
				
			||||||
 | 
							throw new Error(e)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports.ensureWebhook = ensureWebhook
 | 
				
			||||||
 | 
					module.exports.withWebhook = withWebhook
 | 
				
			||||||
							
								
								
									
										23
									
								
								m2d/actions/send-message.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								m2d/actions/send-message.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					// @ts-check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const assert = require("assert").strict
 | 
				
			||||||
 | 
					const DiscordTypes = require("discord-api-types/v10")
 | 
				
			||||||
 | 
					const passthrough = require("../../passthrough")
 | 
				
			||||||
 | 
					const {sync, discord, db} = passthrough
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** @type {import("./register-webhook")} */
 | 
				
			||||||
 | 
					const registerWebhook = sync.require("./register-webhook")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {string} channelID
 | 
				
			||||||
 | 
					 * @param {DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {name: string, file: Buffer}[]} data
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					// param {DiscordTypes.RESTPostAPIWebhookWithTokenQuery & {wait: true, disableEveryone?: boolean}} options
 | 
				
			||||||
 | 
					async function sendMessage(channelID, data) {
 | 
				
			||||||
 | 
					   const result = await registerWebhook.withWebhook(channelID, async webhook => {
 | 
				
			||||||
 | 
					      return discord.snow.webhook.executeWebhook(webhook.id, webhook.token, data, {wait: true, disableEveryone: true})
 | 
				
			||||||
 | 
					   })
 | 
				
			||||||
 | 
					   return result
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports.sendMessage = sendMessage
 | 
				
			||||||
| 
						 | 
					@ -17,3 +17,4 @@ require("../matrix/read-registration.test")
 | 
				
			||||||
require("../d2m/converters/message-to-event.test")
 | 
					require("../d2m/converters/message-to-event.test")
 | 
				
			||||||
require("../d2m/actions/create-room.test")
 | 
					require("../d2m/actions/create-room.test")
 | 
				
			||||||
require("../d2m/converters/user-to-mxid.test")
 | 
					require("../d2m/converters/user-to-mxid.test")
 | 
				
			||||||
 | 
					require("../d2m/actions/register-user.test")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								types.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								types.d.ts
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -9,6 +9,11 @@ export type AppServiceRegistrationConfig = {
 | 
				
			||||||
	rate_limited: boolean
 | 
						rate_limited: boolean
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type WebhookCreds = {
 | 
				
			||||||
 | 
						id: string
 | 
				
			||||||
 | 
						token: string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Event {
 | 
					namespace Event {
 | 
				
			||||||
	export type BaseStateEvent = {
 | 
						export type BaseStateEvent = {
 | 
				
			||||||
		type: string
 | 
							type: string
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue