From e5b29a235e812470023c1f8a67c6476a31010556 Mon Sep 17 00:00:00 2001 From: Dragory Date: Sat, 21 Apr 2018 15:38:21 +0300 Subject: [PATCH] Add multi-server support and more thread header information Fixes #63. Multi-server support allows you to set an array of ids in mainGuildId. If there are more than 1 main guild, the thread header will display nickname and join date for each main guild the user is in. Thread header information now also includes how long it's been since the user joined the guild(s). The commit also includes some minor code cleanup. --- src/config.js | 8 +++++++ src/data/threads.js | 53 +++++++++++++++++++++++++++++++++++---------- src/utils.js | 32 +++++++++++++++++---------- 3 files changed, 71 insertions(+), 22 deletions(-) diff --git a/src/config.js b/src/config.js index 5e83950..1f835e3 100644 --- a/src/config.js +++ b/src/config.js @@ -60,6 +60,7 @@ for (const [prop, value] of Object.entries(userConfig)) { finalConfig[prop] = value; } +// Default knex config if (! finalConfig['knex']) { finalConfig['knex'] = { client: 'sqlite', @@ -70,12 +71,14 @@ if (! finalConfig['knex']) { }; } +// Make sure migration settings are always present in knex config Object.assign(finalConfig['knex'], { migrations: { directory: path.join(finalConfig.dbDir, 'migrations') } }); +// Make sure all of the required config options are present for (const opt of required) { if (! finalConfig[opt]) { console.error(`Missing required config.json value: ${opt}`); @@ -83,4 +86,9 @@ for (const opt of required) { } } +// Make sure mainGuildId is internally always an array +if (! Array.isArray(finalConfig['mainGuildId'])) { + finalConfig['mainGuildId'] = [finalConfig['mainGuildId']]; +} + module.exports = finalConfig; diff --git a/src/data/threads.js b/src/data/threads.js index ee72817..0b8883b 100644 --- a/src/data/threads.js +++ b/src/data/threads.js @@ -4,7 +4,6 @@ const moment = require('moment'); const uuid = require('uuid'); const humanizeDuration = require('humanize-duration'); -const bot = require('../bot'); const knex = require('../knex'); const config = require('../config'); const utils = require('../utils'); @@ -37,6 +36,13 @@ async function findOpenThreadByUserId(userId) { return (thread ? new Thread(thread) : null); } +function getHeaderGuildInfo(member) { + return { + nickname: member.nick || member.user.username, + joinDate: humanizeDuration(Date.now() - member.joinedAt, {largest: 2, round: true}) + }; +} + /** * Creates a new modmail thread for the specified user * @param {Eris.User} user @@ -96,20 +102,45 @@ async function createNewThreadForUser(user, quiet = false) { } // Post some info to the beginning of the new thread - const mainGuild = utils.getMainGuild(); - const member = (mainGuild ? mainGuild.members.get(user.id) : null); - if (! member) console.log(`[INFO] Member ${user.id} not found in main guild ${config.mainGuildId}`); + const infoHeaderItems = []; - let mainGuildNickname = null; - if (member && member.nick) mainGuildNickname = member.nick; - else if (member && member.user) mainGuildNickname = member.user.username; - else if (member == null) mainGuildNickname = 'NOT ON SERVER'; + // Account age + const accountAge = humanizeDuration(Date.now() - user.createdAt, {largest: 2, round: true}); + infoHeaderItems.push(`ACCOUNT AGE **${accountAge}**`); - if (mainGuildNickname == null) mainGuildNickname = 'UNKNOWN'; + // User id + infoHeaderItems.push(`ID **${user.id}**`); + + let infoHeader = infoHeaderItems.join(', '); + + // Guild info + const guildInfoHeaderItems = new Map(); + + utils.getMainGuilds().forEach(guild => { + const member = guild.members.get(user.id); + if (! member) return; + + const {nickname, joinDate} = getHeaderGuildInfo(member); + guildInfoHeaderItems.set(guild.name, [ + `NICKNAME **${nickname}**`, + `JOINED **${joinDate}** ago` + ]); + }); + + guildInfoHeaderItems.forEach((items, guildName) => { + if (guildInfoHeaderItems.size === 1) { + infoHeader += `\n${items.join(', ')}`; + } else { + infoHeader += `\n**[${guildName}]** ${items.join(', ')}`; + } + }); const userLogCount = await getClosedThreadCountByUserId(user.id); - const accountAge = humanizeDuration(Date.now() - user.createdAt, {largest: 2}); - const infoHeader = `ACCOUNT AGE **${accountAge}**, ID **${user.id}**, NICKNAME **${mainGuildNickname}**, LOGS **${userLogCount}**\n-------------------------------`; + if (userLogCount > 0) { + infoHeader += `\n\nThis user has **${userLogCount}** previous modmail threads. Use \`${config.prefix}logs\` to see them.`; + } + + infoHeader += '\n────────────────'; await newThread.postSystemMessage(infoHeader); diff --git a/src/utils.js b/src/utils.js index 8177a5b..8ab6e8a 100644 --- a/src/utils.js +++ b/src/utils.js @@ -7,10 +7,10 @@ const config = require('./config'); class BotError extends Error {} -const userMentionRegex = /^<@\!?([0-9]+?)>$/; +const userMentionRegex = /^<@!?([0-9]+?)>$/; let inboxGuild = null; -let mainGuild = null; +let mainGuilds = []; let logChannel = null; /** @@ -23,17 +23,26 @@ function getInboxGuild() { } /** - * @returns {Eris~Guild} + * @returns {Eris~Guild[]} */ -function getMainGuild() { - if (! mainGuild) mainGuild = bot.guilds.find(g => g.id === config.mainGuildId); - if (! mainGuild) console.warn('[WARN] The bot is not on the main server! If this is intentional, you can ignore this warning.'); - return mainGuild; +function getMainGuilds() { + if (mainGuilds.length === 0) { + mainGuilds = bot.guilds.filter(g => config.mainGuildId.includes(g.id)); + } + + if (mainGuilds.length !== config.mainGuildId.length) { + if (config.mainGuildId.length === 1) { + console.warn(`[WARN] The bot hasn't joined the main guild!`); + } else { + console.warn(`[WARN] The bot hasn't joined one or more main guilds!`); + } + } + + return mainGuilds; } /** * Returns the designated log channel, or the default channel if none is set - * @param bot * @returns {Eris~TextChannel} */ function getLogChannel() { @@ -91,8 +100,9 @@ function messageIsOnInboxServer(msg) { */ function messageIsOnMainServer(msg) { if (! msg.channel.guild) return false; - if (msg.channel.guild.id !== getMainGuild().id) return false; - return true; + + return getMainGuilds() + .some(g => msg.channel.guild.id === g.id); } /** @@ -268,7 +278,7 @@ module.exports = { BotError, getInboxGuild, - getMainGuild, + getMainGuilds, getLogChannel, postError, postLog,