From 6379ffc1b1e3202cbae50cde355bc1ddb0ab6f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Otterstr=C3=B6m?= <35617441+MarcusOtter@users.noreply.github.com> Date: Mon, 3 Jan 2022 06:06:20 +0100 Subject: [PATCH] v1.0 (#22) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Sanetize config * Invalidate cached commands on startup * Make config settable and gettable stored in memory * Improve set config error message * Upgrade packages * Update packages and start implementing messages to config * Start using auto-populated message context * Work on new configuration command * Fully add config typing * Remove manual setting of auto-archive duration (can be done in discord ui) * Transfer work between computers * Add message configuration with temp outputs * Implement auto-threading configuration * Start implementing manual configuration * Add more config channel creation logic * Fix bugs and implement permissions * Refactor and start detecting changes to post in manual config channel * Remove manual config For now! * Use dotenv instead of overrideConfig * Update readme for dotenv * Implement permanent config storage Needs more testing before it's complete * Minor bug fixes * Update deployment commands * Add logos * Make README pretty Found this neat little table align trick 😮 * Catch errors on handlers * Update discord logo * Minor README styling changes * Remove unnecessary dot * Minor functionality tweaks * Add config reset command * Make README more responsive * Remove image link * Add /title command to thread create message * Remove bloat --- .gitignore | 3 +- README.md | 61 +++--- branding/logo-128x128.png | Bin 0 -> 6818 bytes branding/logo-64x64.png | Bin 0 -> 3375 bytes branding/logo-full.PNG | Bin 0 -> 119965 bytes package-lock.json | 286 +++++++++++++++-------------- package.json | 15 +- scripts/deploy-commands.js | 53 ++++-- src/commands/close.ts | 30 +-- src/commands/configure.ts | 160 ++++++++++++++++ src/commands/help.ts | 11 +- src/commands/title.ts | 36 ++-- src/config.json | 32 ++-- src/handlers/commandHandler.ts | 12 +- src/handlers/interactionHandler.ts | 15 +- src/handlers/messageHandler.ts | 37 ++-- src/helpers/configHelpers.ts | 115 +++++++++++- src/helpers/fileHelpers.ts | 7 + src/helpers/messageHelpers.ts | 93 +++++++++- src/helpers/permissionHelpers.ts | 24 ++- src/index.ts | 22 ++- src/types/messageContext.ts | 13 ++ src/types/needleConfig.ts | 20 ++ 23 files changed, 757 insertions(+), 288 deletions(-) create mode 100644 branding/logo-128x128.png create mode 100644 branding/logo-64x64.png create mode 100644 branding/logo-full.PNG create mode 100644 src/commands/configure.ts create mode 100644 src/helpers/fileHelpers.ts create mode 100644 src/types/messageContext.ts create mode 100644 src/types/needleConfig.ts diff --git a/.gitignore b/.gitignore index e5cb576d..bd161a0d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules/ dist/ +configs/ -overrideConfig.json +.env diff --git a/README.md b/README.md index c40d9357..c1889707 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,43 @@ -# Needle -Needle is a [Discord](https://discord.com/) bot that helps you manage your [Discord threads](https://support.discord.com/hc/en-us/articles/4403205878423-Threads-FAQ). -## Features -- Automatically create new threads for every message in certain channels -- Let thread owners close the automatically created threads with `/close` -- Let thread owners change the title of the automatically created thread with `/title` -- More to come :wink: Check out open [issues](https://github.com/MarcusOtter/discord-needle/issues)! -## Running the bot +
+

+ Needle + + + +

+ + Needle is a Discord bot that helps you manage your Discord threads 🪡 +

+ + + + + + +
Website ✨Invite Needle 🪡Get support 💬
+
+ +## Self-hosting 1. Clone the repository -2. Edit the `src/config.json` with API token and the IDs of the channels you want to thread every message in: - ```json - { - "discordApiToken": "INSERT TOKEN", - "threadChannels": [ - "CHANNEL ID 1", - "CHANNEL ID 2", - ] - } - ``` +2. Create a file named `.env` in the root directory and insert your Discord API token: + ```bash + DISCORD_API_TOKEN=abcd1234... + ``` 3. Run `npm install` -4. Make sure the bot has the required permissions in Discord. They are: - - `USE_PUBLIC_THREADS` - - `SEND_MESSAGES_IN_THREADS` - - `READ_MESSAGE_HISTORY` +4. Make sure the bot has the required permissions in Discord: + - [x] View channels + - [x] Send messages + - [x] Send messages in threads + - [x] Create public threads + - [x] Read message history 5. Run `npm start` -6. Done! :tada: +6. Deploy! :tada: + +## Contributing +Coming soon :tm: + +[Join the Discord](https://needle.gg/chat) if interested! diff --git a/branding/logo-128x128.png b/branding/logo-128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..1c192207069ead336675b7e898caec348cb7eb15 GIT binary patch literal 6818 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 literal 0 HcmV?d00001 diff --git a/branding/logo-64x64.png b/branding/logo-64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..e82e4c8bb40dda80e911a3d61ed4edd39e50c623 GIT binary patch literal 3375 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 TI^jO}g9p*p)YB+ehll_h38u-FNTXec$f? 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ⅅO4FNCQsT=A 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%0D`L^%9J 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

`c%|T!1cbO0u91j!*h> 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 literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json index 9afef35a..7cc7b512 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,11 @@ "version": "1.0.0", "license": "GPL-3.0", "dependencies": { - "@discordjs/builders": "^0.6.0", + "@discordjs/builders": "^0.8.2", "@discordjs/rest": "^0.1.0-canary.0", - "discord-api-types": "^0.23.1", - "discord.js": "^13.1.0" + "discord-api-types": "^0.24.0", + "discord.js": "^13.3.1", + "dotenv": "^10.0.0" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^4.29.2", @@ -129,35 +130,28 @@ } }, "node_modules/@discordjs/builders": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.6.0.tgz", - "integrity": "sha512-mH3Gx61LKk2CD05laCI9K5wp+a3NyASHDUGx83DGJFkqJlRlSV5WMJNY6RS37A5SjqDtGMF4wVR9jzFaqShe6Q==", + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.8.2.tgz", + "integrity": "sha512-/YRd11SrcluqXkKppq/FAVzLIPRVlIVmc6X8ZklspzMIHDtJ+A4W37D43SHvLdH//+NnK+SHW/WeOF4Ts54PeQ==", "dependencies": { - "@sindresorhus/is": "^4.0.1", - "discord-api-types": "^0.22.0", + "@sindresorhus/is": "^4.2.0", + "discord-api-types": "^0.24.0", "ow": "^0.27.0", "ts-mixer": "^6.0.0", "tslib": "^2.3.1" }, "engines": { - "node": ">=14.0.0", + "node": ">=16.0.0", "npm": ">=7.0.0" } }, - "node_modules/@discordjs/builders/node_modules/discord-api-types": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.22.0.tgz", - "integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg==", - "engines": { - "node": ">=12" - } - }, "node_modules/@discordjs/collection": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.2.1.tgz", - "integrity": "sha512-vhxqzzM8gkomw0TYRF3tgx7SwElzUlXT/Aa41O7mOcyN6wIJfj5JmDWaO5XGKsGSsNx7F3i5oIlrucCCWV1Nog==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.3.2.tgz", + "integrity": "sha512-dMjLl60b2DMqObbH1MQZKePgWhsNe49XkKBZ0W5Acl5uVV43SN414i2QfZwRI7dXAqIn8pEWD2+XXQFn9KWxqg==", "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0", + "npm": ">=7.0.0" } }, "node_modules/@discordjs/form-data": { @@ -281,12 +275,12 @@ } }, "node_modules/@sapphire/async-queue": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.4.tgz", - "integrity": "sha512-fFrlF/uWpGOX5djw5Mu2Hnnrunao75WGey0sP0J3jnhmrJ5TAPzHYOmytD5iN/+pMxS+f+u/gezqHa9tPhRHEA==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.9.tgz", + "integrity": "sha512-CbXaGwwlEMq+l1TRu01FJCvySJ1CEFKFclHT48nIfNeZXaAAmmwwy7scUKmYHPUa3GhoMp6Qr1B3eAJux6XgOQ==", "engines": { - "node": ">=14", - "npm": ">=6" + "node": ">=v14.0.0", + "npm": ">=7.0.0" } }, "node_modules/@sapphire/snowflake": { @@ -300,9 +294,9 @@ } }, "node_modules/@sindresorhus/is": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", - "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.2.0.tgz", + "integrity": "sha512-VkE3KLBmJwcCaVARtQpfuKcKv8gcBmUubrfHGF84dXuuW6jgsRYxPtzcIhPyK9WAPpRt2/xY6zkD9MnRaJzSyw==", "engines": { "node": ">=10" }, @@ -317,14 +311,36 @@ "dev": true }, "node_modules/@types/node": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.0.tgz", - "integrity": "sha512-e66BrnjWQ3BRBZ2+iA5e85fcH9GLNe4S0n1H0T3OalK2sXg5XWEFTO4xvmGrYQ3edy+q6fdOh5t0/HOY8OAqBg==" + "version": "16.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz", + "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==" + }, + "node_modules/@types/node-fetch": { + "version": "2.5.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz", + "integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==", + "dependencies": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, + "node_modules/@types/node-fetch/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } }, "node_modules/@types/ws": { - "version": "7.4.7", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", - "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.2.0.tgz", + "integrity": "sha512-cyeefcUCgJlEk+hk2h3N+MqKKsPViQgF5boi9TTHSK+PoR9KWBb/C5ccPcDyAqgsbAYHTwulch725DV84+pSpg==", "dependencies": { "@types/node": "*" } @@ -561,9 +577,9 @@ } }, "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { "node": ">=8" @@ -761,56 +777,33 @@ } }, "node_modules/discord-api-types": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.23.1.tgz", - "integrity": "sha512-igWmn+45mzXRWNEPU25I/pr8MwxHb767wAr51oy3VRLRcTlp5ADBbrBR0lq3SA1Rfw3MtM4TQu1xo3kxscfVdQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.24.0.tgz", + "integrity": "sha512-X0uA2a92cRjowUEXpLZIHWl4jiX1NsUpDhcEOpa1/hpO1vkaokgZ8kkPtPih9hHth5UVQ3mHBu/PpB4qjyfJ4A==", "engines": { "node": ">=12" } }, "node_modules/discord.js": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.1.0.tgz", - "integrity": "sha512-gxO4CXKdHpqA+WKG+f5RNnd3srTDj5uFJHgOathksDE90YNq/Qijkd2WlMgTTMS6AJoEnHxI7G9eDQHCuZ+xDA==", + "version": "13.3.1", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.3.1.tgz", + "integrity": "sha512-zn4G8tL5+tMV00+0aSsVYNYcIfMSdT2g0nudKny+Ikd+XKv7m6bqI7n3Vji0GIRqXDr5ArPaw+iYFM2I1Iw3vg==", "dependencies": { - "@discordjs/builders": "^0.5.0", - "@discordjs/collection": "^0.2.1", + "@discordjs/builders": "^0.8.1", + "@discordjs/collection": "^0.3.2", "@discordjs/form-data": "^3.0.1", - "@sapphire/async-queue": "^1.1.4", - "@types/ws": "^7.4.7", - "discord-api-types": "^0.22.0", + "@sapphire/async-queue": "^1.1.8", + "@types/node-fetch": "^2.5.12", + "@types/ws": "^8.2.0", + "discord-api-types": "^0.24.0", "node-fetch": "^2.6.1", - "ws": "^7.5.1" + "ws": "^8.2.3" }, "engines": { "node": ">=16.6.0", "npm": ">=7.0.0" } }, - "node_modules/discord.js/node_modules/@discordjs/builders": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.5.0.tgz", - "integrity": "sha512-HP5y4Rqw68o61Qv4qM5tVmDbWi4mdTFftqIOGRo33SNPpLJ1Ga3KEIR2ibKofkmsoQhEpLmopD1AZDs3cKpHuw==", - "dependencies": { - "@sindresorhus/is": "^4.0.1", - "discord-api-types": "^0.22.0", - "ow": "^0.27.0", - "ts-mixer": "^6.0.0", - "tslib": "^2.3.0" - }, - "engines": { - "node": ">=14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/discord.js/node_modules/discord-api-types": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.22.0.tgz", - "integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg==", - "engines": { - "node": ">=12" - } - }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -837,6 +830,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -2054,11 +2055,11 @@ "dev": true }, "node_modules/ws": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", - "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", "engines": { - "node": ">=8.3.0" + "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", @@ -2166,28 +2167,21 @@ } }, "@discordjs/builders": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.6.0.tgz", - "integrity": "sha512-mH3Gx61LKk2CD05laCI9K5wp+a3NyASHDUGx83DGJFkqJlRlSV5WMJNY6RS37A5SjqDtGMF4wVR9jzFaqShe6Q==", + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.8.2.tgz", + "integrity": "sha512-/YRd11SrcluqXkKppq/FAVzLIPRVlIVmc6X8ZklspzMIHDtJ+A4W37D43SHvLdH//+NnK+SHW/WeOF4Ts54PeQ==", "requires": { - "@sindresorhus/is": "^4.0.1", - "discord-api-types": "^0.22.0", + "@sindresorhus/is": "^4.2.0", + "discord-api-types": "^0.24.0", "ow": "^0.27.0", "ts-mixer": "^6.0.0", "tslib": "^2.3.1" - }, - "dependencies": { - "discord-api-types": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.22.0.tgz", - "integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg==" - } } }, "@discordjs/collection": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.2.1.tgz", - "integrity": "sha512-vhxqzzM8gkomw0TYRF3tgx7SwElzUlXT/Aa41O7mOcyN6wIJfj5JmDWaO5XGKsGSsNx7F3i5oIlrucCCWV1Nog==" + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.3.2.tgz", + "integrity": "sha512-dMjLl60b2DMqObbH1MQZKePgWhsNe49XkKBZ0W5Acl5uVV43SN414i2QfZwRI7dXAqIn8pEWD2+XXQFn9KWxqg==" }, "@discordjs/form-data": { "version": "3.0.1", @@ -2287,9 +2281,9 @@ } }, "@sapphire/async-queue": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.4.tgz", - "integrity": "sha512-fFrlF/uWpGOX5djw5Mu2Hnnrunao75WGey0sP0J3jnhmrJ5TAPzHYOmytD5iN/+pMxS+f+u/gezqHa9tPhRHEA==" + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.9.tgz", + "integrity": "sha512-CbXaGwwlEMq+l1TRu01FJCvySJ1CEFKFclHT48nIfNeZXaAAmmwwy7scUKmYHPUa3GhoMp6Qr1B3eAJux6XgOQ==" }, "@sapphire/snowflake": { "version": "1.3.6", @@ -2297,9 +2291,9 @@ "integrity": "sha512-QnzuLp+p9D7agynVub/zqlDVriDza9y3STArBhNiNBUgIX8+GL5FpQxstRfw1jDr5jkZUjcuKYAHxjIuXKdJAg==" }, "@sindresorhus/is": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", - "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.2.0.tgz", + "integrity": "sha512-VkE3KLBmJwcCaVARtQpfuKcKv8gcBmUubrfHGF84dXuuW6jgsRYxPtzcIhPyK9WAPpRt2/xY6zkD9MnRaJzSyw==" }, "@types/json-schema": { "version": "7.0.9", @@ -2308,14 +2302,35 @@ "dev": true }, "@types/node": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.0.tgz", - "integrity": "sha512-e66BrnjWQ3BRBZ2+iA5e85fcH9GLNe4S0n1H0T3OalK2sXg5XWEFTO4xvmGrYQ3edy+q6fdOh5t0/HOY8OAqBg==" + "version": "16.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz", + "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==" + }, + "@types/node-fetch": { + "version": "2.5.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz", + "integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==", + "requires": { + "@types/node": "*", + "form-data": "^3.0.0" + }, + "dependencies": { + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } }, "@types/ws": { - "version": "7.4.7", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", - "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.2.0.tgz", + "integrity": "sha512-cyeefcUCgJlEk+hk2h3N+MqKKsPViQgF5boi9TTHSK+PoR9KWBb/C5ccPcDyAqgsbAYHTwulch725DV84+pSpg==", "requires": { "@types/node": "*" } @@ -2453,9 +2468,9 @@ "dev": true }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { @@ -2603,42 +2618,24 @@ } }, "discord-api-types": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.23.1.tgz", - "integrity": "sha512-igWmn+45mzXRWNEPU25I/pr8MwxHb767wAr51oy3VRLRcTlp5ADBbrBR0lq3SA1Rfw3MtM4TQu1xo3kxscfVdQ==" + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.24.0.tgz", + "integrity": "sha512-X0uA2a92cRjowUEXpLZIHWl4jiX1NsUpDhcEOpa1/hpO1vkaokgZ8kkPtPih9hHth5UVQ3mHBu/PpB4qjyfJ4A==" }, "discord.js": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.1.0.tgz", - "integrity": "sha512-gxO4CXKdHpqA+WKG+f5RNnd3srTDj5uFJHgOathksDE90YNq/Qijkd2WlMgTTMS6AJoEnHxI7G9eDQHCuZ+xDA==", + "version": "13.3.1", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.3.1.tgz", + "integrity": "sha512-zn4G8tL5+tMV00+0aSsVYNYcIfMSdT2g0nudKny+Ikd+XKv7m6bqI7n3Vji0GIRqXDr5ArPaw+iYFM2I1Iw3vg==", "requires": { - "@discordjs/builders": "^0.5.0", - "@discordjs/collection": "^0.2.1", + "@discordjs/builders": "^0.8.1", + "@discordjs/collection": "^0.3.2", "@discordjs/form-data": "^3.0.1", - "@sapphire/async-queue": "^1.1.4", - "@types/ws": "^7.4.7", - "discord-api-types": "^0.22.0", + "@sapphire/async-queue": "^1.1.8", + "@types/node-fetch": "^2.5.12", + "@types/ws": "^8.2.0", + "discord-api-types": "^0.24.0", "node-fetch": "^2.6.1", - "ws": "^7.5.1" - }, - "dependencies": { - "@discordjs/builders": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.5.0.tgz", - "integrity": "sha512-HP5y4Rqw68o61Qv4qM5tVmDbWi4mdTFftqIOGRo33SNPpLJ1Ga3KEIR2ibKofkmsoQhEpLmopD1AZDs3cKpHuw==", - "requires": { - "@sindresorhus/is": "^4.0.1", - "discord-api-types": "^0.22.0", - "ow": "^0.27.0", - "ts-mixer": "^6.0.0", - "tslib": "^2.3.0" - } - }, - "discord-api-types": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.22.0.tgz", - "integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg==" - } + "ws": "^8.2.3" } }, "doctrine": { @@ -2658,6 +2655,11 @@ "is-obj": "^2.0.0" } }, + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -3556,9 +3558,9 @@ "dev": true }, "ws": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", - "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", "requires": {} }, "yallist": { diff --git a/package.json b/package.json index 29de236d..e297bc11 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,11 @@ "main": "src/index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "build": "rd /s /q dist & tsc && node ./scripts/deploy-commands.js", - "prestart": "npm run build", - "start": "node ./dist/index.js" + "build": "rd /s /q dist & tsc", + "start": "npm run build && node ./dist/index.js", + "dev": "npm run build && node ./scripts/deploy-commands.js && node ./dist/index.js", + "undeploy": "npm run build && node ./scripts/deploy-commands.js --undeploy", + "deploy": "npm run undeploy && node ./scripts/deploy-commands.js --global" }, "repository": { "type": "git", @@ -20,10 +22,11 @@ }, "homepage": "https://github.com/MarcusOtter/discord-needle", "dependencies": { - "@discordjs/builders": "^0.6.0", + "@discordjs/builders": "^0.8.2", "@discordjs/rest": "^0.1.0-canary.0", - "discord-api-types": "^0.23.1", - "discord.js": "^13.1.0" + "discord-api-types": "^0.24.0", + "discord.js": "^13.3.1", + "dotenv": "^10.0.0" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^4.29.2", diff --git a/scripts/deploy-commands.js b/scripts/deploy-commands.js index a093d9c3..eee28ee5 100644 --- a/scripts/deploy-commands.js +++ b/scripts/deploy-commands.js @@ -1,40 +1,57 @@ /* eslint-disable @typescript-eslint/no-var-requires */ // IMPORTANT: You need to `tsc` before running this script. -// TODO: Make this a separate script when commands are more stable (don't try to run it on npm start) +require("dotenv").config(); const { REST } = require("@discordjs/rest"); const { Routes } = require("discord-api-types/v9"); const { getOrLoadAllCommands } = require("../dist/handlers/commandHandler"); -const { getConfig } = require("../dist/helpers/configHelpers"); +const { getApiToken, getGuildId, getClientId } = require("../dist/helpers/configHelpers"); -const CONFIG = getConfig(); -if (!CONFIG) { return; } -if (!CONFIG.dev) { return; } -if (!CONFIG.dev.clientId || CONFIG.dev.clientId === "") { return; } -if (!CONFIG.dev.guildId || CONFIG.dev.guildId === "") { return; } +const API_TOKEN = getApiToken(); +const CLIENT_ID = getClientId(); +const GUILD_ID = getGuildId(); -const rest = new REST({ version: "9" }).setToken(CONFIG.discordApiToken); +if (!API_TOKEN || !CLIENT_ID || !GUILD_ID) { + console.log("API_TOKEN, CLIENT_ID, or GUILD_ID was missing from the .env file: aborting command deployment"); + console.log("Hint: If you just want to start the bot without developing commands, type \"npm start\" instead\n"); + return; +} +const route = process.argv.some(x => x === "--global") + ? Routes.applicationCommands(CLIENT_ID) + : Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID); + +const rest = new REST({ version: "9" }).setToken(API_TOKEN); (async () => { - const allNeedleCommands = await getOrLoadAllCommands(); - const allSlashCommandBuilders = []; - for (const command of allNeedleCommands) { - const builder = await command.getSlashCommandBuilder(); - allSlashCommandBuilders.push(builder); - } + const builders = await getSlashCommandBuilders(); try { - console.log(`Started deploying ${allSlashCommandBuilders.length} application commands.`); + console.log(`Started deploying ${builders.length} application commands.`); await rest.put( - Routes.applicationGuildCommands(CONFIG.dev.clientId, CONFIG.dev.guildId), - { body: allSlashCommandBuilders }, + route, + { body: builders }, ); - console.log("Successfully deployed application commands."); + console.log("Successfully deployed application commands.\n"); } catch (error) { console.error(error); } })(); +async function getSlashCommandBuilders() { + if (process.argv.some(x => x === "--undeploy")) { + console.log("Undeploying guild commands"); + return []; + } + + const allNeedleCommands = await getOrLoadAllCommands(); + const allSlashCommandBuilders = []; + for (const command of allNeedleCommands) { + const builder = await command.getSlashCommandBuilder(); + allSlashCommandBuilders.push(builder); + } + + return allSlashCommandBuilders; +} diff --git a/src/commands/close.ts b/src/commands/close.ts index 1ab3b25c..c063ab4b 100644 --- a/src/commands/close.ts +++ b/src/commands/close.ts @@ -1,12 +1,12 @@ import { SlashCommandBuilder } from "@discordjs/builders"; import { CommandInteraction, GuildMember, MessageComponentInteraction, Permissions } from "discord.js"; -import { ephemeralReply, getThreadStartMessage } from "../helpers/messageHelpers"; +import { interactionReply, getThreadStartMessage, getMessage } from "../helpers/messageHelpers"; import { NeedleCommand } from "../types/needleCommand"; export const command: NeedleCommand = { name: "close", shortHelpDescription: "Closes a thread by setting the auto-archive duration to 1 hour", - longHelpDescription: "The close command lets thread owners set the auto-archive duration to 1 hour.\n\nWhen using auto-archive, the thread will automatically be archived when there have been no new messages in the thread for one hour. This can be undone by a server moderator by manually changing the auto-archive duration back to what it was previously, using Discord's own interface.", + longHelpDescription: "The close command sets the auto-archive duration to 1 hour in a thread.\n\nWhen using auto-archive, the thread will automatically be archived when there have been no new messages in the thread for one hour. This can be undone by a server moderator by manually changing the auto-archive duration back to what it was previously, using Discord's own interface.", async getSlashCommandBuilder() { return new SlashCommandBuilder() @@ -18,29 +18,35 @@ export const command: NeedleCommand = { async execute(interaction: CommandInteraction | MessageComponentInteraction): Promise { const member = interaction.member; if (!(member instanceof GuildMember)) { - return ephemeralReply(interaction, "An unexpected error occurred."); + return interactionReply(interaction, getMessage("ERR_UNKNOWN")); } const channel = interaction.channel; if (!channel?.isThread()) { - return ephemeralReply(interaction, "You can only use this command inside a thread."); + return interactionReply(interaction, getMessage("ERR_ONLY_IN_THREAD")); } - const parentMessage = await getThreadStartMessage(channel); - if (!parentMessage) { - return ephemeralReply(interaction, "Could not find the start message of this thread."); + if (channel.autoArchiveDuration === 60) { + return interactionReply(interaction, getMessage("ERR_NO_EFFECT")); } const hasChangeTitlePermissions = member.permissionsIn(channel).has(Permissions.FLAGS.MANAGE_THREADS, true); - if (!hasChangeTitlePermissions && parentMessage.author !== interaction.user) { - return ephemeralReply(interaction, "You need to be the thread owner to close the thread."); + if (hasChangeTitlePermissions) { + await channel.setAutoArchiveDuration(60); + await interactionReply(interaction, getMessage("SUCCESS_THREAD_ARCHIVE"), false); + return; } - if (channel.autoArchiveDuration === 60) { - return ephemeralReply(interaction, "This server already has the auto-archive duration set to one hour."); + const parentMessage = await getThreadStartMessage(channel); + if (!parentMessage) { + return interactionReply(interaction, getMessage("ERR_THREAD_MESSAGE_MISSING")); + } + + if (parentMessage.author !== interaction.user) { + return interactionReply(interaction, getMessage("ERR_ONLY_THREAD_OWNER")); } await channel.setAutoArchiveDuration(60); - await interaction.reply(`**This thread will be archived soon** :card_box:\n\nAs requested by <@${member.user.id}>, this thread will automatically be archived when one hour passes without any new messages.\n\nThe thread's content will still be searchable with Discord's search function, and anyone will be able to un-archive it at any point in the future by simply sending a message in the thread again.\n\nA server moderator can undo this action by manually setting the auto-archive duration back to what it was previously.`); + await interactionReply(interaction, getMessage("SUCCESS_THREAD_ARCHIVE"), false); }, }; diff --git a/src/commands/configure.ts b/src/commands/configure.ts new file mode 100644 index 00000000..a7261e73 --- /dev/null +++ b/src/commands/configure.ts @@ -0,0 +1,160 @@ +import { SlashCommandBuilder } from "@discordjs/builders"; +import { ChannelType } from "discord-api-types"; +import { CommandInteraction, GuildMember, GuildTextBasedChannel, Permissions } from "discord.js"; +import { disableAutothreading, enableAutothreading, getConfig, resetConfigToDefault, setMessage } from "../helpers/configHelpers"; +import { interactionReply, getMessage, MessageKey, isAutoThreadChannel, addMessageContext } from "../helpers/messageHelpers"; +import { NeedleCommand } from "../types/needleCommand"; +import { memberIsModerator } from "../helpers/permissionHelpers"; + +// Note: +// The important messages of these commands should not be configurable +// (prevents user made soft-locks where it's hard to figure out how to fix it) + +export const command: NeedleCommand = { + name: "configure", + shortHelpDescription: "Modify the configuration of Needle", + + async getSlashCommandBuilder() { + return new SlashCommandBuilder() + .setName("configure") + .setDescription("Modify the configuration of Needle") + .addSubcommand(subcommand => { + return subcommand + .setName("message") + .setDescription("Modify the content of a message that Needle replies with when a certain action happens") + .addStringOption(option => { + const opt = option + .setName("key") + .setDescription("The key of the message") + .setRequired(true); + + for(const messageKey of Object.keys(getConfig().messages ?? [])) { + opt.addChoice(messageKey, messageKey); + } + + return opt; + }) + .addStringOption(option => { + return option + .setName("value") + .setDescription("The new message for the selected key (shows the current value of this message key if left blank)") + .setRequired(false); + }); + }) + .addSubcommand(subcommand => { + return subcommand + .setName("default") + .setDescription("Reset the server's custom Needle configuration to the default"); + }) + .addSubcommand(subcommand => { + return subcommand + .setName("autothreading") + .setDescription("Enable or disable automatic creation of threads on every new message in a channel") + .addChannelOption(option => { + return option + .setName("channel") + .setDescription("The channel to enable/disable automatic threading in") + .addChannelType(ChannelType.GuildText) + .addChannelType(ChannelType.GuildNews) + .setRequired(true); + }) + .addBooleanOption(option => { + return option + .setName("enabled") + .setDescription("Whether or not threads should be automatically created from new messages in the selected channel") + .setRequired(true); + }) + .addStringOption(option => { + return option + .setName("custom-message") + .setDescription("The message to send when a thread is created (uses the message SUCCESS_THREAD_CREATE if left blank)") + .setRequired(false); + }); + }) + .toJSON(); + }, + + async execute(interaction: CommandInteraction): Promise { + if (!interaction.guildId || !interaction.guild) { + return interactionReply(interaction, getMessage("ERR_ONLY_IN_SERVER")); + } + + if (!memberIsModerator(interaction.member as GuildMember)) { + return interactionReply(interaction, getMessage("ERR_INSUFFICIENT_PERMS")); + } + + if (interaction.options.getSubcommand() === "default") { + const success = resetConfigToDefault(interaction.guild.id); + return interactionReply(interaction, success + ? "Successfully reset the Needle configuration to the default." + : getMessage("ERR_NO_EFFECT"), !success); + } + + if (interaction.options.getSubcommand() === "message") { + return configureMessage(interaction); + } + + if (interaction.options.getSubcommand() === "autothreading") { + return configureAutothreading(interaction); + } + + return interactionReply(interaction, getMessage("ERR_UNKNOWN")); + }, +}; + +function configureMessage(interaction: CommandInteraction): Promise { + const key = interaction.options.getString("key") as MessageKey; + const value = interaction.options.getString("value"); + + if (!interaction.guild) { + return interactionReply(interaction, getMessage("ERR_ONLY_IN_SERVER")); + } + + if (!value || value.length === 0) { + return interactionReply(interaction, `**${key}** message:\n\n>>> ${getMessage(key, false)}`); + } + + const oldValue = getMessage(key, false); + return setMessage(interaction.guild, key, value) + ? interactionReply(interaction, `Changed **${key}**\n\nOld message:\n> ${oldValue?.replaceAll("\n", "\n> ")}\n\nNew message:\n>>> ${value}`, false) + : interactionReply(interaction, getMessage("ERR_UNKNOWN")); +} + +async function configureAutothreading(interaction: CommandInteraction): Promise { + const channel = interaction.options.getChannel("channel") as GuildTextBasedChannel; + const enabled = interaction.options.getBoolean("enabled"); + const customMessage = interaction.options.getString("custom-message") ?? ""; + + if (!interaction.guild) { + return interactionReply(interaction, getMessage("ERR_ONLY_IN_SERVER")); + } + + if (!channel || enabled == null) { + return interactionReply(interaction, getMessage("ERR_PARAMETER_MISSING")); + } + + const clientUser = interaction.client.user; + if (!clientUser) return interactionReply(interaction, getMessage("ERR_UNKNOWN")); + + const botMember = await interaction.guild.members.fetch(clientUser); + if (!botMember.permissionsIn(channel.id).has(Permissions.FLAGS.VIEW_CHANNEL)) { + addMessageContext({ channel: channel }); + return interactionReply(interaction, getMessage("ERR_CHANNEL_VISIBILITY")); + } + + if (enabled) { + const success = enableAutothreading(interaction.guild, channel.id, customMessage); + return success + ? interactionReply(interaction, `Updated auto-threading settings for <#${channel.id}>`, false) + : interactionReply(interaction, getMessage("ERR_UNKNOWN")); + } + + if (!isAutoThreadChannel(channel.id, interaction.guildId)) { + return interactionReply(interaction, getMessage("ERR_NO_EFFECT")); + } + + const success = disableAutothreading(interaction.guild, channel.id); + return success + ? interactionReply(interaction, `Removed auto-threading in <#${channel.id}>`, false) + : interactionReply(interaction, getMessage("ERR_UNKNOWN")); +} diff --git a/src/commands/help.ts b/src/commands/help.ts index 6565a101..e850ad6e 100644 --- a/src/commands/help.ts +++ b/src/commands/help.ts @@ -1,6 +1,6 @@ import { SlashCommandBuilder } from "@discordjs/builders"; import { CommandInteraction, MessageActionRow, MessageEmbed } from "discord.js"; -import { APIApplicationCommandOption } from "discord.js/node_modules/discord-api-types"; +import { APIApplicationCommandOption } from "discord-api-types"; import { getCommand, getOrLoadAllCommands } from "../handlers/commandHandler"; import { getBugReportButton, getDiscordInviteButton, getFeatureRequestButton } from "../helpers/messageHelpers"; import { NeedleCommand } from "../types/needleCommand"; @@ -38,7 +38,6 @@ export const command: NeedleCommand = { ephemeral: true, }); } - }, }; @@ -49,7 +48,7 @@ async function getCommandDetailsEmbed(commandName: string): Promise { - const embed = new MessageEmbed().setTitle("Needle Commands 🪡"); // :sewing_needle: + const embed = new MessageEmbed().setTitle("🪡 Needle Commands"); // :sewing_needle: const commands = await getOrLoadAllCommands(); for (const cmd of commands) { // Help command gets special treatment @@ -83,6 +82,8 @@ async function getAllCommandsEmbed(): Promise { async function getCommandOptionString(cmd: NeedleCommand): Promise { const commandInfo = await cmd.getSlashCommandBuilder(); + if (!commandInfo.options) { return ""; } + let output = ""; for (const option of commandInfo.options) { output += ` \`${option.name}${option.required ? "" : "?"}\``; @@ -90,7 +91,7 @@ async function getCommandOptionString(cmd: NeedleCommand): Promise { return output; } -async function getCommandOptions(cmd: NeedleCommand): Promise { +async function getCommandOptions(cmd: NeedleCommand): Promise { const commandInfo = await cmd.getSlashCommandBuilder(); return commandInfo.options; } diff --git a/src/commands/title.ts b/src/commands/title.ts index e151248c..6bb3183b 100644 --- a/src/commands/title.ts +++ b/src/commands/title.ts @@ -1,12 +1,12 @@ import { SlashCommandBuilder } from "@discordjs/builders"; import { CommandInteraction, GuildMember, Permissions } from "discord.js"; -import { ephemeralReply, getThreadStartMessage } from "../helpers/messageHelpers"; +import { interactionReply, getThreadStartMessage, getMessage } from "../helpers/messageHelpers"; import { NeedleCommand } from "../types/needleCommand"; export const command: NeedleCommand = { name: "title", shortHelpDescription: "Sets the title of a thread to `value`", - longHelpDescription: "The title command lets thread owners to change the name of a thread.", + longHelpDescription: "The title command changes the title of a thread.", async getSlashCommandBuilder() { return new SlashCommandBuilder() @@ -24,30 +24,40 @@ export const command: NeedleCommand = { async execute(interaction: CommandInteraction): Promise { const member = interaction.member; if (!(member instanceof GuildMember)) { - return ephemeralReply(interaction, "An unexpected error occurred."); + return interactionReply(interaction, getMessage("ERR_UNKNOWN")); } const channel = interaction.channel; if (!channel?.isThread()) { - return ephemeralReply(interaction, "You can only use this command inside a thread."); + return interactionReply(interaction, getMessage("ERR_ONLY_IN_THREAD")); } - const parentMessage = await getThreadStartMessage(channel); - if (!parentMessage) { - return ephemeralReply(interaction, "Could not find the start message of this thread."); + const newThreadName = interaction.options.getString("value"); + if (!newThreadName) { + return interactionReply(interaction, getMessage("ERR_PARAMETER_MISSING")); + } + + const oldThreadName = channel.name; + + if (oldThreadName === newThreadName) { + return interactionReply(interaction, getMessage("ERR_NO_EFFECT")); } const hasChangeTitlePermissions = member.permissionsIn(channel).has(Permissions.FLAGS.MANAGE_THREADS, true); - if (!hasChangeTitlePermissions && parentMessage.author !== interaction.user) { - return ephemeralReply(interaction, "You need to be the thread owner to change the title."); + if (hasChangeTitlePermissions) { + await channel.setName(newThreadName, `Changed by ${member.user.tag} (${member.id})`); + await interaction.reply(`Successfully changed title from \`${oldThreadName}\` to \`${newThreadName}\`.`); + return; } - const newThreadName = interaction.options.getString("value"); - if (!newThreadName) { - return ephemeralReply(interaction, "You need to provide a new thread name when writing the command"); + const parentMessage = await getThreadStartMessage(channel); + if (!parentMessage) { + return interactionReply(interaction, getMessage("ERR_THREAD_MESSAGE_MISSING")); } - const oldThreadName = channel.name; + if (parentMessage.author !== interaction.user) { + return interactionReply(interaction, getMessage("ERR_ONLY_THREAD_OWNER")); + } // Current rate limit is 2 renames per thread per 10 minutes (2021-09-17). // If that rate limit is hit, it will wait here until it is able to rename the thread. diff --git a/src/config.json b/src/config.json index 74be215d..e41ac972 100644 --- a/src/config.json +++ b/src/config.json @@ -1,17 +1,21 @@ { - "discordApiToken": "", - "threadChannels": [""], - "threadArchiveDuration": "MAX", - "threadMessage": { - "shouldSend": true, - "shouldPin": true, - "content": "Thread created from $$channelMention by $$authorMention $$relativeTimeSince with the following message:", - "embeds": [ - "$$messageEmbed" - ] - }, - "dev": { - "clientId": "", - "guildId": "" + "threadChannels": [], + "messages": { + "ERR_UNKNOWN": "An unexpected error occurred. Please try again later.", + "ERR_ONLY_IN_SERVER": "You can only perform this action inside a server.", + "ERR_ONLY_IN_THREAD": "You can only perform this action inside a thread.", + "ERR_ONLY_THREAD_OWNER": "You need to be the thread owner to perform this action.", + "ERR_NO_EFFECT": "This action will have no effect.", + "ERR_JSON_MISSING": "The JSON content was missing.", + "ERR_JSON_INVALID": "Your input was not valid JSON. You can use an online tool such as to validate your json.", + "ERR_CONFIG_INVALID": "Your config was invalid. Remember to: \n- Pass minified JSON, because new lines inside commands does not work in Discord. You can use an online tool such as for minification.\n- Wrap the config in an object. \n- Spell property keys correctly.\n\nIf you need help with the formatting, you can see the default config of Needle at . Changes to `discordApiToken` and `dev` will be ignored by this command.", + "ERR_DURATION_INVALID": "The specified duration was invalid.", + "ERR_PARAMETER_MISSING": "A non-optional parameter is missing from the command.", + "ERR_INSUFFICIENT_PERMS": "You do not have permission to perform this action.", + "ERR_CHANNEL_VISIBILITY": "The $CHANNEL channel is not visible to the bot. Change the permissions and try again.", + "ERR_THREAD_MESSAGE_MISSING": "The starting message for this thread could not be found, which prevents this action from being performed.", + + "SUCCESS_THREAD_CREATE": "Hello $USER!\nThis thread has been automatically created from your message in $CHANNEL $TIME_AGO.\n\n**Want to unsubscribe from this thread?**\nRight-click the thread (or use the `...` menu) and select **Leave Thread**.\n\n**Want to change the title?**\nUse the `/title` command!\n\n**Done using the thread?**\nClick the button below to archive it.", + "SUCCESS_THREAD_ARCHIVE": "**This thread will be archived soon** :card_box:\nAs requested by $USER, this thread will automatically be archived when **one hour passes without any new messages**.\n\n• The thread's content will still be searchable with Discord's search function\n• Anyone will be able to un-archive the thread at any point in the future by sending a message in the thread again" } } diff --git a/src/handlers/commandHandler.ts b/src/handlers/commandHandler.ts index 449023cb..41b8c637 100644 --- a/src/handlers/commandHandler.ts +++ b/src/handlers/commandHandler.ts @@ -1,14 +1,14 @@ import { CommandInteraction, MessageComponentInteraction } from "discord.js"; import { promises } from "fs"; import { resolve as pathResolve } from "path"; -import { ephemeralReply } from "../helpers/messageHelpers"; +import { getMessage, interactionReply } from "../helpers/messageHelpers"; import { NeedleCommand } from "../types/needleCommand"; const COMMANDS_PATH = pathResolve(__dirname, "../commands"); let loadedCommands: NeedleCommand[] = []; -export async function handleCommandInteraction(interaction: CommandInteraction): Promise { +export function handleCommandInteraction(interaction: CommandInteraction): Promise { const command = getCommand(interaction.commandName); if (!command) return Promise.reject(); @@ -17,7 +17,7 @@ export async function handleCommandInteraction(interaction: CommandInteraction): } catch (error) { console.error(error); - return ephemeralReply(interaction, "There was an error while executing this command. Please try again later."); + return interactionReply(interaction, getMessage("ERR_UNKNOWN")); } } @@ -30,12 +30,12 @@ export async function handleButtonClickedInteraction(interaction: MessageCompone } catch (error) { console.error(error); - return ephemeralReply(interaction, "There was an error while executing this command. Please try again later."); + return interactionReply(interaction, getMessage("ERR_UNKNOWN")); } } -export async function getOrLoadAllCommands(alwaysLoad = false): Promise { - if (loadedCommands.length > 0 && !alwaysLoad) { +export async function getOrLoadAllCommands(allowCache = true): Promise { + if (loadedCommands.length > 0 && allowCache) { return loadedCommands; } diff --git a/src/handlers/interactionHandler.ts b/src/handlers/interactionHandler.ts index 437a9f98..e1cd4a41 100644 --- a/src/handlers/interactionHandler.ts +++ b/src/handlers/interactionHandler.ts @@ -1,11 +1,20 @@ import { Interaction } from "discord.js"; +import { resetMessageContext, addMessageContext } from "../helpers/messageHelpers"; import { handleButtonClickedInteraction, handleCommandInteraction } from "./commandHandler"; -export function handleInteractionCreate(interaction: Interaction): void { +export async function handleInteractionCreate(interaction: Interaction): Promise { + addMessageContext({ + user: interaction.user, + interaction: interaction, + channel: interaction.channel ?? undefined, + }); + if (interaction.isCommand()) { - handleCommandInteraction(interaction); + await handleCommandInteraction(interaction); } else if (interaction.isButton()) { - handleButtonClickedInteraction(interaction); + await handleButtonClickedInteraction(interaction); } + + resetMessageContext(); } diff --git a/src/handlers/messageHandler.ts b/src/handlers/messageHandler.ts index 63299e82..c135a5f2 100644 --- a/src/handlers/messageHandler.ts +++ b/src/handlers/messageHandler.ts @@ -1,5 +1,6 @@ -import { Message, MessageActionRow, MessageButton, MessageEmbed } from "discord.js"; +import { Message, MessageActionRow, MessageButton, NewsChannel, TextChannel } from "discord.js"; import { getConfig } from "../helpers/configHelpers"; +import { getMessage, resetMessageContext, addMessageContext, isAutoThreadChannel } from "../helpers/messageHelpers"; import { getRequiredPermissions } from "../helpers/permissionHelpers"; export async function handleMessageCreate(message: Message): Promise { @@ -19,10 +20,9 @@ export async function handleMessageCreate(message: Message): Promise { if (message.system) return; if (authorUser.bot) return; if (!channel.isText()) return; + if (!(channel instanceof TextChannel) && !(channel instanceof NewsChannel)) return; if (message.hasThread) return; - - const config = getConfig(); - if (!config?.threadChannels?.includes(channel.id)) return; + if (!isAutoThreadChannel(channel.id, guild.id)) return; const botMember = await guild.members.fetch(clientUser); const botPermissions = botMember.permissionsIn(message.channel.id); @@ -39,6 +39,12 @@ export async function handleMessageCreate(message: Message): Promise { return; } + addMessageContext({ + user: authorUser, + channel: channel, + message: message, + }); + const creationDate = message.createdAt.toISOString().slice(0, 10); const authorName = authorMember === null || authorMember.nickname === null ? authorUser.username @@ -46,24 +52,29 @@ export async function handleMessageCreate(message: Message): Promise { const thread = await message.startThread({ name: `${authorName} (${creationDate})`, - autoArchiveDuration: <60 | 1440 | 4320 | 10080 | "MAX"> config.threadArchiveDuration, + autoArchiveDuration: channel.defaultAutoArchiveDuration, }); const closeButton = new MessageButton() .setCustomId("close") - .setLabel("Close thread") + .setLabel("Archive thread") .setStyle("DANGER") - .setEmoji("🗑️"); + .setEmoji("🗃️"); const buttonRow = new MessageActionRow().addComponents(closeButton); - const channelMention = `<#${channel.id}>`; - const relativeTimestamp = ``; + const overrideMessageContent = getConfig(guild.id).threadChannels?.find(x => x?.channelId === channel.id)?.messageContent; + const msgContent = overrideMessageContent + ? overrideMessageContent + : getMessage("SUCCESS_THREAD_CREATE"); - await thread.send({ - content: `Hello <@${authorUser.id}>! This helpful thread has been automatically created from your message in ${channelMention} ${relativeTimestamp}.\n\nWant to unsubscribe from this thread? Right-click the thread (or use the \`...\` menu) and select **Leave Thread**.\n\nIf you are done using this thread, you can click the button below to close this thread.`, - components: [buttonRow], - }); + if (msgContent && msgContent.length > 0) { + await thread.send({ + content: msgContent, + components: [buttonRow], + }); + } await thread.leave(); + resetMessageContext(); } diff --git a/src/helpers/configHelpers.ts b/src/helpers/configHelpers.ts index 5195fca4..747d02ef 100644 --- a/src/helpers/configHelpers.ts +++ b/src/helpers/configHelpers.ts @@ -1,6 +1,115 @@ +import { Guild } from "discord.js"; import * as defaultConfig from "../config.json"; -import * as overrideConfig from "../overrideConfig.json"; +import { resolve as pathResolve } from "path"; +import * as fs from "fs"; +import { NeedleConfig } from "../types/needleConfig"; +import { MessageKey } from "./messageHelpers"; -export function getConfig(): typeof defaultConfig & typeof overrideConfig { - return Object.assign(defaultConfig, overrideConfig); +const CONFIGS_PATH = pathResolve(__dirname, "../../configs"); +const guildConfigsCache = new Map(); + +export function getConfig(guildId = ""): NeedleConfig { + const guildConfig = guildConfigsCache.get(guildId) ?? readConfigFromFile(guildId); + + const defaultConfigCopy = JSON.parse(JSON.stringify(defaultConfig)) as NeedleConfig; + if (guildConfig) { + guildConfig.messages = Object.assign({}, defaultConfigCopy.messages, guildConfig?.messages); + } + + return Object.assign({}, defaultConfigCopy, guildConfig); +} + +// Used by deploy-commands.js (!) +export function getApiToken(): string | undefined { + return process.env.DISCORD_API_TOKEN; +} + +// Used by deploy-commands.js (!) +export function getClientId(): string | undefined { + return process.env.CLIENT_ID; +} + +// Used by deploy-commands.js (!) +export function getGuildId(): string | undefined { + return process.env.GUILD_ID; +} + +export function setMessage(guild: Guild, messageKey: MessageKey, value: string): boolean { + const config = getConfig(guild.id); + if (!config || !config.messages) { return false; } + if (value.length > 2000) { return false; } + + config.messages[messageKey] = value; + return setConfig(guild, config); +} + +export function enableAutothreading(guild: Guild, channelId: string, message = ""): boolean { + const config = getConfig(guild.id); + if (!config || !config.threadChannels) { return false; } + if (message.length > 2000) { return false; } + + const index = config.threadChannels.findIndex(x => x?.channelId === channelId); + if (index > -1) { + config.threadChannels[index].messageContent = message; + } + else { + config.threadChannels.push({ channelId: channelId, messageContent: message }); + } + + return setConfig(guild, config); +} + +export function disableAutothreading(guild: Guild, channelId: string): boolean { + const config = getConfig(guild.id); + if (!config || !config.threadChannels) { return false; } + + const index = config.threadChannels.findIndex(x => x?.channelId === channelId); + if (index > -1) { + delete config.threadChannels[index]; + } + + return setConfig(guild, config); +} + +export function resetConfigToDefault(guildId: string): boolean { + const path = getGuildConfigPath(guildId); + if (!fs.existsSync(path)) return false; + fs.rmSync(path); + guildConfigsCache.delete(guildId); + return true; +} + +function readConfigFromFile(guildId: string): NeedleConfig | undefined { + const path = getGuildConfigPath(guildId); + if (!fs.existsSync(path)) return undefined; + + const jsonConfig = fs.readFileSync(path, { "encoding": "utf-8" }); + return JSON.parse(jsonConfig); +} + +function getGuildConfigPath(guildId: string) { + return `${CONFIGS_PATH}/${guildId}.json`; +} + +function setConfig(guild: Guild | null | undefined, config: NeedleConfig): boolean { + if (!guild || !config) return false; + + const path = getGuildConfigPath(guild.id); + if (!fs.existsSync(CONFIGS_PATH)) { + fs.mkdirSync(CONFIGS_PATH); + } + config.threadChannels = config.threadChannels?.filter(val => val != null && val != undefined); + + // Only save messages that are different from the defaults + const defaultConfigCopy = JSON.parse(JSON.stringify(defaultConfig)) as NeedleConfig; + if (defaultConfigCopy.messages && config.messages) { + for(const [key, message] of Object.entries(config.messages)) { + if (message !== defaultConfigCopy.messages[key as MessageKey]) continue; + delete config.messages[key as MessageKey]; + } + } + + fs.writeFileSync(path, JSON.stringify(config), { encoding: "utf-8" }); + guildConfigsCache.set(guild.id, config); + return true; } diff --git a/src/helpers/fileHelpers.ts b/src/helpers/fileHelpers.ts new file mode 100644 index 00000000..0b7912f3 --- /dev/null +++ b/src/helpers/fileHelpers.ts @@ -0,0 +1,7 @@ +import { MessageAttachment } from "discord.js"; +import { Readable } from "stream"; + +export function createJsonMessageAttachment(obj: unknown, fileName: string, indentation = 2): MessageAttachment { + const stream = Readable.from(JSON.stringify(obj, undefined, indentation), { encoding: "utf-8" }); + return new MessageAttachment(stream, fileName); +} diff --git a/src/helpers/messageHelpers.ts b/src/helpers/messageHelpers.ts index f658d5a3..2c8b7c21 100644 --- a/src/helpers/messageHelpers.ts +++ b/src/helpers/messageHelpers.ts @@ -1,4 +1,31 @@ -import { BaseCommandInteraction, Message, MessageButton, MessageComponentInteraction, TextBasedChannels } from "discord.js"; +import { + BaseCommandInteraction, + Message, + MessageButton, + MessageComponentInteraction, + TextBasedChannels, +} from "discord.js"; + +import { MessageContext } from "../types/messageContext"; +import { NeedleConfig } from "../types/needleConfig"; +import { getConfig } from "./configHelpers"; + +let context: MessageContext = {}; + +export type MessageKey = keyof NonNullable; + +export function addMessageContext(additionalContext: Partial): void { + context = Object.assign(context, additionalContext); +} + +export function resetMessageContext(): void { + context = {}; +} + +export function isAutoThreadChannel(channelId: string, guildId: string): boolean { + const config = getConfig(guildId); + return config?.threadChannels?.some(x => x?.channelId === channelId) ?? false; +} export async function getThreadStartMessage(threadChannel: TextBasedChannels | null): Promise { if (!threadChannel?.isThread()) { return null; } @@ -12,13 +39,60 @@ export async function getThreadStartMessage(threadChannel: TextBasedChannels | n return parentChannel.messages .fetch(threadChannel.id) .catch(() => { - console.error(`Start message has been deleted in thread "${threadChannel.name}"`); + console.error(`Start message is missing in thread "${threadChannel.name}"`); return null; }); } -export function ephemeralReply(interaction: BaseCommandInteraction | MessageComponentInteraction, replyContent: string): Promise { - return interaction.reply({ content: replyContent, ephemeral: true }); +export function getCodeFromCodeBlock(codeBlock: string): string { + const codeBlockStart = codeBlock.match(/^```(\w*)/ig); + + // If it has no code block + if (codeBlockStart?.length === 0) { + return codeBlock; + } + + // Replace start and end tags + const codeWithoutTags = codeBlock.replaceAll(/^```(\w*)/ig, "").replaceAll(/```$/ig, ""); + return codeWithoutTags.trim(); +} + +export function interactionReply( + interaction: BaseCommandInteraction | MessageComponentInteraction, + message?: string, + ephemeral = true): Promise { + if (!message || message.length == 0) { + return interaction.reply({ + content: getMessage("ERR_UNKNOWN"), + ephemeral: true, + }); + } + + return interaction.reply({ + content: message, + ephemeral: ephemeral, + }); +} + +export function getMessage(messageKey: MessageKey, replaceVariables = true): string | undefined { + const config = getConfig(context?.interaction?.guildId); + if (!config.messages) { return ""; } + + const message = config.messages[messageKey]; + if (!context || !message) { return message; } + + const user = context.user ? `<@${context.user.id}>` : ""; + const channel = context.channel ? `<#${context.channel.id}>` : ""; + const timeAgo = context.timeAgo || (context.message + ? `` + : ""); + + return !replaceVariables + ? message + : message + .replaceAll("$USER", user) + .replaceAll("$CHANNEL", channel) + .replaceAll("$TIME_AGO", timeAgo); } export function getDiscordInviteButton(buttonText = "Join the support server"): MessageButton { @@ -45,10 +119,17 @@ export function getBugReportButton(buttonText = "Report a bug"): MessageButton { .setEmoji("🐛"); } -export function getFeatureRequestButton(buttonText = "Suggest a feature"): MessageButton { +export function getFeatureRequestButton(buttonText = "Suggest an improvement"): MessageButton { return new MessageButton() .setLabel(buttonText) .setStyle("LINK") .setURL("https://github.com/MarcusOtter/discord-needle/issues/new/choose") .setEmoji("💡"); -} \ No newline at end of file +} + +export function getCloseConfigChannelButton(): MessageButton { + return new MessageButton() + .setCustomId("close-config-channel") + .setLabel("Close channel") + .setStyle("DANGER"); +} diff --git a/src/helpers/permissionHelpers.ts b/src/helpers/permissionHelpers.ts index daf1df3c..695a6389 100644 --- a/src/helpers/permissionHelpers.ts +++ b/src/helpers/permissionHelpers.ts @@ -1,23 +1,21 @@ -import { Permissions } from "discord.js"; -import { getConfig } from "./configHelpers"; +import { GuildMember, Permissions } from "discord.js"; export function getRequiredPermissions(): bigint[] { - const config = getConfig(); const output = [ - Permissions.FLAGS.USE_PUBLIC_THREADS, - - /* TODO: Replace with SEND_MESSAGES_IN_THREADS when it is released */ + Permissions.FLAGS.VIEW_CHANNEL, Permissions.FLAGS.SEND_MESSAGES, + Permissions.FLAGS.SEND_MESSAGES_IN_THREADS, + Permissions.FLAGS.CREATE_PUBLIC_THREADS, Permissions.FLAGS.READ_MESSAGE_HISTORY, ]; - if (config?.threadMessage?.shouldPin) { - output.push(Permissions.FLAGS.MANAGE_MESSAGES); - } + return output; +} - if (config?.threadMessage?.embeds?.length > 0) { - output.push(Permissions.FLAGS.EMBED_LINKS); - } +export function memberIsModerator(member: GuildMember): boolean { + return member.permissions.has(Permissions.FLAGS.KICK_MEMBERS); +} - return output; +export function memberIsAdmin(member: GuildMember): boolean { + return member.permissions.has(Permissions.FLAGS.ADMINISTRATOR); } diff --git a/src/index.ts b/src/index.ts index d87c5a72..8e24b7db 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,18 +2,20 @@ import { Client, Intents } from "discord.js"; import { getOrLoadAllCommands } from "./handlers/commandHandler"; import { handleInteractionCreate } from "./handlers/interactionHandler"; import { handleMessageCreate } from "./handlers/messageHandler"; -import { getConfig } from "./helpers/configHelpers"; +import { getApiToken } from "./helpers/configHelpers"; -const CLIENT = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] }); - -CLIENT.once("ready", async () => { - console.log("Ready!"); +(async () => { + (await import("dotenv")).config(); // Initial load of all commands - await getOrLoadAllCommands(); -}); + await getOrLoadAllCommands(false); + + const CLIENT = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] }); + CLIENT.once("ready", () => console.log("Ready!")); + + CLIENT.on("interactionCreate", interaction => handleInteractionCreate(interaction).catch(e => console.log(e))); + CLIENT.on("messageCreate", message => handleMessageCreate(message).catch(e => console.log(e))); -CLIENT.on("interactionCreate", interaction => handleInteractionCreate(interaction)); -CLIENT.on("messageCreate", message => handleMessageCreate(message)); + CLIENT.login(getApiToken() ?? undefined); +})(); -CLIENT.login(getConfig().discordApiToken); diff --git a/src/types/messageContext.ts b/src/types/messageContext.ts new file mode 100644 index 00000000..c6342825 --- /dev/null +++ b/src/types/messageContext.ts @@ -0,0 +1,13 @@ +import { CacheType, Interaction, Message, TextBasedChannels, User } from "discord.js"; + +export interface MessageContext { + interaction?: Interaction; + message?: Message; + + // Variables that can be used in messages (if they exist at the time of invocation) + // To use in message configuration, prefix with $ and convert name to SCREAMING_SNAKE_CASE + // For example, $TIME_AGO and $USER + channel?: TextBasedChannels; + user?: User; + timeAgo?: string; +} diff --git a/src/types/needleConfig.ts b/src/types/needleConfig.ts new file mode 100644 index 00000000..2213968d --- /dev/null +++ b/src/types/needleConfig.ts @@ -0,0 +1,20 @@ +export interface NeedleConfig { + threadChannels?: { channelId: string, messageContent: string }[]; + messages?: { + ERR_UNKNOWN?: string, + ERR_ONLY_IN_SERVER?: string, + ERR_ONLY_IN_THREAD?: string, + ERR_ONLY_THREAD_OWNER?: string, + ERR_NO_EFFECT?: string, + ERR_JSON_MISSING?: string, + ERR_JSON_INVALID?: string, + ERR_CONFIG_INVALID?: string; + ERR_PARAMETER_MISSING?: string, + ERR_INSUFFICIENT_PERMS?: string, + ERR_CHANNEL_VISIBILITY?: string, + ERR_THREAD_MESSAGE_MISSING?: string, + + SUCCESS_THREAD_CREATE?: string, + SUCCESS_THREAD_ARCHIVE?: string, + }, +}