From 9626be09a9367c674902828704911078d4e69093 Mon Sep 17 00:00:00 2001 From: BenW Date: Mon, 22 Jan 2024 19:09:07 +0000 Subject: [PATCH] feat: adds docSearch.ts (#5) --- .github/CHANGELOG.md | 1 + package-lock.json | 24 ++++++++++++++ package.json | 2 ++ src/commands/index.ts | 2 ++ src/commands/utils/docSearch.ts | 58 +++++++++++++++++++++++++++++++++ 5 files changed, 87 insertions(+) create mode 100644 src/commands/utils/docSearch.ts diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index b4be78b8..86abd443 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -2,6 +2,7 @@ Update _ January 2024 +- feat: docSearch command (22/01/2024) - fix: vatsim events max fields (20/01/2024) - fix: user and mod log exclude id's (18/01/2024) - feat: New FBW Utils and Moderation bot (08/01/2024) diff --git a/package-lock.json b/package-lock.json index ef6beb2c..00a232f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@hokify/agenda": "^6.0.0", "@octokit/request": "^8.1.1", + "bad-words": "^3.0.4", "config": "^3.3.9", "discord.js": "^14.11.0", "moment": "^2.29.4", @@ -20,6 +21,7 @@ }, "devDependencies": { "@flybywiresim/eslint-config": "^0.1.0", + "@types/bad-words": "^3.0.3", "@types/config": "^3.3.1", "@types/node": "^18.0.0", "@types/node-fetch": "^2.6.10", @@ -1844,6 +1846,12 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "node_modules/@types/bad-words": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/bad-words/-/bad-words-3.0.3.tgz", + "integrity": "sha512-jYdpTxDOJ+EENnsCwt8cOZhV/+4+qcwhks1igrOSg4zwwA17rsPqLsZpTo1l+OwViNu+5SPus0v5g7iGx+ofzA==", + "dev": true + }, "node_modules/@types/config": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/@types/config/-/config-3.3.3.tgz", @@ -2429,6 +2437,22 @@ "dequal": "^2.0.3" } }, + "node_modules/bad-words": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/bad-words/-/bad-words-3.0.4.tgz", + "integrity": "sha512-v/Q9uRPH4+yzDVLL4vR1+S9KoFgOEUl5s4axd6NIAq8SV2mradgi4E8lma/Y0cw1ltVdvyegCQQKffCPRCp8fg==", + "dependencies": { + "badwords-list": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/badwords-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/badwords-list/-/badwords-list-1.0.0.tgz", + "integrity": "sha512-oWhaSG67e+HQj3OGHQt2ucP+vAPm1wTbdp2aDHeuh4xlGXBdWwzZ//pfu6swf5gZ8iX0b7JgmSo8BhgybbqszA==" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", diff --git a/package.json b/package.json index ac3fc3b1..e1ccda74 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "dependencies": { "@hokify/agenda": "^6.0.0", "@octokit/request": "^8.1.1", + "bad-words": "^3.0.4", "config": "^3.3.9", "discord.js": "^14.11.0", "moment": "^2.29.4", @@ -26,6 +27,7 @@ }, "devDependencies": { "@flybywiresim/eslint-config": "^0.1.0", + "@types/bad-words": "^3.0.3", "@types/config": "^3.3.1", "@types/node": "^18.0.0", "@types/node-fetch": "^2.6.10", diff --git a/src/commands/index.ts b/src/commands/index.ts index 37da83a1..1b85addb 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -25,6 +25,7 @@ import birthday from './utils/birthday/birthday'; import count from './utils/count'; import vatsim from './utils/vatsim/vatsim'; import help from './utils/help'; +import docSearch from './utils/docSearch'; const commandArray: SlashCommand[] = [ ping, @@ -53,6 +54,7 @@ const commandArray: SlashCommand[] = [ count, vatsim, help, + docSearch, ]; export default commandArray; diff --git a/src/commands/utils/docSearch.ts b/src/commands/utils/docSearch.ts new file mode 100644 index 00000000..e559ddd9 --- /dev/null +++ b/src/commands/utils/docSearch.ts @@ -0,0 +1,58 @@ +import { ApplicationCommandOptionType, ApplicationCommandType, Colors } from 'discord.js'; +import Filter from 'bad-words'; +import { slashCommand, slashCommandStructure, makeEmbed } from '../../lib'; + +const data = slashCommandStructure({ + name: 'doc_search', + description: 'Searches the FlyByWire Documentation for a given query.', + type: ApplicationCommandType.ChatInput, + options: [{ + name: 'query', + description: 'The query to search for.', + type: ApplicationCommandOptionType.String, + max_length: 100, + required: true, + }], +}); + +const DOCS_BASE_URL = 'https://docs.flybywiresim.com'; + +export default slashCommand(data, async ({ interaction }) => { + const query = interaction.options.getString('query')!; + + // Separates the query into an array. + const words = query.split(/\s+/); + + // Itterate through the array and check if any of the words are a URL. Then check if any of the words are profanity. + for (const searchWord of words) { + try { + const _ = new URL(searchWord); + const URLEmbed = makeEmbed({ + title: 'FlyByWire Documentation | Error', + description: 'Providing URLs to the Documentation search command is not allowed.', + color: Colors.Red, + }); + return interaction.reply({ embeds: [URLEmbed] }); + } catch (_) { /**/ } + + const filter = new Filter(); + if (filter.isProfane(searchWord)) { + const profanityEmbed = makeEmbed({ + title: 'FlyByWire Documentation | Error', + description: 'Providing profanity to the Documentation search command is not allowed.', + color: Colors.Red, + }); + + return interaction.reply({ embeds: [profanityEmbed] }); + } + } + + // Safety to prevent users from entering unexpected data that might result in strange behavior in a URL. + const encodedSearchQuery = encodeURIComponent(query); + + const queryEmbed = makeEmbed({ + title: 'FlyByWire Documentation Search', + description: `Search the FlyByWire Documentation for "${query}" [here](${DOCS_BASE_URL}/?q=${encodedSearchQuery}).`, + }); + return interaction.reply({ embeds: [queryEmbed] }); +});