Add support for hooks. Add beforeNewThread hook. Allow overriding new thread category id in createNewThreadForUser().
parent
3fc3905628
commit
3c0352ff09
|
@ -52,12 +52,17 @@ function getHeaderGuildInfo(member) {
|
|||
/**
|
||||
* Creates a new modmail thread for the specified user
|
||||
* @param {User} user
|
||||
* @param {Member} member
|
||||
* @param {Boolean} quiet If true, doesn't ping mentionRole or reply with responseMessage
|
||||
* @param {Object} opts
|
||||
* @param {Boolean} opts.quiet If true, doesn't ping mentionRole or reply with responseMessage
|
||||
* @param {Boolean} opts.ignoreRequirements If true, creates a new thread even if the account doesn't meet requiredAccountAge
|
||||
* @param {String} opts.categoryId Override the category ID for the new thread
|
||||
* @returns {Promise<Thread|undefined>}
|
||||
* @throws {Error}
|
||||
*/
|
||||
async function createNewThreadForUser(user, quiet = false, ignoreRequirements = false) {
|
||||
async function createNewThreadForUser(user, opts = {}) {
|
||||
const quiet = opts.quiet != null ? opts.quiet : false;
|
||||
const ignoreRequirements = opts.ignoreRequirements != null ? opts.ignoreRequirements : false;
|
||||
|
||||
const existingThread = await findOpenThreadByUserId(user.id);
|
||||
if (existingThread) {
|
||||
throw new Error('Attempted to create a new thread for a user with an existing open thread!');
|
||||
|
@ -126,9 +131,9 @@ async function createNewThreadForUser(user, quiet = false, ignoreRequirements =
|
|||
console.log(`[NOTE] Creating new thread channel ${channelName}`);
|
||||
|
||||
// Figure out which category we should place the thread channel in
|
||||
let newThreadCategoryId;
|
||||
let newThreadCategoryId = opts.categoryId || null;
|
||||
|
||||
if (config.categoryAutomation.newThreadFromGuild) {
|
||||
if (! newThreadCategoryId && config.categoryAutomation.newThreadFromGuild) {
|
||||
// Categories for specific source guilds (in case of multiple main guilds)
|
||||
for (const [guildId, categoryId] of Object.entries(config.categoryAutomation.newThreadFromGuild)) {
|
||||
if (userGuildData.has(guildId)) {
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* @callback BeforeNewThreadHook_SetCategoryId
|
||||
* @param {String} categoryId
|
||||
* @return void
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef BeforeNewThreadHookEvent
|
||||
* @property {Function} cancel
|
||||
* @property {BeforeNewThreadHook_SetCategoryId} setCategoryId
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback BeforeNewThreadHook
|
||||
* @param {BeforeNewThreadHookEvent} ev
|
||||
* @return {void|Promise<void>}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type BeforeNewThreadHook[]
|
||||
*/
|
||||
const beforeNewThreadHooks = [];
|
||||
|
||||
/**
|
||||
* @param {BeforeNewThreadHook} fn
|
||||
*/
|
||||
function beforeNewThread(fn) {
|
||||
beforeNewThreadHooks.push(fn);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
beforeNewThreadHooks,
|
||||
beforeNewThread,
|
||||
};
|
25
src/main.js
25
src/main.js
|
@ -8,6 +8,7 @@ const {messageQueue} = require('./queue');
|
|||
const utils = require('./utils');
|
||||
const { createCommandManager } = require('./commands');
|
||||
const { getPluginAPI, loadPlugin } = require('./plugins');
|
||||
const { beforeNewThreadHooks } = require('./hooks');
|
||||
|
||||
const blocked = require('./data/blocked');
|
||||
const threads = require('./data/threads');
|
||||
|
@ -123,13 +124,33 @@ function initBaseMessageHandlers() {
|
|||
messageQueue.add(async () => {
|
||||
let thread = await threads.findOpenThreadByUserId(msg.author.id);
|
||||
|
||||
|
||||
// New thread
|
||||
if (! thread) {
|
||||
// Ignore messages that shouldn't usually open new threads, such as "ok", "thanks", etc.
|
||||
if (config.ignoreAccidentalThreads && msg.content && ACCIDENTAL_THREAD_MESSAGES.includes(msg.content.trim().toLowerCase())) return;
|
||||
|
||||
thread = await threads.createNewThreadForUser(msg.author);
|
||||
let cancelled = false;
|
||||
let categoryId = null;
|
||||
|
||||
/**
|
||||
* @type {BeforeNewThreadHookEvent}
|
||||
*/
|
||||
const ev = {
|
||||
cancel() {
|
||||
cancelled = true;
|
||||
},
|
||||
|
||||
setCategoryId(_categoryId) {
|
||||
categoryId = _categoryId;
|
||||
},
|
||||
};
|
||||
|
||||
for (const hook of beforeNewThreadHooks) {
|
||||
await hook(ev, msg);
|
||||
if (cancelled) return;
|
||||
}
|
||||
|
||||
thread = await threads.createNewThreadForUser(msg.author, { categoryId });
|
||||
}
|
||||
|
||||
if (thread) {
|
||||
|
|
|
@ -15,7 +15,7 @@ module.exports = ({ bot, knex, config, commands }) => {
|
|||
return;
|
||||
}
|
||||
|
||||
const createdThread = await threads.createNewThreadForUser(user, true, true);
|
||||
const createdThread = await threads.createNewThreadForUser(user, { quiet: true, ignoreRequirements: true });
|
||||
createdThread.postSystemMessage(`Thread was opened by ${msg.author.username}#${msg.author.discriminator}`);
|
||||
|
||||
msg.channel.createMessage(`Thread opened: <#${createdThread.channel_id}>`);
|
||||
|
|
Loading…
Reference in New Issue