From 90dd35194ccab495581e886a66e2d5937e2e693b Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Wed, 21 Oct 2020 22:07:35 +0300 Subject: [PATCH] Add support for inline snippets. Fixes #464 --- CHANGELOG.md | 4 ++++ docs/configuration.md | 15 +++++++++++++++ src/data/Thread.js | 20 ++++++++++++++++++++ src/data/cfg.jsdoc.js | 3 +++ src/data/cfg.schema.json | 15 +++++++++++++++ 5 files changed, 57 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7884e8..2d9eb77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ Please report any bugs you encounter by [creating a GitHub issue](https://github **General changes:** * Replies are now limited in length to the Discord message limit (including the moderator name and role in the DM sent to the user) * This was to fix issues with `!edit` and `!delete` when a reply spanned multiple messages +* Snippets can now be included *within* messages by wrapping the snippet name in curly braces + * E.g. `!r Hello! {{rules}}` + * The symbols used can be changed with the `inlineSnippetStart` and `inlineSnippetEnd` options + * This feature can be disabled by setting `allowInlineSnippets = off` in your config * Plugins can now also be installed from NPM modules * Example: `plugins[] = npm:some-plugin-package` * Fix occasional bug with expiring blocks where the bot would send the expiry message multiple times diff --git a/docs/configuration.md b/docs/configuration.md index 52c1d77..800771c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -97,6 +97,13 @@ If enabled, staff members can delete their own replies in modmail threads with ` **Default:** `on` If enabled, staff members can edit their own replies in modmail threads with `!edit` +#### allowInlineSnippets +**Default:** `on` +If enabled, snippets can be included *within* replies by wrapping the snippet's name in {{ and }}. +E.g. `!r Hello! {{rules}}` + +See [inlineSnippetStart](#inlineSnippetStart) and [inlineSnippetEnd](#inlineSnippetEnd) to customize the symbols used. + #### alwaysReply **Default:** `off` If enabled, all messages in modmail threads will be sent to the user without having to use `!r`. @@ -185,6 +192,14 @@ If enabled, the bot attempts to ignore common "accidental" messages that would s **Accepts multiple values.** Permission name, user id, or role id required to use bot commands on the inbox server. See ["Permissions" on this page](https://abal.moe/Eris/docs/reference) for supported permission names (e.g. `kickMembers`). +#### inlineSnippetStart +**Default:** `{{` +Symbol(s) to use at the beginning of an inline snippet. See [allowInlineSnippets](#allowInlineSnippets) for more details. + +#### inlineSnippetEnd +**Default:** `}}` +Symbol(s) to use at the end of an inline snippet. See [allowInlineSnippets](#allowInlineSnippets) for more details. + #### timeOnServerDeniedMessage **Default:** `You haven't been a member of the server for long enough to contact modmail.` If `requiredTimeOnServer` is set, users that are too new will be sent this message if they try to message modmail. diff --git a/src/data/Thread.js b/src/data/Thread.js index 1aeee44..2db3d0c 100644 --- a/src/data/Thread.js +++ b/src/data/Thread.js @@ -8,6 +8,7 @@ const config = require("../cfg"); const attachments = require("./attachments"); const { formatters } = require("../formatters"); const { callAfterThreadCloseHooks } = require("../hooks/afterThreadClose"); +const snippets = require("./snippets"); const ThreadMessage = require("./ThreadMessage"); @@ -195,6 +196,25 @@ class Thread { const mainRole = utils.getMainRole(moderator); const roleName = mainRole ? mainRole.name : null; + if (config.allowInlineSnippets) { + // Replace {{snippet}} with the corresponding snippet + // The beginning and end of the variable - {{ and }} - can be changed with the config options + // config.inlineSnippetStart and config.inlineSnippetEnd + const allSnippets = await snippets.all(); + const snippetMap = allSnippets.reduce((_map, snippet) => { + _map[snippet.trigger.toLowerCase()] = snippet; + return _map; + }, {}); + + text = text.replace( + new RegExp(`${config.inlineSnippetStart}(.+)${config.inlineSnippetEnd}`, "i"), + (orig, trigger) => { + const snippet = snippetMap[trigger.toLowerCase()]; + return snippet != null ? snippet.body : orig; + } + ); + } + // Prepare attachments, if any const files = []; const attachmentLinks = []; diff --git a/src/data/cfg.jsdoc.js b/src/data/cfg.jsdoc.js index 1d46881..1acae72 100644 --- a/src/data/cfg.jsdoc.js +++ b/src/data/cfg.jsdoc.js @@ -56,6 +56,9 @@ * @property {boolean} [createThreadOnMention=false] * @property {boolean} [notifyOnMainServerLeave=true] * @property {boolean} [notifyOnMainServerJoin=true] + * @property {boolean} [allowInlineSnippets=true] + * @property {string} [inlineSnippetStart="{{"] + * @property {string} [inlineSnippetEnd="}}"] * @property {string} [logStorage="local"] * @property {object} [logOptions] * @property {string} logOptions.attachmentDirectory diff --git a/src/data/cfg.schema.json b/src/data/cfg.schema.json index 96c42fc..d042dab 100644 --- a/src/data/cfg.schema.json +++ b/src/data/cfg.schema.json @@ -316,6 +316,21 @@ "default": true }, + "allowInlineSnippets": { + "$ref": "#/definitions/customBoolean", + "default": true + }, + + "inlineSnippetStart": { + "type": "string", + "default": "{{" + }, + + "inlineSnippetEnd": { + "type": "string", + "default": "}}" + }, + "logStorage": { "type": "string", "default": "local"