diff --git a/.eslintrc b/.eslintrc index d33e1cf..437180d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -19,6 +19,8 @@ "!": true, "!!": true } - }] + }], + "quotes": ["error", "double"], + "no-shadow": "error" } } diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..04d2265 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "monthly" + target-branch: "dev" + allow: + - dependency-type: "direct" diff --git a/.gitignore b/.gitignore index 6757ecf..621624d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ /.vscode /.idea /node_modules -/config.* -!/config.example.ini /welcome.png /update.sh + +# Config files +/config.* +*.config.ini +!/config.example.ini diff --git a/.nvmrc b/.nvmrc index f599e28..8351c19 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -10 +14 diff --git a/CHANGELOG.md b/CHANGELOG.md index c556d73..da01f5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,20 +1,280 @@ # Changelog +For instructions on how to update the bot, see **[✨ Updating the bot](docs/updating.md)** -## v2.31.0-beta.0 -This is a beta release. It is not available on the Releases page and bugs are expected. +## v3.3.2 +* Fix database warning when updating to v3.3.1 or higher -* Add support for Node.js 13 - * Support for Node.js 14 is coming in a future update that will also drop Node.js 10 support. - This mirrors the `sqlite3` library's version support. -* Log formatting is now more consistent and easier to parse with automated tools +## v3.3.1 +* Fix crash when a user joins or leaves a [stage channel](https://blog.discord.com/captivate-your-community-with-stage-channels-46bbb756e89b) +* Fix global moderator display role overrides (i.e. `!role` used outside of a thread) not working + +## v3.3.0 + +**Breaking changes:** +* The default value for [`inboxServerPermission`](docs/configuration.md#inboxServerPermission) is now `manageMessages` + * This means that after updating, if you haven't set `inboxServerPermission` in your `config.ini`, + only those members with the "Manage Messages" permission on the inbox server will be able to use the bot's commands +* The default value for [`mentionRole`](docs/configuration.md#mentionRole) is now `none` + * To turn `@here` pings back on for new threads, set `mentionRole = here` in your `config.ini` + +**General changes:** +* New option: `showResponseMessageInThreadChannel` + * Controls whether the bot's response message is shown in the thread channel +* Bot and Node.js version is now shown on bot start-up +* `!close silent` can now also be used with `!close -silent` and `!close -s` ([#528](https://github.com/Dragory/modmailbot/pull/528) by [@SnowyLuma](https://github.com/SnowyLuma)) +* `!close cancel` can now also be used with `!close -cancel` and `!close -c` +* `config.example.ini` now contains several common options by default +* When starting the bot via command line, you can now specify which config file to load with the `--config`/`-c` CLI option + * E.g. `npm start -- -c my-other-config.ini` (note the `--` between `npm start` and the option) +* Updated bot dependencies + +**Plugins:** +* Plugins are now installed before connecting to the Discord Gateway +* Fix GitHub-based NPM plugins requiring Git to be installed to work + * If you need to install GitHub-based plugins with Git after this change, set `useGitForGitHubPlugins = on` in your config +* Plugin installation errors are no longer truncated + +## v3.2.0 + +**General changes:** +* Updated to Eris 0.14.0, which changes the API url used to `discord.com` instead of `discordapp.com` + * API calls to `discordapp.com` are being phased out on Nov 7, 2020 + * This means that bot versions prior to v3.2.0 *might stop working* on Nov 7, 2020 +* New options: `allowBlock`, `allowSuspend`, `allowSnippets` ([#498](https://github.com/Dragory/modmailbot/pull/498) by [@lirolake](https://github.com/lirolake)) + * These all default to `on` +* Improved error messages and error handling + * Removes at least one instance of ECONNRESET errors +* Fixed issue where NPM plugins would not install on Windows +* Fixed issue where mentions by the bot were not working in certain situations ([#496](https://github.com/Dragory/modmailbot/pull/496) by [@DarkView](https://github.com/DarkView)) +* Fixed issue where long system messages (primarily from plugins) would not get chunked properly and would throw an error instead + +**Plugins:** +* Make sure to check the [Eris 0.14.0 changelog](https://github.com/abalabahaha/eris/releases/tag/0.14.0) for any changes that might affect your plugins +* The `attachments` object now includes a new `saveAttachment()` function to save arbitrary attachments using the bot's `attachmentStorage` +* Fixed the `ignoreHooks` option for `threads.createNewThreadForUser()` not working +* Fixed `!newthread` throwing an error if a plugin cancels thread creation in the `beforeNewThread` hook + +## v3.1.0 +* Each thread is now assigned a number, increasing by 1 each thread. This can be used in commands like `!log` in place of the full thread ID. +* New option: `autoAlert` + * When enabled, the last moderator to reply to a modmail thread will be automatically alerted when the thread gets a new reply + * Auto-alert kicks in after a small delay after the reply to prevent alerts in the middle of an ongoing conversation. This delay is set by the option `autoAlertDelay`. +* New option: `pinThreadHeader` + * When enabled, the bot will automatically pin the "thread header" message that contains the user's details +* `!thread` is now an alias for `!log`/`!loglink` +* Fix some bugs with the `mentionRole` option +* `mentionRole = off` now behaves the same as `mentionRole = none` +* Fixed snippet previews (via `!snippet snippet_name_here`) sometimes cutting off the first word ([#491](https://github.com/Dragory/modmailbot/pull/491) by @Gugu7264) +* When calling `threads.createNewThreadForUser()`, plugins can now specify `mentionRole` as one of the options to override the default mentionRole config option value for the new thread + +## v3.0.3 +* Fix inline snippets only working once per reply + +## v3.0.2 +* Fix `npm ci` and `start.bat` failing when Git is not installed + +## v3.0.1 +* Fix local attachments not being accessible through the bot's links + +## v3.0.0 +*This changelog also includes changes from v2.31.0-beta.1 and v2.31.0-beta.2* + +**General changes:** +* **BREAKING CHANGE:** Logs from Modmail versions prior to Feb 2018 are no longer converted automatically + * To update from a Modmail version from before Feb 2018, update to `v2.30.1` and run the bot once first. Then you can update to version v3.0.0 and later. +* **BREAKING CHANGE:** Added support for Node.js 13 and 14, **dropped support for Node.js 10 and 11** + * The supported versions are now 12, 13, and 14 +* **BREAKING CHANGE:** The bot now requests the necessary [Gateway Intents](https://discord.com/developers/docs/topics/gateway#gateway-intents) + * **This includes the privileged "Server Members Intent"**, which is used for server greetings/welcome messages. + This means that [**you need to turn on "Server Members Intent"**](docs/server-members-intent-2.png) on the bot's page on the Discord Developer Portal. +* Added support for editing and deleting staff replies via new `!edit` and `!delete` commands + * This is **enabled by default** + * This can be disabled with the `allowStaffEdit` and `allowStaffDelete` options + * Only the staff member who sent the reply can edit/delete it +* Renamed the following options. Old names are still supported as aliases, so old config files won't break. + * `mainGuildId` => `mainServerId` + * `mailGuildId` => `inboxServerId` + * `categoryAutomation.newThreadFromGuild` => `categoryAutomation.newThreadFromServer` + * `guildGreetings` => `serverGreetings` +* Moderators can now set the role they'd like to be displayed with their replies ("display role") by default and on a per-thread basis by using `!role` + * Moderators can only choose roles they currently have + * You can view your current display role by using `!role` + * If you're in a modmail thread, this will show your display role for that thread + * If you're *not* in a modmail thread, this will show your *default* display role + * You can set the display role by using `!role `, e.g. `!role Interviewer` + * If you're in a modmail thread, this will set your display role for that thread + * If you're *not* in a modmail thread, this will set your *default* display role + * You can reset the display role by using `!role reset` + * If you're in a modmail thread, this will reset your display role for that thread to the default + * If you're *not* in a modmail thread, this will reset your *default* display role + * This feature can be disabled by setting `allowChangingDisplayRole = off` +* New option: `fallbackRoleName` + * Sets the role name to display in moderator replies if the moderator doesn't have a hoisted role +* New option `logStorage` + * Allows changing how logs are stored + * Possible values are `local` (default), `attachment`, and `none` +* New **default** attachment storage option: `original` + * This option simply links the original attachment and does not rehost it in any way +* New option `reactOnSeen` ([#398](https://github.com/Dragory/modmailbot/pull/398) by @Eegras) + * When enabled, the bot will react to user DMs with a checkmark when they have been received + * The reaction emoji can be customized with the `reactOnSeenEmoji` option +* New option `createThreadOnMention` ([#397](https://github.com/Dragory/modmailbot/pull/397) by @dopeghoti) + * When enabled, a new modmail thread will be created whenever a user mentions/pings the bot on the main server + * As with `pingOnBotMention`, staff members are automatically ignored +* New option `statusType` + * Allows changing the bot's status type between "Playing", "Watching", "Listening" + * Possible values are `playing` (default), `watching`, `listening` +* New option `anonymizeChannelName` ([#457](https://github.com/Dragory/modmailbot/pull/457) by @funkyhippo) + * Off by default. When enabled, instead of using the user's name as the channel name, uses a random channel name instead. + * Useful on single-server setups where people with modified clients can see the names of even hidden channels +* New option `updateNotificationsForBetaVersions` + * Off by default. When enabled, also shows update notifications for beta versions. + * By default, update notifications are only shown for stable releases +* Snippets can now be included *within* messages by wrapping the snippet name in curly braces + * E.g. `!r Hello! {{rules}}` to include the snippet `rules` in the place of `{{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 + * By default, the bot will refuse to send a reply with an unknown inline snippet. To disable this behavior, set `errorOnUnknownInlineSnippet = off`. +* `mentionRole` can now be set to `none` +* Removed the long-deprecated `logDir` option +* The bot now notifies if the user leaves/joins the server ([#437](https://github.com/Dragory/modmailbot/pull/437) by @DarkView) +* 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 is to fix issues with `!edit` and `!delete` when a reply spanned multiple messages * DM channel and message IDs are now stored * Use `!loglink -v` to view these in logs * Use `!dm_channel_id` in an inbox thread to view the DM channel ID * *DM channel and message IDs are primarily useful for Discord T&S reports* +* Unless `fallbackRoleName` is set, anonymous replies without a role will no longer display "Moderator:" at the beginning of the message +* Plugins can now also be installed from NPM modules + * Example: `plugins[] = npm:some-plugin-package` +* "Connection reset by peer" error (code 1006) is now handled gracefully in the background and no longer crashes the bot +* Multiple people can now sign up for reply alerts (`!alert`) simultaneously ([#373](https://github.com/Dragory/modmailbot/pull/373) by @DarkView) +* The bot now displays a note if the user sent an application invite, e.g. an invite to listen along on Spotify +* The bot now displays a note if the user sent a sticker, including the sticker's name +* Log formatting is now more consistent and easier to parse with automated tools +* Messages in modmail threads by other bots are no longer ignored, and are displayed in logs +* Added official support for MySQL databases. Refer to the documentation on `dbType` for more details. + * This change also means the following options are **no longer supported:** + * `dbDir` (use `sqliteOptions.filename` to specify the database file instead) + * `knex` (see `dbType` documentation for more details) +* System messages sent to the user, such as `responseMessage` and `closeMessage`, are now shown in the thread channel +* Fixed `!edit_snippet` crashing the bot when leaving the new snippet text empty +* Fix crash when using `!newthread` with the bot's own ID (fixes [#452](https://github.com/Dragory/modmailbot/issues/452)) +* Fix occasional bug with expiring blocks where the bot would send the expiry message multiple times +* Fix bug with long messages being cut off and only the last part being shown in the thread (most evident in long DMs and e.g. !edit notifications of long messages) +* Fix messages containing *only* a large number (e.g. an ID) rounding the number +* Several common errors are now handled silently in the background, such as "Connection reset by peer" + +**Plugins:** +* Added support for replacing default message formatting in threads, DMs, and logs +* Added support for *hooks*. Hooks can be used to run custom plugin code before/after specific moments. + * Two hooks are initially available: `beforeNewThread` and `afterThreadClose` + * See plugin documentation for mode details +* If your plugin requires special gateway intents, use the new `extraIntents` config option +* Plugins can now access the bot's web server via a new `webserver` property in plugin arguments +* Plugins can now store *metadata* in threads and thread messages via new `setMetadataValue` and `getMetadataValue` functions on `Thread` and `ThreadMessage` objects +* Plugins can access the API for setting/getting moderator display roles via a new `displayRoles` property in plugin arguments +* System messages now have a formatter +* The `beforeNewThread` hook's parameters now also include the original DM message object +* Plugins can now access the `threads` module (via `pluginApi.threads`) to create and fetch threads +* Plugins can now access the `displayRoles` module (via `pluginApi.displayRoles`) to get, set, and reset display role overrides for moderators, + and to get the final role that will be displayed in moderator replies (by default or per-thread) + +**Internal/technical updates:** +* Updated Eris to v0.13.3 +* Updated several other dependencies +* New JSON Schema based config parser that validates each option and their types more strictly to prevent undefined behavior +* Database migrations are now stored under `src/` +* Modmail now uses [Express](https://expressjs.com/) as its web server for logs/attachments +* Unhandled rejections are now handled the same as uncaught exceptions, and *will* crash the bot + +## v2.31.0-beta.2 +**This is a beta release, bugs are expected.** +Please report any bugs you encounter by [creating a GitHub issue](https://github.com/Dragory/modmailbot/issues/new)! + +**General changes:** +* **BREAKING CHANGE:** Logs from Modmail versions prior to Feb 2018 are no longer converted automatically + * To update from a Modmail version from before Feb 2018, update to `v2.30.1` and run the bot once first. Then you can update to later versions. +* New option `logStorage` + * Allows changing how logs are stored + * Possible values are `local` (default), `attachment`, and `none` +* New option `statusType` + * Allows changing the bot's status type between "Playing", "Watching", "Listening" + * Possible values are `playing` (default), `watching`, `listening` +* New option `anonymizeChannelName` ([#457](https://github.com/Dragory/modmailbot/pull/457) by @funkyhippo) + * Off by default. When enabled, instead of using the user's name as the channel name, uses a random channel name instead. + * Useful on single-server setups where people with modified clients can see the names of even hidden channels +* New option `updateNotificationsForBetaVersions` + * Off by default. When enabled, also shows update notifications for beta versions. + * By default, update notifications are only shown for stable releases +* `mentionRole` can now be set to `none` +* The bot now notifies if the user leaves/joins the server ([#437](https://github.com/Dragory/modmailbot/pull/437) by @DarkView) +* Fix crash when using `!newthread` with the bot's own ID (fixes [#452](https://github.com/Dragory/modmailbot/issues/452)) + +**Plugins:** +* New hook: `afterThreadClose` + * Called right after a thread is closed with the thread's id +* You can now add custom log storage types + +**Internal/technical updates:** +* Database migrations are now stored under `src/` + +## v2.31.0-beta.1 +**This is a beta release, bugs are expected.** +Please report any bugs you encounter by [creating a GitHub issue](https://github.com/Dragory/modmailbot/issues/new)! + +**General changes:** +* **BREAKING CHANGE:** Added support for Node.js 13 and 14, dropped support for Node.js 10 and 11 + * The supported versions are now 12, 13, and 14 +* **BREAKING CHANGE:** The bot now requests the necessary [Gateway Intents](https://discord.com/developers/docs/topics/gateway#gateway-intents) + * **This includes the privileged "Server Members Intent"**, which is used for server greetings/welcome messages. + This means that [**you need to turn on "Server Members Intent"**](docs/server-members-intent-2.png) on the bot's page on the Discord Developer Portal. +* Renamed the following options. Old names are still supported as aliases, so old config files won't break. + * `mainGuildId` => `mainServerId` + * `mailGuildId` => `inboxServerId` + * `categoryAutomation.newThreadFromGuild` => `categoryAutomation.newThreadFromServer` + * `guildGreetings` => `serverGreetings` +* Added support for editing and deleting staff replies + * This is **enabled by default** + * This can be disabled with the `allowStaffEdit` and `allowStaffDelete` options + * Only the staff member who sent the reply can edit/delete it +* New option `reactOnSeen` ([#398](https://github.com/Dragory/modmailbot/pull/398) by @Eegras) + * When enabled, the bot will react to user DMs with a checkmark when they have been received + * The reaction emoji can be customized with the `reactOnSeenEmoji` option +* New option `createThreadOnMention` ([#397](https://github.com/Dragory/modmailbot/pull/397) by @dopeghoti) + * When enabled, a new modmail thread will be created whenever a user mentions/pings the bot on the main server + * As with `pingOnBotMention`, staff members are automatically ignored +* New **default** attachment storage option: `original` + * This option simply links the original attachment and does not rehost it in any way +* DM channel and message IDs are now stored + * Use `!loglink -v` to view these in logs + * Use `!dm_channel_id` in an inbox thread to view the DM channel ID + * *DM channel and message IDs are primarily useful for Discord T&S reports* +* Multiple people can now sign up for reply alerts (`!alert`) simultaneously ([#373](https://github.com/Dragory/modmailbot/pull/373) by @DarkView) +* The bot now displays a note if the user sent an application invite, e.g. an invite to listen along on Spotify +* Log formatting is now more consistent and easier to parse with automated tools +* Messages in modmail threads by other bots are no longer ignored, and are displayed in logs +* Added official support for MySQL databases. Refer to the documentation on `dbType` for more details. + * This change also means the following options are **no longer supported:** + * `dbDir` (use `sqliteOptions.filename` to specify the database file instead) + * `knex` (see `dbType` documentation for more details) +* Removed the long-deprecated `logDir` option +* Fixed `!edit_snippet` crashing the bot when leaving the new snippet text empty + +**Plugins:** +* Added support for replacing default message formatting in threads, DMs, and logs +* Added support for *hooks*. Hooks can be used to run custom plugin code before/after specific moments. + * Initially only the `beforeNewThread` hook is available. See plugin documentation for more details. +* If your plugin requires special gateway intents, use the new `extraIntents` config option * Some code reorganisation related to threads and thread messages. If you have a plugin that interacts with Thread or ThreadMessage objects, test them before running this update in production! +**Internal/technical updates:** +* Updated Eris to v0.13.3 +* Updated several other dependencies +* New JSON Schema based config parser that validates each option and their types more strictly to prevent undefined behavior + ## v2.30.1 * Fix crash with `responseMessage` and `closeMessage` introduced in v2.30.0 ([#369](https://github.com/Dragory/modmailbot/pull/369)) diff --git a/LICENSE.md b/LICENSE.md index f682d0f..094390e 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 Miikka Virtanen +Copyright (c) 2017–2021 Miikka (Dragory) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index af4e399..bdf7252 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,25 @@ # Modmail for Discord -Modmail Bot is a bot for [Discord](https://discordapp.com/) that allows users to DM the bot to contact the server's moderators/staff +Modmail Bot is a bot for [Discord](https://discord.com/) that allows users to DM the bot to contact the server's moderators/staff without messaging them individually or pinging them publically on the server. These DMs get relayed to modmail *threads*, channels where staff members can reply to and talk with the user. To the user, the entire process happens in DMs with the bot. Inspired by Reddit's modmail system. +**⚠ Note on updating to v3.0.0:** If you're currently using a *very* old version of the bot, from before February 2018, you'll first need to update to v2.30.1 and run the bot once before updating to v3.0.0. + +Always take a backup of your `db/data.sqlite` file before updating the bot. + ## Getting started * **[🛠️ Setting up the bot](docs/setup.md)** +* **[✨ Updating the bot](docs/updating.md)** +* **[🙋 Frequently Asked Questions](docs/faq.md)** * [📝 Configuration](docs/configuration.md) * [🤖 Commands](docs/commands.md) * [📋 Snippets](docs/snippets.md) * [🧩 Plugins](docs/plugins.md) -* [🙋 Frequently Asked Questions](docs/faq.md) -* [Release notes](CHANGELOG.md) +* [📌 Release notes](CHANGELOG.md) +* [📚 **Community Guides & Resources**](https://github.com/Dragory/modmailbot-community-resources) ## Support server If you need help with setting up the bot or would like to discuss other things related to it, join the support server on Discord here: diff --git a/config.example.ini b/config.example.ini deleted file mode 100644 index 8b403a9..0000000 --- a/config.example.ini +++ /dev/null @@ -1,9 +0,0 @@ -# Required settings -# ----------------- -token = REPLACE_WITH_TOKEN -mainGuildId = REPLACE_WITH_MAIN_SERVER_ID -mailGuildId = REPLACE_WITH_INBOX_SERVER_ID -logChannelId = REPLACE_WITH_LOG_CHANNEL_ID - -# Add new options below this line: -# ---------------------------------- diff --git a/db/migrations/20171223203915_create_tables.js b/db/migrations/20171223203915_create_tables.js deleted file mode 100644 index b5880a3..0000000 --- a/db/migrations/20171223203915_create_tables.js +++ /dev/null @@ -1,45 +0,0 @@ -exports.up = async function(knex, Promise) { - await knex.schema.createTableIfNotExists('threads', table => { - table.string('id', 36).notNullable().primary(); - table.integer('status').unsigned().notNullable().index(); - table.integer('is_legacy').unsigned().notNullable(); - table.string('user_id', 20).notNullable().index(); - table.string('user_name', 128).notNullable(); - table.string('channel_id', 20).nullable().unique(); - table.dateTime('created_at').notNullable().index(); - }); - - await knex.schema.createTableIfNotExists('thread_messages', table => { - table.increments('id'); - table.string('thread_id', 36).notNullable().index().references('id').inTable('threads').onDelete('CASCADE'); - table.integer('message_type').unsigned().notNullable(); - table.string('user_id', 20).nullable(); - table.string('user_name', 128).notNullable(); - table.mediumtext('body').notNullable(); - table.integer('is_anonymous').unsigned().notNullable(); - table.string('dm_message_id', 20).nullable().unique(); - table.dateTime('created_at').notNullable().index(); - }); - - await knex.schema.createTableIfNotExists('blocked_users', table => { - table.string('user_id', 20).primary().notNullable(); - table.string('user_name', 128).notNullable(); - table.string('blocked_by', 20).nullable(); - table.dateTime('blocked_at').notNullable(); - }); - - await knex.schema.createTableIfNotExists('snippets', table => { - table.string('trigger', 32).primary().notNullable(); - table.text('body').notNullable(); - table.integer('is_anonymous').unsigned().notNullable(); - table.string('created_by', 20).nullable(); - table.dateTime('created_at').notNullable(); - }); -}; - -exports.down = async function(knex, Promise) { - await knex.schema.dropTableIfExists('thread_messages'); - await knex.schema.dropTableIfExists('threads'); - await knex.schema.dropTableIfExists('blocked_users'); - await knex.schema.dropTableIfExists('snippets'); -}; diff --git a/db/migrations/20180224235946_add_close_at_to_threads.js b/db/migrations/20180224235946_add_close_at_to_threads.js deleted file mode 100644 index dbbb04d..0000000 --- a/db/migrations/20180224235946_add_close_at_to_threads.js +++ /dev/null @@ -1,15 +0,0 @@ -exports.up = async function (knex, Promise) { - await knex.schema.table('threads', table => { - table.dateTime('scheduled_close_at').index().nullable().defaultTo(null).after('channel_id'); - table.string('scheduled_close_id', 20).nullable().defaultTo(null).after('channel_id'); - table.string('scheduled_close_name', 128).nullable().defaultTo(null).after('channel_id'); - }); -}; - -exports.down = async function(knex, Promise) { - await knex.schema.table('threads', table => { - table.dropColumn('scheduled_close_at'); - table.dropColumn('scheduled_close_id'); - table.dropColumn('scheduled_close_name'); - }); -}; diff --git a/db/migrations/20180421161550_add_alert_id_to_threads.js b/db/migrations/20180421161550_add_alert_id_to_threads.js deleted file mode 100644 index 5defc38..0000000 --- a/db/migrations/20180421161550_add_alert_id_to_threads.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = async function (knex, Promise) { - await knex.schema.table('threads', table => { - table.string('alert_id', 20).nullable().defaultTo(null).after('scheduled_close_name'); - }); -}; - -exports.down = async function(knex, Promise) { - await knex.schema.table('threads', table => { - table.dropColumn('alert_id'); - }); -}; diff --git a/db/migrations/20180920224224_remove_is_anonymous_from_snippets.js b/db/migrations/20180920224224_remove_is_anonymous_from_snippets.js deleted file mode 100644 index ac33267..0000000 --- a/db/migrations/20180920224224_remove_is_anonymous_from_snippets.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = async function (knex, Promise) { - await knex.schema.table('snippets', table => { - table.dropColumn('is_anonymous'); - }); -}; - -exports.down = async function(knex, Promise) { - await knex.schema.table('snippets', table => { - table.integer('is_anonymous').unsigned().notNullable(); - }); -}; diff --git a/db/migrations/20190306204728_add_scheduled_close_silent_to_threads.js b/db/migrations/20190306204728_add_scheduled_close_silent_to_threads.js deleted file mode 100644 index e61490d..0000000 --- a/db/migrations/20190306204728_add_scheduled_close_silent_to_threads.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = async function(knex, Promise) { - await knex.schema.table('threads', table => { - table.integer('scheduled_close_silent').nullable().after('scheduled_close_name'); - }); -}; - -exports.down = async function(knex, Promise) { - await knex.schema.table('threads', table => { - table.dropColumn('scheduled_close_silent'); - }); -}; diff --git a/db/migrations/20190306211534_add_scheduled_suspend_to_threads.js b/db/migrations/20190306211534_add_scheduled_suspend_to_threads.js deleted file mode 100644 index a22b5f3..0000000 --- a/db/migrations/20190306211534_add_scheduled_suspend_to_threads.js +++ /dev/null @@ -1,15 +0,0 @@ -exports.up = async function(knex, Promise) { - await knex.schema.table('threads', table => { - table.dateTime('scheduled_suspend_at').index().nullable().defaultTo(null).after('channel_id'); - table.string('scheduled_suspend_id', 20).nullable().defaultTo(null).after('channel_id'); - table.string('scheduled_suspend_name', 128).nullable().defaultTo(null).after('channel_id'); - }); -}; - -exports.down = async function(knex, Promise) { - await knex.schema.table('threads', table => { - table.dropColumn('scheduled_suspend_at'); - table.dropColumn('scheduled_suspend_id'); - table.dropColumn('scheduled_suspend_name'); - }); -}; diff --git a/db/migrations/20190609161116_create_updates_table.js b/db/migrations/20190609161116_create_updates_table.js deleted file mode 100644 index c90e9bd..0000000 --- a/db/migrations/20190609161116_create_updates_table.js +++ /dev/null @@ -1,14 +0,0 @@ -exports.up = async function(knex, Promise) { - if (! await knex.schema.hasTable('updates')) { - await knex.schema.createTable('updates', table => { - table.string('available_version', 16).nullable(); - table.dateTime('last_checked').nullable(); - }); - } -}; - -exports.down = async function(knex, Promise) { - if (await knex.schema.hasTable('updates')) { - await knex.schema.dropTable('updates'); - } -}; diff --git a/db/migrations/20190609193213_add_expires_at_to_blocked_users.js b/db/migrations/20190609193213_add_expires_at_to_blocked_users.js deleted file mode 100644 index ea456a6..0000000 --- a/db/migrations/20190609193213_add_expires_at_to_blocked_users.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.up = async function(knex, Promise) { - await knex.schema.table('blocked_users', table => { - table.dateTime('expires_at').nullable(); - }); -}; - -exports.down = async function(knex, Promise) { - await knex.schema.table('blocked_users', table => { - table.dropColumn('expires_at'); - }); -}; diff --git a/db/migrations/20191206002418_add_number_to_thread_messages.js b/db/migrations/20191206002418_add_number_to_thread_messages.js deleted file mode 100644 index 3564b90..0000000 --- a/db/migrations/20191206002418_add_number_to_thread_messages.js +++ /dev/null @@ -1,19 +0,0 @@ -const Knex = require('knex'); - -/** - * @param {Knex} knex - */ -exports.up = async function(knex) { - await knex.schema.table('thread_messages', table => { - table.integer('message_number').unsigned().nullable(); - }); -}; - -/** - * @param {Knex} knex - */ -exports.down = async function(knex) { - await knex.schema.table('thread_messages', table => { - table.dropColumn('message_number'); - }); -}; diff --git a/db/migrations/20191206011638_add_thread_message_id_to_thread_messages.js b/db/migrations/20191206011638_add_thread_message_id_to_thread_messages.js deleted file mode 100644 index 475c066..0000000 --- a/db/migrations/20191206011638_add_thread_message_id_to_thread_messages.js +++ /dev/null @@ -1,19 +0,0 @@ -const Knex = require('knex'); - -/** - * @param {Knex} knex - */ -exports.up = async function(knex) { - await knex.schema.table('thread_messages', table => { - table.string('inbox_message_id', 20).nullable().unique(); - }); -}; - -/** - * @param {Knex} knex - */ -exports.down = async function(knex) { - await knex.schema.table('thread_messages', table => { - table.dropColumn('inbox_message_id'); - }); -}; diff --git a/db/migrations/20191206180113_add_dm_channel_id_to_thread_messages.js b/db/migrations/20191206180113_add_dm_channel_id_to_thread_messages.js deleted file mode 100644 index 4b0aa6a..0000000 --- a/db/migrations/20191206180113_add_dm_channel_id_to_thread_messages.js +++ /dev/null @@ -1,19 +0,0 @@ -const Knex = require('knex'); - -/** - * @param {Knex} knex - */ -exports.up = async function(knex) { - await knex.schema.table('thread_messages', table => { - table.string('dm_channel_id', 20).nullable(); - }); -}; - -/** - * @param {Knex} knex - */ -exports.down = async function(knex) { - await knex.schema.table('thread_messages', table => { - table.dropColumn('dm_channel_id'); - }); -}; diff --git a/docs/commands.md b/docs/commands.md index ae2037e..6b7a2d2 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -13,7 +13,7 @@ Send a reply to the user. **Example:** `!r How can I help you?` -To reply automatically without using `!reply`, [enable `alwaysReply` in bot settings](configuration.md). +To reply automatically without using `!reply`, [turn on `alwaysReply` in bot settings](configuration.md). ### `!anonreply ` / `!ar ` Send an anonymous reply to the user. Anonymous replies only show the moderator's role in the reply. @@ -28,6 +28,9 @@ Close the Modmail thread after a timer. Sending a message to the user or receivi **Example:** `!close 15m` +### `!close -s` / `!close -s