diff --git a/README.md b/README.md index be8cb39..8364534 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,8 @@ These go in `config.json`. See also `config.example.json`. |alwaysReplyAnon|false|If `alwaysReply` is set to true, this option controls whether the auto-reply is anonymous| |useNicknames|false|If set to true, mod replies will use their nickname (on the inbox server) instead of their username| |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.| +|typingProxy|false|If set to true, the bot will start typing in the corresponding modmail channel when the user starts typing in DM. +|typingProxyReverse|false|If set to true, the bot will start typing in the user's DM when someone starts typing in the corresponding thread. |enableGreeting|false|Set to true to send a welcome message to new main guild members. Requires `mainGuildId` to be set.| |greetingMessage|None|Text content of the welcome message| |greetingAttachment|None|Path to an image or other attachment to send along with the greeting| diff --git a/src/config.js b/src/config.js index 2b93f55..89abb30 100644 --- a/src/config.js +++ b/src/config.js @@ -29,6 +29,8 @@ const defaultConfig = { "ignoreAccidentalThreads": false, "threadTimestamps": false, "allowMove": false, + "typingProxy": false, + "typingProxyReverse": false, "enableGreeting": false, "greetingMessage": null, diff --git a/src/data/Thread.js b/src/data/Thread.js index e744622..e26e36f 100644 --- a/src/data/Thread.js +++ b/src/data/Thread.js @@ -138,6 +138,13 @@ class Thread { }); } + /** + * @returns {Promise} + */ + getDMChannel() { + return bot.getDMChannel(this.user_id); + } + /** * @param {String} text * @param {Eris~MessageFile|Eris~MessageFile[]} file @@ -146,7 +153,7 @@ class Thread { */ async postToUser(text, file = null) { // Try to open a DM channel with the user - const dmChannel = await bot.getDMChannel(this.user_id); + const dmChannel = await this.getDMChannel(); if (! dmChannel) { throw new Error('Could not open DMs with the user. They may have blocked the bot or set their privacy settings higher.'); } diff --git a/src/main.js b/src/main.js index db15b9f..5c665b5 100644 --- a/src/main.js +++ b/src/main.js @@ -146,6 +146,34 @@ bot.on('messageCreate', async msg => { }); }); +// Typing proxy: forwarding typing events between the DM and the modmail thread +if(config.typingProxy || config.typingProxyReverse) { + bot.on("typingStart", async (channel, user) => { + // config.typingProxy: forward user typing in a DM to the modmail thread + if (config.typingProxy && (channel instanceof Eris.PrivateChannel)) { + const thread = await threads.findOpenThreadByUserId(user.id); + if (! thread) return; + + try { + await bot.sendChannelTyping(thread.channel_id); + } catch (e) {} + } + + // config.typingProxyReverse: forward moderator typing in a thread to the DM + else if (config.typingProxyReverse && (channel instanceof Eris.GuildChannel) && ! user.bot) { + const thread = await threads.findByChannelId(channel.id); + if (! thread) return; + + const dmChannel = await thread.getDMChannel(thread.user_id); + if (! dmChannel) return; + + try { + await bot.sendChannelTyping(dmChannel.id); + } catch(e) {} + } + }); +} + // Mods can reply to modmail threads using !r or !reply // These messages get relayed back to the DM thread between the bot and the user addInboxServerCommand('reply', async (msg, args, thread) => {