Merge pull request #270 from reboxer/master

Add min time that a user must be a member of the guild
master
Miikka 2019-04-15 18:32:50 +03:00 committed by GitHub
commit 3ad2d0a2ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 45 additions and 4 deletions

View File

@ -81,6 +81,7 @@ These go in `config.json`. See also `config.example.json`.
|greetingMessage|None|Text content of the welcome message| |greetingMessage|None|Text content of the welcome message|
|ignoreAccidentalThreads|false|If set to true, the bot attempts to ignore common "accidental" messages that would start a new thread, such as "ok", "thanks", etc.| |ignoreAccidentalThreads|false|If set to true, the bot attempts to ignore common "accidental" messages that would start a new thread, such as "ok", "thanks", etc.|
|inboxServerPermission|None|Permission required to use bot commands on the inbox server| |inboxServerPermission|None|Permission required to use bot commands on the inbox server|
|joinedAtDeniedMessage|"You haven't been a member of the server for enough time to contact modmail"|See `requiredJoinedAt` below|
|mentionRole|"here"|Role that is mentioned when new threads are created or the bot is mentioned. Accepted values are "here", "everyone", or a role id as a string. Set to null to disable these pings entirely.| |mentionRole|"here"|Role that is mentioned when new threads are created or the bot is mentioned. Accepted values are "here", "everyone", or a role id as a string. Set to null to disable these pings entirely.|
|mentionUserInThreadHeader|false|If set to true, mentions the thread's user in the thread header| |mentionUserInThreadHeader|false|If set to true, mentions the thread's user in the thread header|
|newThreadCategoryId|None|ID of the category where new modmail thread channels should be placed| |newThreadCategoryId|None|ID of the category where new modmail thread channels should be placed|
@ -89,6 +90,7 @@ These go in `config.json`. See also `config.example.json`.
|prefix|"!"|Prefix for bot commands| |prefix|"!"|Prefix for bot commands|
|relaySmallAttachmentsAsAttachments|false|Whether to relay small attachments from users as native attachments rather than links in modmail threads| |relaySmallAttachmentsAsAttachments|false|Whether to relay small attachments from users as native attachments rather than links in modmail threads|
|requiredAccountAge|None|Required account age for contacting modmail (in hours). If the account is not old enough, a new thread will not be created and the bot will reply with `accountAgeDeniedMessage` (if set) instead.| |requiredAccountAge|None|Required account age for contacting modmail (in hours). If the account is not old enough, a new thread will not be created and the bot will reply with `accountAgeDeniedMessage` (if set) instead.|
|requiredJoinedAt|None|Required amount of time (in hours) the user must be a member of the server before being able to contact modmail. If the user hasn't been a member of the server for the specified time, a new thread will not be created and the bot will reply with `joinedAtDeniedMessage` (if set) instead. Only works if one main guild has been set.|
|responseMessage|"Thank you for your message! Our mod team will reply to you here as soon as possible."|The bot's response to DMs that start a new thread| |responseMessage|"Thank you for your message! Our mod team will reply to you here as soon as possible."|The bot's response to DMs that start a new thread|
|smallAttachmentLimit|2097152|Size limit of `relaySmallAttachmentsAsAttachments`, in bytes (default is 2MB)| |smallAttachmentLimit|2097152|Size limit of `relaySmallAttachmentsAsAttachments`, in bytes (default is 2MB)|
|snippetPrefix|"!!"|Prefix to use snippets| |snippetPrefix|"!!"|Prefix to use snippets|

View File

@ -78,6 +78,9 @@ const defaultConfig = {
"requiredAccountAge": null, // In hours "requiredAccountAge": null, // In hours
"accountAgeDeniedMessage": "Your Discord account is not old enough to contact modmail.", "accountAgeDeniedMessage": "Your Discord account is not old enough to contact modmail.",
"requiredJoinedAt": null, // In hours too
"joinedAtDeniedMessage": "You haven't been a member of the server for enough time to contact modmail",
"relaySmallAttachmentsAsAttachments": false, "relaySmallAttachmentsAsAttachments": false,
"smallAttachmentLimit": 1024 * 1024 * 2, "smallAttachmentLimit": 1024 * 1024 * 2,
"attachmentStorage": "local", "attachmentStorage": "local",

View File

@ -51,12 +51,24 @@ function getHeaderGuildInfo(member) {
* @returns {Promise<Thread>} * @returns {Promise<Thread>}
* @throws {Error} * @throws {Error}
*/ */
async function createNewThreadForUser(user, quiet = false) { async function createNewThreadForUser(user, member, quiet = false) {
const existingThread = await findOpenThreadByUserId(user.id); const existingThread = await findOpenThreadByUserId(user.id);
if (existingThread) { if (existingThread) {
throw new Error('Attempted to create a new thread for a user with an existing open thread!'); throw new Error('Attempted to create a new thread for a user with an existing open thread!');
} }
// Check the config for a requirement of a minimum time the user must be a member of the guild to contact modmail,
// if the user hasn't been a member of the guild for the specified time, return an optional message without making a new thread
if (config.requiredJoinedAt && member) {
if (member.joinedAt > moment() - config.requiredJoinedAt) {
if (config.joinedAtDeniedMessage) {
const privateChannel = await user.getDMChannel();
await privateChannel.createMessage(config.joinedAtDeniedMessage);
}
return;
}
}
// Check the config for a requirement of account age to contact modmail, // Check the config for a requirement of account age to contact modmail,
// if the account is too young, return an optional message without making a new thread // if the account is too young, return an optional message without making a new thread
if (config.requiredAccountAge) { if (config.requiredAccountAge) {

View File

@ -74,12 +74,25 @@ bot.on('messageCreate', async msg => {
messageQueue.add(async () => { messageQueue.add(async () => {
let thread = await threads.findOpenThreadByUserId(msg.author.id); let thread = await threads.findOpenThreadByUserId(msg.author.id);
// Due the way discord works, private channels don't have a member property as they are a guild only property,
// if more than one main guild have been set, we just ignore the requiredJoinedAt config option
let member;
const mainGuilds = utils.getMainGuilds();
if (mainGuilds.length === 1) {
member = bot.guilds.get(mainGuilds[0]).members.get(msg.author.id);
if (! member) {
member = false;
}
} else {
member = false;
}
// New thread // New thread
if (! thread) { if (! thread) {
// Ignore messages that shouldn't usually open new threads, such as "ok", "thanks", etc. // 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; if (config.ignoreAccidentalThreads && msg.content && ACCIDENTAL_THREAD_MESSAGES.includes(msg.content.trim().toLowerCase())) return;
thread = await threads.createNewThreadForUser(msg.author); thread = await threads.createNewThreadForUser(msg.author, member);
} }
if (thread) await thread.receiveUserReply(msg); if (thread) await thread.receiveUserReply(msg);

View File

@ -17,13 +17,24 @@ module.exports = bot => {
return; return;
} }
let member;
const mainGuilds = utils.getMainGuilds();
if (mainGuilds.length === 1) {
member = bot.guilds.get(mainGuilds[0]).members.get(msg.author.id);
if (! member) {
member = false;
}
} else {
member = false;
}
const existingThread = await threads.findOpenThreadByUserId(user.id); const existingThread = await threads.findOpenThreadByUserId(user.id);
if (existingThread) { if (existingThread) {
utils.postSystemMessageWithFallback(msg.channel, thread, `Cannot create a new thread; there is another open thread with this user: <#${existingThread.channel_id}>`); utils.postSystemMessageWithFallback(msg.channel, thread, `Cannot create a new thread; there is another open thread with this user: <#${existingThread.channel_id}>`);
return; return;
} }
const createdThread = await threads.createNewThreadForUser(user, true); const createdThread = await threads.createNewThreadForUser(user, member, true);
createdThread.postSystemMessage(`Thread was opened by ${msg.author.username}#${msg.author.discriminator}`); createdThread.postSystemMessage(`Thread was opened by ${msg.author.username}#${msg.author.discriminator}`);
if (thread) { if (thread) {

View File

@ -78,7 +78,7 @@ function postError(str) {
* @returns {boolean} * @returns {boolean}
*/ */
function isStaff(member) { function isStaff(member) {
if (!member) return false; if (! member) return false;
if (config.inboxServerPermission.length === 0) return true; if (config.inboxServerPermission.length === 0) return true;
return config.inboxServerPermission.some(perm => { return config.inboxServerPermission.some(perm => {