From 7afbbdfb252d726a837bb84bc8860d5f06a5d495 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Wed, 8 Dec 2021 09:29:46 +0100 Subject: [PATCH 01/71] add i18next dependency --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 6ec4480..f72e410 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "eslint-plugin-prettier": "^4.0.0", "fs": "^0.0.1-security", "github-create-issue": "^1.0.1", + "i18next": "^21.5.6", "luxon": "^2.1.1", "moment": "^2.29.1", "moment-timezone": "^0.5.34", From 19f6ce62c959d15023bc7038bdaa43d296dcd09e Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 12 Dec 2021 21:24:40 +0100 Subject: [PATCH 02/71] initial i18 commit --- index.ts | 19 +++++++++++++++++++ locales/de.json | 5 +++++ locales/en.json | 5 +++++ package.json | 1 + 4 files changed, 30 insertions(+) create mode 100644 locales/de.json create mode 100644 locales/en.json diff --git a/index.ts b/index.ts index 5321505..e230dcf 100644 --- a/index.ts +++ b/index.ts @@ -1,9 +1,28 @@ import * as fs from 'fs' import { Collection, Intents } from 'discord.js' +import i18next from 'i18next' +import Backend from 'i18next-fs-backend' import config from './private/config.json' import { DiscordClient } from './types/customTypes' +const backend = new Backend({ + loadPath: '/locales/{{lng}}/{{ns}}.json', +}) + +i18next.use(backend).init({ + lng: 'en', + fallbackLng: 'en', + preload: ['en', 'de'], + ns: ['translation'], + defaultNS: 'translation', + debug: true, + backend: { + loadPath: './locales/{{lng}}.json', + }, + initImmediate: false, +}) + /** * Folder that contains all commands. */ diff --git a/locales/de.json b/locales/de.json new file mode 100644 index 0000000..293d7b2 --- /dev/null +++ b/locales/de.json @@ -0,0 +1,5 @@ +{ + "devtest": { + "welcome": "hallo welt" + } +} \ No newline at end of file diff --git a/locales/en.json b/locales/en.json new file mode 100644 index 0000000..9729b7a --- /dev/null +++ b/locales/en.json @@ -0,0 +1,5 @@ +{ + "devtest": { + "welcome": "hello world" + } +} \ No newline at end of file diff --git a/package.json b/package.json index f72e410..4d4c74d 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "fs": "^0.0.1-security", "github-create-issue": "^1.0.1", "i18next": "^21.5.6", + "i18next-fs-backend": "^1.1.4", "luxon": "^2.1.1", "moment": "^2.29.1", "moment-timezone": "^0.5.34", From 49ff64ac17d01a049923ccb1ae6da89cb5b88517 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 12 Dec 2021 21:41:43 +0100 Subject: [PATCH 03/71] add client.translate as global translation method --- types/customTypes.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/types/customTypes.ts b/types/customTypes.ts index e317dc7..a91aa74 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -1,5 +1,6 @@ // eslint-disable-next-line @typescript-eslint/no-unused-vars import { Client, Message, TextChannel, MessageOptions, Collection } from 'discord.js' +import i18next from 'i18next' /** * Extended version of the default {@link Client} with addidtional functions and properties. @@ -93,6 +94,16 @@ export class DiscordClient extends Client { ) }) } + + /** + * Translates {@link key} using {@link i18next.t} + * @param {string} key Key to look translation for + * @param {Object} options Options + * @returns {string} + */ + public translate(key: string, options?: object): string { + return i18next.t(key, options) + } } /** From 0c00dbb6b2a97d82566e2628eccaf8bca26523dd Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 12 Dec 2021 21:42:59 +0100 Subject: [PATCH 04/71] update types --- types/customTypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/customTypes.ts b/types/customTypes.ts index a91aa74..f4b654a 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -101,7 +101,7 @@ export class DiscordClient extends Client { * @param {Object} options Options * @returns {string} */ - public translate(key: string, options?: object): string { + public translate(key: string | string[], options?: object | string): string { return i18next.t(key, options) } } From f024224d25f43f8353bba4b4b9f37d85a9e2fd64 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 12 Dec 2021 22:02:46 +0100 Subject: [PATCH 05/71] add optional lng option --- types/customTypes.ts | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/types/customTypes.ts b/types/customTypes.ts index f4b654a..41ff411 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -96,16 +96,27 @@ export class DiscordClient extends Client { } /** - * Translates {@link key} using {@link i18next.t} - * @param {string} key Key to look translation for - * @param {Object} options Options + * Translate {@link trans.key} using {@link trans.lng} or alternatively {@link trans.options}. + * @param {trans} args Arguments to use to translate * @returns {string} */ - public translate(key: string | string[], options?: object | string): string { - return i18next.t(key, options) + public translate(args: trans): string { + const options = args.options ?? args.lng ? { lng: args.lng } : null + return i18next.t(args.key, options) } } +/** + * Interface for translation parameters + * @readonly + * @private + */ +interface trans { + key: string | string[] + lng?: string + options?: object | string +} + /** * Interface of Command structure * @readonly From a7307f3e841c9e38b08beda1b42541d0b4489949 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Wed, 15 Dec 2021 08:08:48 +0100 Subject: [PATCH 06/71] bump i18next --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4d4c74d..a8a0548 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "eslint-plugin-prettier": "^4.0.0", "fs": "^0.0.1-security", "github-create-issue": "^1.0.1", - "i18next": "^21.5.6", + "i18next": "^21.6.0", "i18next-fs-backend": "^1.1.4", "luxon": "^2.1.1", "moment": "^2.29.1", @@ -36,4 +36,4 @@ "@typescript-eslint/parser": "^5.5.0", "eslint": "^8.4.0" } -} +} \ No newline at end of file From f3e9d85275005a0c307fd485a55fdcd640e0cfee Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Tue, 14 Dec 2021 16:14:41 +0100 Subject: [PATCH 07/71] rm logging of interaction --- slashCommands/wochenplan.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/slashCommands/wochenplan.ts b/slashCommands/wochenplan.ts index f40d5d3..8a6a9b2 100644 --- a/slashCommands/wochenplan.ts +++ b/slashCommands/wochenplan.ts @@ -225,7 +225,6 @@ exports.run = async client => { await postSlashCommand(client) client.on('interactionCreate', async (interaction: Interaction) => { - console.log(interaction) if (!interaction.isCommand()) return const COMMAND = interaction.commandName if (COMMAND !== 'wochenplan') return From b6efac79cb3222733b1096300b3e6ce52e63c664 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Wed, 15 Dec 2021 08:09:48 +0100 Subject: [PATCH 08/71] add error handling --- slashCommands/issue.ts | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/slashCommands/issue.ts b/slashCommands/issue.ts index 60bd8a7..436abf6 100644 --- a/slashCommands/issue.ts +++ b/slashCommands/issue.ts @@ -44,19 +44,32 @@ async function respond(interaction, COMMAND: string, client: any): Promise body: interaction.options.getString('vorschlag'), } - createIssue( - REPOSITORY, - `${interaction.user.username}'s Vorschlag${ - interaction.options.getString('titel') ? `: ${interaction.options.getString('titel')}` : '' - }`, - options, - clbk, - ) + try { + createIssue( + REPOSITORY, + `${interaction.user.username}'s Vorschlag${ + interaction.options.getString('titel') ? `: ${interaction.options.getString('titel')}` : '' + }`, + options, + clbk, + ) - await interaction.reply({ - embeds: [new MessageEmbed().setTitle('Vorschlag angekommen!').setDescription('Vielen Dank für deinen Vorschlag!')], - ephemeral: true, - }) + await interaction.reply({ + embeds: [ + new MessageEmbed().setTitle('Vorschlag angekommen!').setDescription('Vielen Dank für deinen Vorschlag!'), + ], + ephemeral: true, + }) + } catch (error) { + await interaction.reply({ + embeds: [ + new MessageEmbed() + .setTitle('⚠Fehler') + .setDescription('Es ist ein Fehler aufgetreten. Bitte versuche es später erneut.'), + ], + }) + throw new Error(error) + } } function clbk(error: Error, issue: object, info): void { From ce6bf6a9f911043706a3b0539864d9dd64141ef1 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Wed, 15 Dec 2021 10:51:57 +0100 Subject: [PATCH 09/71] bump dependencies --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index a8a0548..0b06e48 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "author": "Christoph Bluem", "dependencies": { "discord-api-types": "^0.25.2", - "discord.js": "^13.4.0-dev.1639353941.2ce244b", + "discord.js": "^13.4.0-dev.1639526739.a0fe0ac", "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.25.3", "eslint-plugin-prettier": "^4.0.0", @@ -20,7 +20,7 @@ "github-create-issue": "^1.0.1", "i18next": "^21.6.0", "i18next-fs-backend": "^1.1.4", - "luxon": "^2.1.1", + "luxon": "^2.2.0", "moment": "^2.29.1", "moment-timezone": "^0.5.34", "node-ical": "^0.14.1", @@ -32,8 +32,8 @@ "valid-url": "^1.0.9" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^5.5.0", - "@typescript-eslint/parser": "^5.5.0", - "eslint": "^8.4.0" + "@typescript-eslint/eslint-plugin": "^5.7.0", + "@typescript-eslint/parser": "^5.7.0", + "eslint": "^8.4.1" } -} \ No newline at end of file +} From 7a5a420b93bf39e70a8ca9bf2854a24366309756 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sat, 18 Dec 2021 14:42:03 +0100 Subject: [PATCH 10/71] bump dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 0b06e48..16c692e 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,13 @@ "author": "Christoph Bluem", "dependencies": { "discord-api-types": "^0.25.2", - "discord.js": "^13.4.0-dev.1639526739.a0fe0ac", + "discord.js": "^13.4.0-dev.1639656190.b9b60a3", "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.25.3", "eslint-plugin-prettier": "^4.0.0", "fs": "^0.0.1-security", "github-create-issue": "^1.0.1", - "i18next": "^21.6.0", + "i18next": "^21.6.2", "i18next-fs-backend": "^1.1.4", "luxon": "^2.2.0", "moment": "^2.29.1", @@ -34,6 +34,6 @@ "devDependencies": { "@typescript-eslint/eslint-plugin": "^5.7.0", "@typescript-eslint/parser": "^5.7.0", - "eslint": "^8.4.1" + "eslint": "^8.5.0" } } From c971178370d122cf9fe189f0b297f1217958deb5 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sat, 18 Dec 2021 14:51:05 +0100 Subject: [PATCH 11/71] remove Message import --- slashCommands/wochenplan.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slashCommands/wochenplan.ts b/slashCommands/wochenplan.ts index 8a6a9b2..cde97a5 100644 --- a/slashCommands/wochenplan.ts +++ b/slashCommands/wochenplan.ts @@ -1,4 +1,4 @@ -import { Interaction, Message, MessageEmbed } from 'discord.js' +import { Interaction, MessageEmbed } from 'discord.js' import moment from 'moment-timezone' import { async } from 'node-ical' import { DiscordClient } from '../types/customTypes' From f25e60578ba48c40cd8448dce3931a79abcdd85e Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 20 Dec 2021 10:27:15 +0100 Subject: [PATCH 12/71] add function to get language --- types/customTypes.ts | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/types/customTypes.ts b/types/customTypes.ts index 41ff411..60c606c 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -1,3 +1,4 @@ +import { readdirSync } from 'fs' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { Client, Message, TextChannel, MessageOptions, Collection } from 'discord.js' import i18next from 'i18next' @@ -96,11 +97,44 @@ export class DiscordClient extends Client { } /** - * Translate {@link trans.key} using {@link trans.lng} or alternatively {@link trans.options}. - * @param {trans} args Arguments to use to translate + * Get user language. + * @param {Message} message Message sent by user * @returns {string} */ - public translate(args: trans): string { + public getLanguage(message: Message): string { + /** + * List of all defined languages in './locales/'. + */ + const files = readdirSync('./locales/') + + /** + * Loop through all languages. + */ + for (const file of files) { + /** + * Remove '.json' filetype from file name + */ + const language = file.split('.')[0] + + /** + * Return language if match is found. + */ + if (message.member.roles.cache.some(role => role.name === language)) return language + } + + /** + * Return null if no language match is found. + */ + return null + } + + /** + * Translate {@link translation_options.key} using {@link translation_options.lng} + * or alternatively {@link translation_options.options}. + * @param {translation_options} args Arguments to use to translate + * @returns {string} + */ + public translate(args: translation_options): string { const options = args.options ?? args.lng ? { lng: args.lng } : null return i18next.t(args.key, options) } @@ -111,7 +145,7 @@ export class DiscordClient extends Client { * @readonly * @private */ -interface trans { +interface translation_options { key: string | string[] lng?: string options?: object | string From 429b087eef3258b37e2a9b9e26e9ca7a7db1ab72 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 20 Dec 2021 10:56:14 +0100 Subject: [PATCH 13/71] change null to undefined return --- types/customTypes.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/customTypes.ts b/types/customTypes.ts index 60c606c..d61db1f 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -123,9 +123,9 @@ export class DiscordClient extends Client { } /** - * Return null if no language match is found. + * Return undefined if no language match is found. */ - return null + return undefined } /** From 1e62665c0f023b73c2ddca480a2e266c3b11bd28 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 20 Dec 2021 10:56:48 +0100 Subject: [PATCH 14/71] add language parsing --- events/messageCreate.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/events/messageCreate.ts b/events/messageCreate.ts index 7e797c2..53f031c 100644 --- a/events/messageCreate.ts +++ b/events/messageCreate.ts @@ -37,10 +37,15 @@ exports.run = (client: DiscordClient, message: Message) => { */ if (commandfile === undefined) return + /** + * Get language for user. + */ + const userLanguage: string = client.getLanguage(message) ?? client.config.defaultLanguage + /** * Run the command. */ - executeCommand(message, commandfile, client, args, commandName) + executeCommand(message, commandfile, client, args, commandName, userLanguage) } } @@ -146,6 +151,7 @@ function getCommandData( * @param {DiscordClient} client Bot-Client * @param {string[]} args Arguments used by the user * @param {string} commandName Name of the selected command + * @param {string} language Language for user * @returns {void} */ function executeCommand( @@ -154,6 +160,7 @@ function executeCommand( client: DiscordClient, args: string[], commandName: string, + language: string, ): void { try { /** @@ -165,7 +172,7 @@ function executeCommand( * Runs the selected command. * Delete the message issuing the command after it replied successfully. */ - commandfile.run(client, message, args)?.then(msg => msg?.delete()) + commandfile.run(client, message, language, args)?.then(msg => msg?.delete()) /** * Increment the counter of issued commands since last restart. From 967e8a7f7112c36a1978a9a33e747459d155d031 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 20 Dec 2021 10:57:10 +0100 Subject: [PATCH 15/71] add language parameter --- commands/fun/tenor.ts | 2 +- commands/utility/channelinfo.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/commands/fun/tenor.ts b/commands/fun/tenor.ts index 165ea4d..fddfe9e 100644 --- a/commands/fun/tenor.ts +++ b/commands/fun/tenor.ts @@ -10,7 +10,7 @@ exports.usage = `tenor ` exports.aliases = ['gif'] -exports.run = (client: DiscordClient, message: Message, args: string[]) => { +exports.run = (client: DiscordClient, message: Message, language: string, args: string[]) => { /** * Get {@link UserMention} from message. * @type {string} diff --git a/commands/utility/channelinfo.ts b/commands/utility/channelinfo.ts index 2fa043d..a0177cd 100644 --- a/commands/utility/channelinfo.ts +++ b/commands/utility/channelinfo.ts @@ -16,7 +16,7 @@ exports.description = 'Displays some information about the channel and its users exports.usage = 'channelinfo {#channel}' -exports.run = async (client: DiscordClient, message: Message, args: string[]) => { +exports.run = async (client: DiscordClient, message: Message, language: string, args: string[]) => { /** * Channel to display information about. */ From e6fc2799bf0d692a911259017118318d53dd5179 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 20 Dec 2021 10:57:21 +0100 Subject: [PATCH 16/71] add hello command --- commands/tests/hello.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 commands/tests/hello.ts diff --git a/commands/tests/hello.ts b/commands/tests/hello.ts new file mode 100644 index 0000000..20d0fcb --- /dev/null +++ b/commands/tests/hello.ts @@ -0,0 +1,17 @@ +import { Message } from 'discord.js' + +import { DiscordClient } from '../../types/customTypes' + +exports.name = 'devtest' + +exports.description = 'Testfunktion von neuen Features' + +exports.usage = 'devtest' + +exports.aliases = ['hallo'] + +exports.run = (client: DiscordClient, message: Message, language: string) => { + const returnString = client.translate({ key: 'devtest.welcome', lng: language }) + + return client.reply(message, { content: returnString }) +} From d972a574bdef20b9957569e4d4bef0c86543189e Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 20 Dec 2021 10:59:17 +0100 Subject: [PATCH 17/71] change information about command --- commands/tests/hello.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/commands/tests/hello.ts b/commands/tests/hello.ts index 20d0fcb..e7904e5 100644 --- a/commands/tests/hello.ts +++ b/commands/tests/hello.ts @@ -2,11 +2,11 @@ import { Message } from 'discord.js' import { DiscordClient } from '../../types/customTypes' -exports.name = 'devtest' +exports.name = 'hello' -exports.description = 'Testfunktion von neuen Features' +exports.description = 'Hallo welt!' -exports.usage = 'devtest' +exports.usage = 'hello' exports.aliases = ['hallo'] From 9453d03299c5b3378f5f92443b2ee96f235658e1 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 26 Dec 2021 18:26:11 +0100 Subject: [PATCH 18/71] add language to user object --- types/customTypes.ts | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/types/customTypes.ts b/types/customTypes.ts index d61db1f..39ce791 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -1,6 +1,6 @@ import { readdirSync } from 'fs' // eslint-disable-next-line @typescript-eslint/no-unused-vars -import { Client, Message, TextChannel, MessageOptions, Collection } from 'discord.js' +import { Client, Message, TextChannel, MessageOptions, Collection, User } from 'discord.js' import i18next from 'i18next' /** @@ -101,7 +101,7 @@ export class DiscordClient extends Client { * @param {Message} message Message sent by user * @returns {string} */ - public getLanguage(message: Message): string { + public getLanguage(message: DiscordMessage): string { /** * List of all defined languages in './locales/'. */ @@ -119,13 +119,15 @@ export class DiscordClient extends Client { /** * Return language if match is found. */ - if (message.member.roles.cache.some(role => role.name === language)) return language + if (message.member.roles.cache.some(role => role.name === language)) { + return (message.author.language = language) + } } /** - * Return undefined if no language match is found. + * Return default language if no language match is found. */ - return undefined + return (message.author.language = 'en') } /** @@ -140,6 +142,20 @@ export class DiscordClient extends Client { } } +/** + * Extended Message to hold DiscordUser. + */ +export interface DiscordMessage extends Message { + author: DiscordUser +} + +/** + * Extended User to hold language. + */ +class DiscordUser extends User { + language: string +} + /** * Interface for translation parameters * @readonly From 3c4701b7fbbd3179cf7b89847f1687531cdc3514 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 26 Dec 2021 18:26:27 +0100 Subject: [PATCH 19/71] bump dependencies --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 16c692e..e5d5f5e 100644 --- a/package.json +++ b/package.json @@ -11,14 +11,14 @@ "homepage": "https://github.com/Chr1s70ph/ETIT-Master-JS#readme", "author": "Christoph Bluem", "dependencies": { - "discord-api-types": "^0.25.2", - "discord.js": "^13.4.0-dev.1639656190.b9b60a3", + "discord-api-types": "^0.26.0", + "discord.js": "^13.5.0-dev.1640520180.f1d35e3", "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.25.3", "eslint-plugin-prettier": "^4.0.0", "fs": "^0.0.1-security", "github-create-issue": "^1.0.1", - "i18next": "^21.6.2", + "i18next": "^21.6.3", "i18next-fs-backend": "^1.1.4", "luxon": "^2.2.0", "moment": "^2.29.1", @@ -32,8 +32,8 @@ "valid-url": "^1.0.9" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^5.7.0", - "@typescript-eslint/parser": "^5.7.0", + "@typescript-eslint/eslint-plugin": "^5.8.0", + "@typescript-eslint/parser": "^5.8.0", "eslint": "^8.5.0" } } From cc987acbf56e8a168689b8ef7c4e9f2ae9081c9d Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 26 Dec 2021 18:28:12 +0100 Subject: [PATCH 20/71] use user with language property --- events/messageCreate.ts | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/events/messageCreate.ts b/events/messageCreate.ts index 53f031c..6fe7613 100644 --- a/events/messageCreate.ts +++ b/events/messageCreate.ts @@ -1,6 +1,5 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import { Message, MessageEmbed, MessagePayload } from 'discord.js' -import { DiscordClient } from '../types/customTypes' +import { MessageEmbed } from 'discord.js' +import { DiscordClient, DiscordMessage } from '../types/customTypes' const tx2 = require('tx2') /** @@ -10,7 +9,7 @@ const commandsCounter = tx2.counter({ name: 'Commands used', }) -exports.run = (client: DiscordClient, message: Message) => { +exports.run = (client: DiscordClient, message: DiscordMessage) => { /** * Only respond to messages sent by users. */ @@ -40,12 +39,12 @@ exports.run = (client: DiscordClient, message: Message) => { /** * Get language for user. */ - const userLanguage: string = client.getLanguage(message) ?? client.config.defaultLanguage + client.getLanguage(message) /** * Run the command. */ - executeCommand(message, commandfile, client, args, commandName, userLanguage) + executeCommand(message, commandfile, client, args, commandName) } } @@ -54,7 +53,7 @@ exports.run = (client: DiscordClient, message: Message) => { * @param {Message} message Message sent by user * @param {DiscordClient} client Bot-Client */ -function dmForwarding(message: Message, client: DiscordClient): void { +function dmForwarding(message: DiscordMessage, client: DiscordClient): void { /** * Payload containing info about the user and the message he sent. */ @@ -93,7 +92,7 @@ function dmForwarding(message: Message, client: DiscordClient): void { * @param {any} messagePayload {@link messagePayload} * @returns {MessageEmbed} */ -function userMessageEmbed(message: Message, messagePayload: any): MessageEmbed { +function userMessageEmbed(message: DiscordMessage, messagePayload: any): MessageEmbed { /** * Return {@link MessageEmbed} with information about the user and what he sent. */ @@ -115,7 +114,7 @@ function userMessageEmbed(message: Message, messagePayload: any): Messa * @returns {string} */ function getCommandData( - message: Message, + message: DiscordMessage, client: DiscordClient, ): { commandfile: any; args: string[]; commandName: string } { /** @@ -146,7 +145,7 @@ function getCommandData( } /** - * @param {Message} message Message sent by the user + * @param {DiscordMessage} message Message sent by the user * @param {any} commandfile Selected command * @param {DiscordClient} client Bot-Client * @param {string[]} args Arguments used by the user @@ -155,12 +154,11 @@ function getCommandData( * @returns {void} */ function executeCommand( - message: Message, + message: DiscordMessage, commandfile: any, client: DiscordClient, args: string[], commandName: string, - language: string, ): void { try { /** @@ -172,7 +170,7 @@ function executeCommand( * Runs the selected command. * Delete the message issuing the command after it replied successfully. */ - commandfile.run(client, message, language, args)?.then(msg => msg?.delete()) + commandfile.run(client, message, message.author.language, args)?.then(msg => msg?.delete()) /** * Increment the counter of issued commands since last restart. From 33ba92ee657a6172fed42d62104d5f55805e717c Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 26 Dec 2021 18:49:52 +0100 Subject: [PATCH 21/71] add basic structure of translations --- locales/de.json | 45 +++++++++++++++++++++++++++++++++++++++++++-- locales/en.json | 45 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/locales/de.json b/locales/de.json index 293d7b2..1067708 100644 --- a/locales/de.json +++ b/locales/de.json @@ -1,5 +1,46 @@ { - "devtest": { - "welcome": "hallo welt" + "commands": { + "admin": { + "missingPermission": "Du bist nicht berechtigt, diesen Befehl auszuführen.", + "devtest": {}, + "restart": { + "feedback": "🤖Starte neu..." + }, + "say": {}, + "status": { + "feedback": "👥Präsenz wurde geändert!" + } + }, + "fun": { + "fact": {}, + "komedi": {}, + "tenor": {} + }, + "tests": { + "hello": { + "welcome": "hallo welt" + } + }, + "utility": { + "antwortaufalles": {}, + "channelinfo": {}, + "command": {}, + "countdown": {}, + "git": {}, + "liftoff": {}, + "onlinecount": {}, + "ping": {}, + "start": {}, + "test": {}, + "uptime": {}, + "userprofile": {}, + "zoom": {} + } + }, + "slashCommands": { + "help": {}, + "issue": {}, + "ping": {}, + "wochenplan": {} } } \ No newline at end of file diff --git a/locales/en.json b/locales/en.json index 9729b7a..faf3aef 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1,5 +1,46 @@ { - "devtest": { - "welcome": "hello world" + "commands": { + "admin": { + "missingPermission": "You do not have permission to perform that command.", + "devtest": {}, + "restart": { + "feedback": "🤖Restarting..." + }, + "say": {}, + "status": { + "feedback": "👥Presence has been updated!" + } + }, + "fun": { + "fact": {}, + "komedi": {}, + "tenor": {} + }, + "tests": { + "hello": { + "welcome": "hello world" + } + }, + "utility": { + "antwortaufalles": {}, + "channelinfo": {}, + "command": {}, + "countdown": {}, + "git": {}, + "liftoff": {}, + "onlinecount": {}, + "ping": {}, + "start": {}, + "test": {}, + "uptime": {}, + "userprofile": {}, + "zoom": {} + } + }, + "slashCommands": { + "help": {}, + "issue": {}, + "ping": {}, + "wochenplan": {} } } \ No newline at end of file From b973ebcfff9f653f95373cfbd0d6f362b411cc87 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 26 Dec 2021 18:50:23 +0100 Subject: [PATCH 22/71] rename slashHelp --- slashCommands/{slashHelp.ts => help.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename slashCommands/{slashHelp.ts => help.ts} (100%) diff --git a/slashCommands/slashHelp.ts b/slashCommands/help.ts similarity index 100% rename from slashCommands/slashHelp.ts rename to slashCommands/help.ts From 696296a680d63d49f981546272456646ca8ed321 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 26 Dec 2021 18:50:42 +0100 Subject: [PATCH 23/71] rename slashPing --- slashCommands/{slashPing.ts => ping.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename slashCommands/{slashPing.ts => ping.ts} (100%) diff --git a/slashCommands/slashPing.ts b/slashCommands/ping.ts similarity index 100% rename from slashCommands/slashPing.ts rename to slashCommands/ping.ts From 228f05399702503bf40e537840f71ddf8daf2146 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 26 Dec 2021 18:51:03 +0100 Subject: [PATCH 24/71] rm stopbackupbot --- commands/admin/stopbackupbot.ts | 41 --------------------------------- 1 file changed, 41 deletions(-) delete mode 100644 commands/admin/stopbackupbot.ts diff --git a/commands/admin/stopbackupbot.ts b/commands/admin/stopbackupbot.ts deleted file mode 100644 index 919500b..0000000 --- a/commands/admin/stopbackupbot.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Message } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' -/** - * Const required, otherwise pm2 throws an error. - */ -const pm2 = require('pm2') - -exports.name = 'stopbackupbot' - -exports.description = 'stops backup bot' - -exports.usage = 'stopbackupbot' - -exports.run = (client: DiscordClient, message: Message) => { - /** - * Check if the user has the correct rights to execute the command. - */ - if (!Object.values(client.config.ids.acceptedAdmins).includes(message.author.id)) { - return client.reply(message, { content: 'You do not have the permissions to perform that command.' }) - } - - pm2Handle() - return client.send(message, { content: 'Stopping Backup Bot...' }) -} - -/** - * Pm2 restart handler. - * @description Connect to the pm2 interface and stops the backup process. - */ -function pm2Handle(): void { - pm2.connect(err => { - if (err) { - throw new Error(err) - } - try { - pm2.stop('ETIT-Chef', null) - } catch (error) { - throw new Error(error) - } - }) -} From 0b7b9379129d6673041a870fff0d53b8298454da Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 26 Dec 2021 18:51:31 +0100 Subject: [PATCH 25/71] change key --- commands/tests/hello.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/tests/hello.ts b/commands/tests/hello.ts index e7904e5..41d1678 100644 --- a/commands/tests/hello.ts +++ b/commands/tests/hello.ts @@ -11,7 +11,7 @@ exports.usage = 'hello' exports.aliases = ['hallo'] exports.run = (client: DiscordClient, message: Message, language: string) => { - const returnString = client.translate({ key: 'devtest.welcome', lng: language }) + const returnString = client.translate({ key: 'commands.tests.hello.welcome', lng: language }) return client.reply(message, { content: returnString }) } From 84daddd2b506288754fb0a4bc5434c0d469789c5 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 26 Dec 2021 18:55:17 +0100 Subject: [PATCH 26/71] use dynamic language selection --- commands/admin/restart.ts | 14 +++++++++----- commands/admin/say.ts | 14 ++++++++------ commands/admin/status.ts | 24 ++++++++++++++++-------- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/commands/admin/restart.ts b/commands/admin/restart.ts index e608695..9d96d38 100644 --- a/commands/admin/restart.ts +++ b/commands/admin/restart.ts @@ -1,5 +1,5 @@ -import { Message } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' + /** * Const required, otherwise pm2 throws an error. */ @@ -11,16 +11,20 @@ exports.description = '' exports.usage = 'restart' -exports.run = (client: DiscordClient, message: Message) => { +exports.run = (client: DiscordClient, message: DiscordMessage) => { /** * Check if user has the correct rights to execute the command. */ if (!Object.values(client.config.ids.acceptedAdmins).includes(message.author.id)) { - return client.reply(message, { content: 'You do not have the permissions to perform that command.' }) + return client.reply(message, { + content: client.translate({ key: 'commands.admin.missingPermission', lng: message.author.language }), + }) } pm2Handle() - return client.send(message, { content: '🤖Restarting...' }) + return client.send(message, { + content: client.translate({ key: 'commands.admin.restart.feedback', lng: message.author.language }), + }) } /** diff --git a/commands/admin/say.ts b/commands/admin/say.ts index fcf7888..5fd718b 100644 --- a/commands/admin/say.ts +++ b/commands/admin/say.ts @@ -1,5 +1,5 @@ -import { MessageEmbed, Message } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' +import { MessageEmbed } from 'discord.js' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' exports.name = 'say' @@ -7,12 +7,14 @@ exports.description = 'Der Bot sagt, was man ihm sagt, dass er sagen soll, weil exports.usage = 'say ' -exports.run = (client: DiscordClient, message: Message) => { +exports.run = (client: DiscordClient, message: DiscordMessage) => { /** * Check if user has the correct rights to execute the command. */ if (!Object.values(client.config.ids.acceptedAdmins).includes(message.author.id)) { - return client.reply(message, { content: 'You do not have the permissions to perform that command.' }) + return client.reply(message, { + content: client.translate({ key: 'commands.admin.missingPermission', lng: message.author.language }), + }) } /** @@ -30,11 +32,11 @@ exports.run = (client: DiscordClient, message: Message) => { /** * - * @param {Message} message command Message + * @param {DiscordMessage} message command Message * @param {DiscordClient} client Bot-Client * @returns {MessageEmbed} embed with given message.content */ -function createEmbed(message: Message, client: DiscordClient): MessageEmbed { +function createEmbed(message: DiscordMessage, client: DiscordClient): MessageEmbed { const messageContent = message.content.substring(message.content.indexOf(' ') + client.config.prefix.length) const embed = new MessageEmbed() diff --git a/commands/admin/status.ts b/commands/admin/status.ts index ae4de68..551c607 100644 --- a/commands/admin/status.ts +++ b/commands/admin/status.ts @@ -1,5 +1,5 @@ import { Message, PresenceData as setPresenceData, PresenceStatusData } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' exports.name = 'status' exports.description = 'Setzt den Status des Bottes' @@ -24,12 +24,14 @@ const presence: setPresenceData = { exports.presence = presence -exports.run = (client: DiscordClient, message: Message) => { +exports.run = (client: DiscordClient, message: DiscordMessage) => { /** * Check if user has the correct rights to execute the command. */ if (!Object.values(client.config.ids.acceptedAdmins).includes(message.author.id)) { - return client.reply(message, { content: 'You do not have the permissions to perform that command.' }) + return client.reply(message, { + content: client.translate({ key: 'commands.admin.missingPermission', lng: message.author.language }), + }) } /** @@ -37,7 +39,7 @@ exports.run = (client: DiscordClient, message: Message) => { */ let messageContent: string = message.content - messageContent = messageContent.split('.status')[1] + messageContent = messageContent.split(`${client.config.prefix}status`)[1] /** * Set activity name. @@ -84,12 +86,18 @@ function getPresenceStatusData(messageContent: string): PresenceStatusData { } /** - * * @param {DiscordClient} client {@link DiscordClient} - * @param {Message} message Command {@link Message} + * @param {DiscordMessage} message Command {@link Message} * @param {setPresenceData} _presence {@link setPresenceData} + * @returns {Promise>} */ -function setPresenceData(client: DiscordClient, message: Message, _presence: setPresenceData): void { +function setPresenceData( + client: DiscordClient, + message: DiscordMessage, + _presence: setPresenceData, +): Promise> { client.user.setPresence(_presence) - message.channel.send('👥Präsenz wurde geupdated!') + return client.send(message, { + content: client.translate({ key: 'commands.admin.status.feedback', lng: message.author.language }), + }) } From 05950fe779200bb87ac7984d830a9dff358c7fdc Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 26 Dec 2021 23:16:25 +0100 Subject: [PATCH 27/71] fix options --- types/customTypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/customTypes.ts b/types/customTypes.ts index 39ce791..ff7db8a 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -137,7 +137,7 @@ export class DiscordClient extends Client { * @returns {string} */ public translate(args: translation_options): string { - const options = args.options ?? args.lng ? { lng: args.lng } : null + const options = args.options ?? { lng: args.lng ?? 'en' } return i18next.t(args.key, options) } } From 247190cbf035c2d5af7919bd511939679d9774ba Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Sun, 26 Dec 2021 23:21:31 +0100 Subject: [PATCH 28/71] add automatic translation --- commands/fun/fact.ts | 8 ++++---- commands/fun/tenor.ts | 20 ++++++++++++++------ locales/de.json | 9 +++++++-- locales/en.json | 9 +++++++-- 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/commands/fun/fact.ts b/commands/fun/fact.ts index 41c424e..5f14ac4 100644 --- a/commands/fun/fact.ts +++ b/commands/fun/fact.ts @@ -1,6 +1,6 @@ import { readFileSync } from 'fs' -import { Message, MessageEmbed } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' +import { MessageEmbed } from 'discord.js' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' const FACTS_FILE = './data/facts.txt' @@ -10,7 +10,7 @@ exports.description = 'Willst du Fakten? Dann bist du hier genau richtig.' exports.usage = 'fact' -exports.run = (client: DiscordClient, message: Message) => { +exports.run = (client: DiscordClient, message: DiscordMessage) => { /** * Read data from facts file. * @type {string} @@ -29,7 +29,7 @@ exports.run = (client: DiscordClient, message: Message) => { return client.send(message, { embeds: [ new MessageEmbed() - .setTitle('🧠Fact') + .setTitle(client.translate({ key: 'commands.fun.fact.feedback', lng: message.author.language })) .setDescription(fact) .setFooter(message.author.tag, message.author.avatarURL({ dynamic: true })), ], diff --git a/commands/fun/tenor.ts b/commands/fun/tenor.ts index fddfe9e..39d63f6 100644 --- a/commands/fun/tenor.ts +++ b/commands/fun/tenor.ts @@ -1,6 +1,6 @@ // eslint-disable-next-line @typescript-eslint/no-unused-vars import { MessageEmbed, Message, MessageMentions, UserMention, MessageEmbedFooter } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' exports.name = 'tenor' @@ -10,7 +10,7 @@ exports.usage = `tenor ` exports.aliases = ['gif'] -exports.run = (client: DiscordClient, message: Message, language: string, args: string[]) => { +exports.run = (client: DiscordClient, message: DiscordMessage, language: string, args: string[]) => { /** * Get {@link UserMention} from message. * @type {string} @@ -26,7 +26,9 @@ exports.run = (client: DiscordClient, message: Message, language: string, args: * Send reply. */ return searchQuery.length === 0 - ? client.send(message, { content: 'Bitte gebe einen suchwort an!' }) + ? client.send(message, { + content: client.translate({ key: 'commands.fun.tenor.ErrorMissingSearchQuery', lng: message.author.language }), + }) : queryTenorAndReply(client, searchQuery, message, userPing) } @@ -49,14 +51,14 @@ function removeMatching(originalArray: string[], regex: RegExp): string[] { * Query the Tenor-API and send a reply with a random GIF. * @param {DiscordClient} client Bot-Client. * @param {string} searchQuery Query to search for with the tenor api - * @param {Message} message Command-message to respond to + * @param {DiscordMessage} message Command-message to respond to * @param {string} userPing User to mention * @returns {any} */ function queryTenorAndReply( client: DiscordClient, searchQuery: string, - message: Message, + message: DiscordMessage, userPing: string, ): any { /** @@ -81,9 +83,15 @@ function queryTenorAndReply( * Set image of embed if Tenor query returned any. * If no results have been returned, set Description to tell user that nothing has been found. */ + // ? embed.setDescription(`<@${message.author.id}> Es konnten keine Gifs gefunden werden für: '${searchQuery}'`) embed = Results.length === 0 - ? embed.setDescription(`<@${message.author.id}> Es konnten keine Gifs gefunden werden für: '${searchQuery}'`) + ? embed.setDescription( + client.translate({ + key: 'commands.fun.tenor.ErrorNoGifsFound', + options: { userID: message.author.id, searchQuery: searchQuery, lng: message.author.language }, + }), + ) : embed.setImage(Results[0].media.find(element => Object.prototype.hasOwnProperty.call(element, 'gif')).gif.url) /** diff --git a/locales/de.json b/locales/de.json index 1067708..7350a82 100644 --- a/locales/de.json +++ b/locales/de.json @@ -12,9 +12,14 @@ } }, "fun": { - "fact": {}, + "fact": { + "feedback": "🧠Fakt" + }, "komedi": {}, - "tenor": {} + "tenor": { + "ErrorMissingSearchQuery": "Bitte gebe ein suchwort an!", + "ErrorNoGifsFound": "<@{{userID}}> Es konnten keine Gifs gefunden werden für : '{{searchQuery}}'" + } }, "tests": { "hello": { diff --git a/locales/en.json b/locales/en.json index faf3aef..c24b750 100644 --- a/locales/en.json +++ b/locales/en.json @@ -12,9 +12,14 @@ } }, "fun": { - "fact": {}, + "fact": { + "feedback": "🧠Fact" + }, "komedi": {}, - "tenor": {} + "tenor": { + "ErrorMissingSearchQuery": "Please enter a search query!", + "ErrorNoGifsFound": "<@{{userID}}> No Gifs have been found for : '{{searchQuery}}'" + } }, "tests": { "hello": { From ad92fa8a285d309dc17ec2fd297eab3eb426a57d Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 27 Dec 2021 21:18:06 +0100 Subject: [PATCH 29/71] shorten locales --- commands/admin/restart.ts | 2 +- commands/admin/status.ts | 2 +- commands/fun/fact.ts | 2 +- locales/de.json | 18 +++++++----------- locales/en.json | 18 +++++++----------- 5 files changed, 17 insertions(+), 25 deletions(-) diff --git a/commands/admin/restart.ts b/commands/admin/restart.ts index 9d96d38..97f44ce 100644 --- a/commands/admin/restart.ts +++ b/commands/admin/restart.ts @@ -23,7 +23,7 @@ exports.run = (client: DiscordClient, message: DiscordMessage) => { pm2Handle() return client.send(message, { - content: client.translate({ key: 'commands.admin.restart.feedback', lng: message.author.language }), + content: client.translate({ key: 'commands.admin.restart', lng: message.author.language }), }) } diff --git a/commands/admin/status.ts b/commands/admin/status.ts index 551c607..90264dc 100644 --- a/commands/admin/status.ts +++ b/commands/admin/status.ts @@ -98,6 +98,6 @@ function setPresenceData( ): Promise> { client.user.setPresence(_presence) return client.send(message, { - content: client.translate({ key: 'commands.admin.status.feedback', lng: message.author.language }), + content: client.translate({ key: 'commands.admin.status', lng: message.author.language }), }) } diff --git a/commands/fun/fact.ts b/commands/fun/fact.ts index 5f14ac4..942f06c 100644 --- a/commands/fun/fact.ts +++ b/commands/fun/fact.ts @@ -29,7 +29,7 @@ exports.run = (client: DiscordClient, message: DiscordMessage) => { return client.send(message, { embeds: [ new MessageEmbed() - .setTitle(client.translate({ key: 'commands.fun.fact.feedback', lng: message.author.language })) + .setTitle(client.translate({ key: 'commands.fun.fact', lng: message.author.language })) .setDescription(fact) .setFooter(message.author.tag, message.author.avatarURL({ dynamic: true })), ], diff --git a/locales/de.json b/locales/de.json index 7350a82..fdf0867 100644 --- a/locales/de.json +++ b/locales/de.json @@ -3,18 +3,12 @@ "admin": { "missingPermission": "Du bist nicht berechtigt, diesen Befehl auszuführen.", "devtest": {}, - "restart": { - "feedback": "🤖Starte neu..." - }, + "restart": "🤖Starte neu...", "say": {}, - "status": { - "feedback": "👥Präsenz wurde geändert!" - } + "status": "👥Präsenz wurde geändert!" }, "fun": { - "fact": { - "feedback": "🧠Fakt" - }, + "fact": "🧠Fakt", "komedi": {}, "tenor": { "ErrorMissingSearchQuery": "Bitte gebe ein suchwort an!", @@ -27,8 +21,10 @@ } }, "utility": { - "antwortaufalles": {}, - "channelinfo": {}, + "antwortaufalles": "Die Antwort auf die Frage nach dem Leben, dem Universum und dem ganzen Rest ist :four::two:", + "channelinfo": { + "ErrorNotAvailable": "Kanalinformationen sind in diesem Kanal nicht verfügbar. Versuche es mit einem anderen Kanal." + }, "command": {}, "countdown": {}, "git": {}, diff --git a/locales/en.json b/locales/en.json index c24b750..c23b046 100644 --- a/locales/en.json +++ b/locales/en.json @@ -3,18 +3,12 @@ "admin": { "missingPermission": "You do not have permission to perform that command.", "devtest": {}, - "restart": { - "feedback": "🤖Restarting..." - }, + "restart": "🤖Restarting...", "say": {}, - "status": { - "feedback": "👥Presence has been updated!" - } + "status": "👥Presence has been updated!" }, "fun": { - "fact": { - "feedback": "🧠Fact" - }, + "fact": "🧠Fact", "komedi": {}, "tenor": { "ErrorMissingSearchQuery": "Please enter a search query!", @@ -27,8 +21,10 @@ } }, "utility": { - "antwortaufalles": {}, - "channelinfo": {}, + "antwortaufalles": "The answer to the question about life, the universe, and all the rest is :four: :two:", + "channelinfo": { + "ErrorNotAvailable": "Channel info is not available in this channel. Try a different channel." + }, "command": {}, "countdown": {}, "git": {}, From df50a37f26979737ad1a4171116432144ff23bc1 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 27 Dec 2021 21:18:27 +0100 Subject: [PATCH 30/71] add translation --- commands/utility/antwortaufalles.ts | 8 ++++---- commands/utility/channelinfo.ts | 13 +++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/commands/utility/antwortaufalles.ts b/commands/utility/antwortaufalles.ts index d5742b7..8bbcb3f 100644 --- a/commands/utility/antwortaufalles.ts +++ b/commands/utility/antwortaufalles.ts @@ -1,5 +1,5 @@ -import { Message, MessageEmbed } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' +import { MessageEmbed } from 'discord.js' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' exports.name = 'antwortaufalles' @@ -7,14 +7,14 @@ exports.description = 'Was ist die Antwort auf alles?' exports.usage = 'antwortaufalles' -exports.run = (client: DiscordClient, message: Message) => +exports.run = (client: DiscordClient, message: DiscordMessage) => /** * Reply with the anwer to everything. */ client.reply(message, { embeds: [ new MessageEmbed().setDescription( - 'Die Antwort auf die Frage nach dem Leben, dem Universum und dem ganzen Rest ist :four::two:', + client.translate({ key: 'commands.utility.antwortaufalles', lng: message.author.language }), ), ], }) diff --git a/commands/utility/channelinfo.ts b/commands/utility/channelinfo.ts index a0177cd..0616084 100644 --- a/commands/utility/channelinfo.ts +++ b/commands/utility/channelinfo.ts @@ -1,7 +1,6 @@ import { Channel, GuildMember, - Message, MessageEmbed, MessageMentions, NewsChannel, @@ -9,14 +8,14 @@ import { TextChannel, ThreadChannel, } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' exports.name = 'channelinfo' exports.description = 'Displays some information about the channel and its users.' exports.usage = 'channelinfo {#channel}' -exports.run = async (client: DiscordClient, message: Message, language: string, args: string[]) => { +exports.run = async (client: DiscordClient, message: DiscordMessage, language: string, args: string[]) => { /** * Channel to display information about. */ @@ -55,7 +54,9 @@ exports.run = async (client: DiscordClient, message: Message, language: string, */ return client.reply(message, { embeds: [ - new MessageEmbed().setDescription('Nicht in diesem Kanal verfügbar. Probiere es doch in einem anderen Kanal.'), + new MessageEmbed().setDescription( + client.translate({ key: 'commands.utility.channelinfo.ErrorNotAvailable', lng: message.author.language }), + ), ], }) } @@ -65,13 +66,13 @@ exports.run = async (client: DiscordClient, message: Message, language: string, * Helper function to get channel. * @param { string[] } args message arguments * @param { DiscordClient } client Bot client - * @param { Message } message issued command message + * @param { DiscordMessage } message issued command message * @returns { Channel | PartialDMChannel | TextChannel | NewsChannel | ThreadChannel } */ async function getChannel( args: string[], client: DiscordClient, - message: Message, + message: DiscordMessage, ): Promise { const _channel = args.find(value => MessageMentions.CHANNELS_PATTERN.test(value))?.slice(2, -1) const CHANNEL = _channel ? await client.channels.fetch(_channel) : message.channel From 394d7a03041bad1e506aca3403a6b057e50b8b57 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 27 Dec 2021 21:39:09 +0100 Subject: [PATCH 31/71] fix parameters and message deleting error --- events/messageCreate.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/events/messageCreate.ts b/events/messageCreate.ts index 6fe7613..931ba30 100644 --- a/events/messageCreate.ts +++ b/events/messageCreate.ts @@ -170,7 +170,9 @@ function executeCommand( * Runs the selected command. * Delete the message issuing the command after it replied successfully. */ - commandfile.run(client, message, message.author.language, args)?.then(msg => msg?.delete()) + commandfile.run(client, message, args)?.then(msg => { + if (msg?.deletable) msg?.delete() + }) /** * Increment the counter of issued commands since last restart. From 80659c5f4aea59df97984be5ac2a1c76e9840851 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 27 Dec 2021 21:39:49 +0100 Subject: [PATCH 32/71] fix error if user used commands in dms --- types/customTypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/customTypes.ts b/types/customTypes.ts index ff7db8a..0a46c26 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -119,7 +119,7 @@ export class DiscordClient extends Client { /** * Return language if match is found. */ - if (message.member.roles.cache.some(role => role.name === language)) { + if (message.member?.roles?.cache.some(role => role.name === language)) { return (message.author.language = language) } } From 4d84341c2276293aecb31d99e498d0d9a84cb63c Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 27 Dec 2021 21:40:09 +0100 Subject: [PATCH 33/71] add translation --- commands/utility/channelinfo.ts | 13 +++++++++++-- locales/de.json | 1 + locales/en.json | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/commands/utility/channelinfo.ts b/commands/utility/channelinfo.ts index 0616084..b974bd2 100644 --- a/commands/utility/channelinfo.ts +++ b/commands/utility/channelinfo.ts @@ -15,7 +15,7 @@ exports.description = 'Displays some information about the channel and its users exports.usage = 'channelinfo {#channel}' -exports.run = async (client: DiscordClient, message: DiscordMessage, language: string, args: string[]) => { +exports.run = async (client: DiscordClient, message: DiscordMessage, args: string[]) => { /** * Channel to display information about. */ @@ -43,7 +43,16 @@ exports.run = async (client: DiscordClient, message: DiscordMessage, language: s embeds: [ new MessageEmbed() .setAuthor({ name: client.user.tag, iconURL: client.user.avatarURL() }) - .setTitle(`Anzahl an Kanalmitgliedern: ${CHANNEL.members.size.toString()}\nin ${CHANNEL.name}`) + .setTitle( + client.translate({ + key: 'commands.utility.channelinfo.Answer', + options: { + memberNumber: CHANNEL.members.size.toString(), + channelName: CHANNEL.name, + lng: message.author.language, + }, + }), + ) .setColor('BLURPLE') .setDescription(cutUserList), ], diff --git a/locales/de.json b/locales/de.json index fdf0867..faf5696 100644 --- a/locales/de.json +++ b/locales/de.json @@ -23,6 +23,7 @@ "utility": { "antwortaufalles": "Die Antwort auf die Frage nach dem Leben, dem Universum und dem ganzen Rest ist :four::two:", "channelinfo": { + "Answer": "Anzahl an Kanalmitgliedern in: {{memberNumber}}\nin {{channelName}}.", "ErrorNotAvailable": "Kanalinformationen sind in diesem Kanal nicht verfügbar. Versuche es mit einem anderen Kanal." }, "command": {}, diff --git a/locales/en.json b/locales/en.json index c23b046..142ecfa 100644 --- a/locales/en.json +++ b/locales/en.json @@ -23,6 +23,7 @@ "utility": { "antwortaufalles": "The answer to the question about life, the universe, and all the rest is :four: :two:", "channelinfo": { + "Answer": "Number of channel members: {{memberNumber}}\nin {{channelName}}.", "ErrorNotAvailable": "Channel info is not available in this channel. Try a different channel." }, "command": {}, From eeef7ccb60ed3464d6a7141ddaa255f1b5591c2e Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 27 Dec 2021 22:54:37 +0100 Subject: [PATCH 34/71] bump dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index e5d5f5e..2f29971 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "author": "Christoph Bluem", "dependencies": { "discord-api-types": "^0.26.0", - "discord.js": "^13.5.0-dev.1640520180.f1d35e3", + "discord.js": "^13.5.0-dev.1640563809.d0c3961", "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.25.3", "eslint-plugin-prettier": "^4.0.0", @@ -32,8 +32,8 @@ "valid-url": "^1.0.9" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^5.8.0", - "@typescript-eslint/parser": "^5.8.0", + "@typescript-eslint/eslint-plugin": "^5.8.1", + "@typescript-eslint/parser": "^5.8.1", "eslint": "^8.5.0" } } From 1a6f65bac70afb23e5d587790e82cf0e3eae198c Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 27 Dec 2021 22:55:05 +0100 Subject: [PATCH 35/71] add translation --- commands/utility/command.ts | 44 +++++++++++++++++++++++++------------ locales/de.json | 8 ++++++- locales/en.json | 8 ++++++- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/commands/utility/command.ts b/commands/utility/command.ts index 927f8d6..d981426 100644 --- a/commands/utility/command.ts +++ b/commands/utility/command.ts @@ -1,5 +1,5 @@ -import { Message, MessageEmbed } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' +import { MessageEmbed } from 'discord.js' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' exports.name = 'command' @@ -11,35 +11,45 @@ exports.example = 'command test' exports.aliases = ['commandinfo'] -exports.run = (client: DiscordClient, message: Message, args: any): any => { +exports.run = (client: DiscordClient, message: DiscordMessage, args: any): any => { /** * Check if user provided a command name. */ - if (args.length === 0) return client.send(message, { content: 'Please provide arguments!' }) + if (args.length === 0) { + return client.send(message, { + content: client.translate({ key: 'commands.utility.command.ErrorNoCommandName', lng: message.author.language }), + }) + } for (const [key, value] of client.commands.entries()) { if (key === args[0].toLowerCase() || findAliases(value.aliases, args)) { - const commandHelpEmbed = createEmbed(value, client) + const commandHelpEmbed = createEmbed(value, client, message) return client.reply(message, { embeds: [commandHelpEmbed] }) } } - return client.send(message, { content: 'Bitte verwende einen Commandnamen.' }) + return client.send(message, { + content: client.translate({ key: 'commands.utility.command.ErrorNoCommandName', lng: message.author.language }), + }) } /** * Creates an Embed with the provided information. * @param {any} value Information about the command * @param {DiscordClient} client Bot-Client + * @param {DiscordMessage} message Message sent by user * @returns {MessageEmbed} */ -function createEmbed(value: any, client: DiscordClient): MessageEmbed { +function createEmbed(value: any, client: DiscordClient, message: DiscordMessage): MessageEmbed { /** * Embed with command information. */ const embed = new MessageEmbed() .setColor('#7289ea') - .setAuthor({ name: 'Befehlshilfe', iconURL: 'https://bit.ly/30ZO6jh' }) + .setAuthor({ + name: client.translate({ key: 'commands.utility.command.CommandHelp', lng: message.author.language }), + iconURL: 'https://bit.ly/30ZO6jh', + }) .setThumbnail(client.user.avatarURL()) .setTitle(`‎${value.name}\n ‎`) @@ -47,7 +57,7 @@ function createEmbed(value: any, client: DiscordClient): MessageEmbed { * Loop through all aliases of the command and add them to the Embed. */ if (value.aliases && value.aliases.length > 0) { - addAliasesToEmbed(value.aliases, embed) + addAliasesToEmbed(value.aliases, embed, client, message) } /** @@ -55,12 +65,12 @@ function createEmbed(value: any, client: DiscordClient): MessageEmbed { */ embed.addFields( { - name: 'Beschreibung', + name: client.translate({ key: 'commands.utility.command.Description', lng: message.author.language }), value: `${value.description}\n‎ ‎`, inline: false, }, { - name: 'Benutzung:', + name: client.translate({ key: 'commands.utility.command.Usage', lng: message.author.language }), value: `${client.config.prefix}${value.usage}\n ‎`, inline: false, }, @@ -87,10 +97,16 @@ function findAliases(aliasesArray: any, args: any): boolean { * * @param {Array} aliasesArray array of aliases exported * @param {Object} embed command embed - * @param {Array} args arguments of issued command + * @param {DiscordClient} client Bot-Client + * @param {DiscordMessage} message Message sent by user * @returns {MessageEmbed} commandHelpEmbed with added aliases */ -function addAliasesToEmbed(aliasesArray: any, embed: any): MessageEmbed { +function addAliasesToEmbed( + aliasesArray: any, + embed: any, + client: DiscordClient, + message: DiscordMessage, +): MessageEmbed { /** * String of aliases seperated by commas. */ @@ -100,7 +116,7 @@ function addAliasesToEmbed(aliasesArray: any, embed: any): MessageEmbed { * Add the string of aliases to {@link embed} */ embed.addFields({ - name: 'Aliase', + name: client.translate({ key: 'commands.utility.command.Aliases', lng: message.author.language }), value: `${aliasesString}\n `, inline: false, }) diff --git a/locales/de.json b/locales/de.json index faf5696..eb93df3 100644 --- a/locales/de.json +++ b/locales/de.json @@ -26,7 +26,13 @@ "Answer": "Anzahl an Kanalmitgliedern in: {{memberNumber}}\nin {{channelName}}.", "ErrorNotAvailable": "Kanalinformationen sind in diesem Kanal nicht verfügbar. Versuche es mit einem anderen Kanal." }, - "command": {}, + "command": { + "ErrorNoCommandName": "Bitte gebe einen Befehlsnamen an.", + "CommandHelp": "Befehlshilfe", + "Description": "Beschreibung", + "Usage": "Benutzung", + "Aliases": "Aliase" + }, "countdown": {}, "git": {}, "liftoff": {}, diff --git a/locales/en.json b/locales/en.json index 142ecfa..0ac9710 100644 --- a/locales/en.json +++ b/locales/en.json @@ -26,7 +26,13 @@ "Answer": "Number of channel members: {{memberNumber}}\nin {{channelName}}.", "ErrorNotAvailable": "Channel info is not available in this channel. Try a different channel." }, - "command": {}, + "command": { + "ErrorNoCommandName": "Please provide a command name.", + "CommandHelp": "Command assistance", + "Description": "Description", + "Usage": "Usage", + "Aliases": "Aliases" + }, "countdown": {}, "git": {}, "liftoff": {}, From 23314b4de931cb48a1ad4a30cbfa51b75b6d7fef Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Wed, 29 Dec 2021 21:43:00 +0100 Subject: [PATCH 36/71] add translation --- commands/utility/countdown.ts | 35 ++++++++++++++++++++++++----------- locales/de.json | 6 +++++- locales/en.json | 6 +++++- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/commands/utility/countdown.ts b/commands/utility/countdown.ts index 737b343..954b046 100644 --- a/commands/utility/countdown.ts +++ b/commands/utility/countdown.ts @@ -1,5 +1,5 @@ -import { Message, MessageEmbed } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' +import { MessageEmbed } from 'discord.js' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' exports.name = 'countdown' @@ -7,39 +7,41 @@ exports.description = 'Ein simpler countdown von 10 runter' exports.usage = 'countdown' -exports.run = async (client: DiscordClient, message: Message) => { +exports.run = async (client: DiscordClient, message: DiscordMessage) => { /** * Embed template. */ const msgEmbed = new MessageEmbed() - .setTitle('Liftoff in:') + .setTitle(client.translate({ key: 'commands.utility.countdown.Countdown', lng: message.author.language })) .setFooter(message.author.tag, message.author.avatarURL({ dynamic: true })) .setThumbnail('https://upload.wikimedia.org/wikipedia/commons/3/33/Cartoon_space_rocket.png') /** * Reply with the embed and set the description. */ - const msg = await message + const msg = (await message .reply({ embeds: [msgEmbed.setDescription(`🚀10🚀`)], }) .then(_msg => { message.delete() return _msg - }) + })) as DiscordMessage /** * Update the embed to count down from 10. */ - editEmbed(msg, msgEmbed) + editEmbed(msg, msgEmbed, client) } + /** * Edit the embed to display a countdown. - * @param {Message} msg Message of the reply with the embed + * @param {DiscordMessage} msg Message of the reply with the embed * @param {MessageEmbed} msgEmbed The embed to edit and attatch + * @param {DiscordMessage} client Bot-Client * @returns {void} */ -function editEmbed(msg: Message, msgEmbed: MessageEmbed): void { +function editEmbed(msg: DiscordMessage, msgEmbed: MessageEmbed, client: DiscordClient): void { /** * Count only 8, 6, 4, 3, 2, 1, 0 and skips 9, 7, 5 due to API limits. */ @@ -52,8 +54,19 @@ function editEmbed(msg: Message, msgEmbed: MessageEmbed): void { } } else { setTimeout(() => { - if (i === 0) msg.edit({ embeds: [msgEmbed.setTitle('Abfluuug').setDescription(`🚀Abgehoben🚀`)] }) - else msg.edit({ embeds: [msgEmbed.setDescription(`🚀${i}🚀`)] }) + if (i === 0) { + msg.edit({ + embeds: [ + msgEmbed + .setTitle('Abfluuug') + .setDescription( + client.translate({ key: 'commands.utility.countdown.Liftoff', lng: msg.author.language }), + ), + ], + }) + } else { + msg.edit({ embeds: [msgEmbed.setDescription(`🚀${i}🚀`)] }) + } }, 1000 * (10 - i)) } } diff --git a/locales/de.json b/locales/de.json index eb93df3..b1a6cbb 100644 --- a/locales/de.json +++ b/locales/de.json @@ -33,7 +33,11 @@ "Usage": "Benutzung", "Aliases": "Aliase" }, - "countdown": {}, + "countdown": { + "Countdown": "Fahrstuhl aus in:", + "Departure": "Abfluuuug", + "Liftoff": "🚀Abgehoben🚀" + }, "git": {}, "liftoff": {}, "onlinecount": {}, diff --git a/locales/en.json b/locales/en.json index 0ac9710..f4a79c4 100644 --- a/locales/en.json +++ b/locales/en.json @@ -33,7 +33,11 @@ "Usage": "Usage", "Aliases": "Aliases" }, - "countdown": {}, + "countdown": { + "Countdown": "Liftoff in:", + "Departure": "Departuuuure", + "Liftoff": "🚀Departed🚀" + }, "git": {}, "liftoff": {}, "onlinecount": {}, From 395cfae41d78e803b8f9f98ecec6d3877fee5c69 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Wed, 29 Dec 2021 21:44:35 +0100 Subject: [PATCH 37/71] fix translation --- commands/utility/countdown.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/utility/countdown.ts b/commands/utility/countdown.ts index 954b046..0c05782 100644 --- a/commands/utility/countdown.ts +++ b/commands/utility/countdown.ts @@ -58,7 +58,7 @@ function editEmbed(msg: DiscordMessage, msgEmbed: MessageEmbed, client: DiscordC msg.edit({ embeds: [ msgEmbed - .setTitle('Abfluuug') + .setTitle(client.translate({ key: 'commands.utility.countdown.Departure', lng: msg.author.language })) .setDescription( client.translate({ key: 'commands.utility.countdown.Liftoff', lng: msg.author.language }), ), From 9a34423a0571a93876af0d912f2abc336120c035 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Wed, 29 Dec 2021 21:44:46 +0100 Subject: [PATCH 38/71] bump dependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 2f29971..9eeb1be 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,13 @@ "author": "Christoph Bluem", "dependencies": { "discord-api-types": "^0.26.0", - "discord.js": "^13.5.0-dev.1640563809.d0c3961", + "discord.js": "^14.0.0-dev.1640779371.9cdc448", "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.25.3", "eslint-plugin-prettier": "^4.0.0", "fs": "^0.0.1-security", "github-create-issue": "^1.0.1", - "i18next": "^21.6.3", + "i18next": "^21.6.4", "i18next-fs-backend": "^1.1.4", "luxon": "^2.2.0", "moment": "^2.29.1", From 17fdcb99fa964ff9e5ee2c74a236e4c918cc24de Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Wed, 29 Dec 2021 22:00:26 +0100 Subject: [PATCH 39/71] update footer --- scripts/loginMessage.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/loginMessage.ts b/scripts/loginMessage.ts index 65e7954..8cf098c 100644 --- a/scripts/loginMessage.ts +++ b/scripts/loginMessage.ts @@ -86,10 +86,10 @@ function createEmbed(client: DiscordClient, commands: any[], slashCount: string[ }, ) .setTimestamp() - .setFooter( - `[ID] ${client.config.ids.userID.botUserID} \nstarted`, - 'https://image.flaticon.com/icons/png/512/888/888879.png', - ) + .setFooter({ + text: `[ID] ${client.config.ids.userID.botUserID} \nstarted`, + iconURL: 'https://image.flaticon.com/icons/png/512/888/888879.png', + }) } /** * Count commands. From 48d6edc7913910320901c9264a3c376b3c5b8546 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Wed, 29 Dec 2021 22:00:50 +0100 Subject: [PATCH 40/71] add translation to git --- commands/utility/git.ts | 31 +++++++++++++++++++------------ locales/de.json | 6 +++++- locales/en.json | 6 +++++- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/commands/utility/git.ts b/commands/utility/git.ts index ea6420b..3b74424 100644 --- a/commands/utility/git.ts +++ b/commands/utility/git.ts @@ -1,5 +1,5 @@ -import { MessageEmbed, Message } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' +import { MessageEmbed } from 'discord.js' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' const gitlab = 'https://git.scc.kit.edu' const github = 'https://git.io/J3Vao' @@ -10,11 +10,11 @@ exports.description = 'Link zum KIT Gitlab und zur Repository' exports.usage = 'git' -exports.run = (client: DiscordClient, message: Message) => { +exports.run = (client: DiscordClient, message: DiscordMessage) => { /** * Embed containing information about git. */ - const gitEmbed = createEmbed(client) + const gitEmbed = createEmbed(client, message) return client.reply(message, { embeds: [gitEmbed.setTimestamp()] }) } @@ -24,24 +24,31 @@ exports.run = (client: DiscordClient, message: Message) => { * URL of the embed leads to the git-documentation. * Seperate links to the repository of the bot and to the university gitlab. * @param {DiscordClient} client Bot-Client + * @param {DiscordMessage} message Message sent by user * @returns {MessageEmbed} */ -function createEmbed(client: DiscordClient): MessageEmbed { +function createEmbed(client: DiscordClient, message: DiscordMessage): MessageEmbed { return new MessageEmbed() .setColor('#ffa500') .setAuthor({ name: client.user.tag, iconURL: 'https://git-scm.com/images/logos/downloads/Git-Icon-1788C.png' }) .setThumbnail('https://git-scm.com/images/logos/downloads/Git-Icon-1788C.png') - .setTitle('[🌐] GIT Wiki') + .setTitle(client.translate({ key: 'commands.utility.git.Title', lng: message.author.language })) .setURL('https://git-scm.com/book/en/v2') .addFields( { name: 'Gitlab:', - value: `[Link](${gitlab}) zur Gitlab Startseite`, + value: client.translate({ + key: 'commands.utility.git.Gitlab', + options: { gitlab: gitlab, lng: message.author.language }, + }), inline: false, }, { name: `Github:`, - value: `Github [Repository](${github}) von <@${client.config.ids.userID.botUserID}>`, + value: client.translate({ + key: 'commands.utility.git.Github', + options: { github: github, userID: client.user.id, lng: message.author.language }, + }), inline: false, }, { @@ -49,8 +56,8 @@ function createEmbed(client: DiscordClient): MessageEmbed { value: '\u200B', }, ) - .setFooter( - `[ID] ${client.config.ids.userID.botUserID} \n`, - 'https://about.gitlab.com/images/press/logo/png/gitlab-icon-rgb.png', - ) + .setFooter({ + text: `[ID] ${client.user.id} \n`, + iconURL: 'https://about.gitlab.com/images/press/logo/png/gitlab-icon-rgb.png', + }) } diff --git a/locales/de.json b/locales/de.json index b1a6cbb..acfedd9 100644 --- a/locales/de.json +++ b/locales/de.json @@ -38,7 +38,11 @@ "Departure": "Abfluuuug", "Liftoff": "🚀Abgehoben🚀" }, - "git": {}, + "git": { + "Title": "[🌐] GIT Wiki", + "Gitlab": "[Link]({{gitlab}}) zur Gitlab Startseite", + "Github": "Github [Repository]({{github}}) von <@{{userID}}>" + }, "liftoff": {}, "onlinecount": {}, "ping": {}, diff --git a/locales/en.json b/locales/en.json index f4a79c4..7b5bf9b 100644 --- a/locales/en.json +++ b/locales/en.json @@ -38,7 +38,11 @@ "Departure": "Departuuuure", "Liftoff": "🚀Departed🚀" }, - "git": {}, + "git": { + "Title": "[🌐] GIT Wiki", + "Gitlab": "[Link]({{gitlab}}) to Gitlab Homepage", + "Github": "Github [Repository]({{github}}) of <@{{userID}}>" + }, "liftoff": {}, "onlinecount": {}, "ping": {}, From 895e4c6c1636b620af0c126988df32b35d132f43 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Wed, 29 Dec 2021 22:01:40 +0100 Subject: [PATCH 41/71] delete liftoff --- commands/utility/liftoff.ts | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 commands/utility/liftoff.ts diff --git a/commands/utility/liftoff.ts b/commands/utility/liftoff.ts deleted file mode 100644 index 1915baa..0000000 --- a/commands/utility/liftoff.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Message, MessageEmbed } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' -exports.name = 'liftoff' - -exports.description = 'Liftoff celebration' - -exports.usage = 'liftoff' - -exports.run = (client: DiscordClient, message: Message) => - /** - * Reply with a liftoff celebration. - */ - client.send(message, { - embeds: [ - new MessageEmbed() - .setTitle('Hurraaa 🚀🚀') - .setFooter(message.author.tag, message.author.avatarURL({ dynamic: true })), - ], - }) From e448dddd0fb23d9afa5cd50999ddcfdbbab8c98b Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 09:34:33 +0100 Subject: [PATCH 42/71] add translation to onlinecount --- commands/utility/onlinecount.ts | 30 ++++++++++++++++++++---------- locales/de.json | 8 ++++++-- locales/en.json | 8 ++++++-- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/commands/utility/onlinecount.ts b/commands/utility/onlinecount.ts index 29fc96d..f10cfd9 100644 --- a/commands/utility/onlinecount.ts +++ b/commands/utility/onlinecount.ts @@ -1,12 +1,12 @@ -import { Message, MessageEmbed } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' +import { MessageEmbed } from 'discord.js' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' exports.name = 'onlinecount' exports.description = 'Zeigt an, wie viele Leute online, idle und auf dnd sind.' exports.usage = 'onlinecount' -exports.run = async (client: DiscordClient, message: Message) => { +exports.run = async (client: DiscordClient, message: DiscordMessage) => { /** * Numbers of online, idle and dnd members. */ @@ -15,7 +15,7 @@ exports.run = async (client: DiscordClient, message: Message) => { /** * Embed with number of online, idle and dnd members */ - const onlineCountEmbed = createEmbed(client, online, idle, dnd) + const onlineCountEmbed = createEmbed(client, online, idle, dnd, message) return client.reply(message, { embeds: [onlineCountEmbed.setTimestamp()] }) } @@ -52,26 +52,36 @@ async function fetchMemberStates(client: DiscordClient): Promise<{ online: numbe * @param {number} online Number of online members * @param {number} idle Number of idle members * @param {number} dnd Number of dnd members + * @param {DiscordMessage} message Message set by user * @returns {MessageEmbed} */ -function createEmbed(client: DiscordClient, online: number, idle: number, dnd: number): MessageEmbed { +function createEmbed( + client: DiscordClient, + online: number, + idle: number, + dnd: number, + message: DiscordMessage, +): MessageEmbed { return new MessageEmbed() .setColor('#aaa540') - .setTitle('[🌐] Online Counter') - .setFooter(`[ID] ${client.config.ids.userID.botUserID}`, 'https://image.flaticon.com/icons/png/512/888/888879.png') + .setTitle(client.translate({ key: 'commands.utility.onlinecount.OnlineCounter', lng: message.author.language })) + .setFooter({ + text: `[ID] ${client.config.ids.userID.botUserID}`, + iconURL: 'https://image.flaticon.com/icons/png/512/888/888879.png', + }) .addFields( { - name: '🟢Online:', + name: client.translate({ key: 'commands.utility.onlinecount.Online', lng: message.author.language }), value: `${online}`, inline: false, }, { - name: '🟡Idle:', + name: client.translate({ key: 'commands.utility.onlinecount.Idle', lng: message.author.language }), value: `${idle}`, inline: false, }, { - name: '🔴DND:', + name: client.translate({ key: 'commands.utility.onlinecount.DND', lng: message.author.language }), value: `${dnd}`, inline: false, }, diff --git a/locales/de.json b/locales/de.json index acfedd9..913ac80 100644 --- a/locales/de.json +++ b/locales/de.json @@ -43,8 +43,12 @@ "Gitlab": "[Link]({{gitlab}}) zur Gitlab Startseite", "Github": "Github [Repository]({{github}}) von <@{{userID}}>" }, - "liftoff": {}, - "onlinecount": {}, + "onlinecount": { + "OnlineCounter": "[🌐] Online Zähler", + "Online": "🟢Online", + "Idle": "🟡Abwesend", + "DND": "🔴Nicht stören" + }, "ping": {}, "start": {}, "test": {}, diff --git a/locales/en.json b/locales/en.json index 7b5bf9b..aea270d 100644 --- a/locales/en.json +++ b/locales/en.json @@ -43,8 +43,12 @@ "Gitlab": "[Link]({{gitlab}}) to Gitlab Homepage", "Github": "Github [Repository]({{github}}) of <@{{userID}}>" }, - "liftoff": {}, - "onlinecount": {}, + "onlinecount": { + "OnlineCounter": "[🌐] Online Counter", + "Online": "🟢Online", + "Idle": "🟡Idle", + "DND": "🔴DND" + }, "ping": {}, "start": {}, "test": {}, From 3c5662e176de5ad0dea471bdcff85f1edf57ab34 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 09:39:01 +0100 Subject: [PATCH 43/71] multi lingual ping --- commands/utility/ping.ts | 14 ++++++++++---- locales/de.json | 2 +- locales/en.json | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/commands/utility/ping.ts b/commands/utility/ping.ts index 51d7d19..5a7d03d 100644 --- a/commands/utility/ping.ts +++ b/commands/utility/ping.ts @@ -1,15 +1,21 @@ -import { Message } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' exports.name = 'ping' exports.description = 'pong' exports.usage = 'ping' -exports.run = (client: DiscordClient, message: Message) => +exports.run = (client: DiscordClient, message: DiscordMessage) => /** * Send reply with API latency. */ client.send(message, { - content: `🏓Latency is ${Date.now() - message.createdTimestamp}ms. API Latency is ${Math.round(client.ws.ping)}ms`, + content: client.translate({ + key: 'commands.utility.ping', + options: { + latency: Date.now() - message.createdTimestamp, + api_latency: Math.round(client.ws.ping), + lng: message.author.language, + }, + }), }) diff --git a/locales/de.json b/locales/de.json index 913ac80..4ad8e0d 100644 --- a/locales/de.json +++ b/locales/de.json @@ -49,7 +49,7 @@ "Idle": "🟡Abwesend", "DND": "🔴Nicht stören" }, - "ping": {}, + "ping": "🏓Die Latenz beträgt {{latency}}ms. API - Latenz ist {{api_latency}}", "start": {}, "test": {}, "uptime": {}, diff --git a/locales/en.json b/locales/en.json index aea270d..7447809 100644 --- a/locales/en.json +++ b/locales/en.json @@ -49,7 +49,7 @@ "Idle": "🟡Idle", "DND": "🔴DND" }, - "ping": {}, + "ping": "🏓Latency is {{latency}}ms. API Latency is {{api_latency}}ms", "start": {}, "test": {}, "uptime": {}, From 7ccd442b050772fee403da43ebdaf4a1f5b59c20 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 10:25:23 +0100 Subject: [PATCH 44/71] add translation to start and fix links (disable protection against xss attacks) --- commands/utility/start.ts | 22 ++++++++++++++-------- locales/de.json | 10 +++++++--- locales/en.json | 10 +++++++--- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/commands/utility/start.ts b/commands/utility/start.ts index 81f0ef8..3cf5008 100644 --- a/commands/utility/start.ts +++ b/commands/utility/start.ts @@ -1,6 +1,6 @@ -import { Message, MessageEmbed } from 'discord.js' +import { MessageEmbed } from 'discord.js' import fetch from 'node-fetch' -import { DiscordClient } from '../../types/customTypes' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' /** * NOTE: * This code is heavily inspired by the discord-together package @@ -30,12 +30,12 @@ const defaultApplications = { } exports.name = 'start' -exports.description = `Trickst die API aus um Discord-Spiele freizuschalten. +exports.description = `Trickst die API aus um Discord-Spiele freizuschalten. **NOTIZ**: Nicht alle Spiele sind vollends implementiert` exports.usage = `start \`${Object.keys(defaultApplications)}\`` -exports.run = async (client: DiscordClient, message: Message, args: any, applications = defaultApplications) => { +exports.run = async (client: DiscordClient, message: DiscordMessage, args: any, applications = defaultApplications) => { /** * Throw an error, if the user is not in a voiceChannel. */ @@ -43,8 +43,7 @@ exports.run = async (client: DiscordClient, message: Message, args: any, applica return client.reply(message, { embeds: [ new MessageEmbed().setDescription( - `⚠️ You are not in a Voice-Channel. - Please join a Voice-Channel to use this function`, + client.translate({ key: 'commands.utility.start.ErrorNoVoice', lng: message.author.language }), ), ], }) @@ -85,7 +84,11 @@ exports.run = async (client: DiscordClient, message: Message, args: any, applica * Send reply telling the user, that the application they selected does not exist. */ return client.reply(message, { - embeds: [new MessageEmbed().setDescription(`⚠️ Invalid option!`)], + embeds: [ + new MessageEmbed().setDescription( + client.translate({ key: 'commands.utility.start.ErrorInvalidOption', lng: message.author.language }), + ), + ], }) } @@ -96,7 +99,10 @@ exports.run = async (client: DiscordClient, message: Message, args: any, applica content: returnData.code, embeds: [ new MessageEmbed().setDescription( - `❔ If you can't join the activity **create it** by clicking the **[link](${returnData.code})** above.`, + client.translate({ + key: 'commands.utility.start.Info', + options: { invite: returnData.code, lng: message.author.language }, + }), ), ], }) diff --git a/locales/de.json b/locales/de.json index 4ad8e0d..5ce451d 100644 --- a/locales/de.json +++ b/locales/de.json @@ -40,8 +40,8 @@ }, "git": { "Title": "[🌐] GIT Wiki", - "Gitlab": "[Link]({{gitlab}}) zur Gitlab Startseite", - "Github": "Github [Repository]({{github}}) von <@{{userID}}>" + "Gitlab": "[Link]({{- gitlab}}) zur Gitlab Startseite", + "Github": "Github [Repository]({{- github}}) von <@{{userID}}>" }, "onlinecount": { "OnlineCounter": "[🌐] Online Zähler", @@ -50,7 +50,11 @@ "DND": "🔴Nicht stören" }, "ping": "🏓Die Latenz beträgt {{latency}}ms. API - Latenz ist {{api_latency}}", - "start": {}, + "start": { + "ErrorNoVoice": "⚠️ Du bist nicht in einem Sprach-Kanal.\nBitte trete einenm Sprach-Kanal bei, um diesen Befehl nutzen zu können.", + "ErrorInvalidOption": "⚠️ Nicht zulässige Option!", + "Info": "❔ Wenn du der Aktivität nicht beitreten kannst, **erstelle ** sie, indem du oben auf den **[Link]({{- invite}})** klickst." + }, "test": {}, "uptime": {}, "userprofile": {}, diff --git a/locales/en.json b/locales/en.json index 7447809..2f3637c 100644 --- a/locales/en.json +++ b/locales/en.json @@ -40,8 +40,8 @@ }, "git": { "Title": "[🌐] GIT Wiki", - "Gitlab": "[Link]({{gitlab}}) to Gitlab Homepage", - "Github": "Github [Repository]({{github}}) of <@{{userID}}>" + "Gitlab": "[Link]({{- gitlab}}) to Gitlab Homepage", + "Github": "Github [Repository]({{- github}}) of <@{{userID}}>" }, "onlinecount": { "OnlineCounter": "[🌐] Online Counter", @@ -50,7 +50,11 @@ "DND": "🔴DND" }, "ping": "🏓Latency is {{latency}}ms. API Latency is {{api_latency}}ms", - "start": {}, + "start": { + "ErrorNoVoice": "⚠️ You are not in a Voice-Channel.\nPlease join a Voice-Channel to use this command.", + "ErrorInvalidOption": "⚠️ Invalid option!", + "Info": "❔ If you can't join the activity **create it** by clicking the **[Link]({{- invite}})** above." + }, "test": {}, "uptime": {}, "userprofile": {}, From c6f25500b09726183ed3d971dfcd26828654841f Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 10:25:56 +0100 Subject: [PATCH 45/71] update footer --- commands/utility/test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/utility/test.ts b/commands/utility/test.ts index f3459a4..111e7e1 100644 --- a/commands/utility/test.ts +++ b/commands/utility/test.ts @@ -15,6 +15,6 @@ exports.run = (client: DiscordClient, message: Message) => embeds: [ new MessageEmbed() .setTitle('🌐 This Bot is working as intended!') - .setFooter(message.author.tag, message.author.avatarURL({ dynamic: true })), + .setFooter({ text: message.author.tag, iconURL: message.author.avatarURL({ dynamic: true }) }), ], }) From 7f0c21890053c7887a86002edd766a9a7dafba09 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 10:27:56 +0100 Subject: [PATCH 46/71] add translatiopn to test --- commands/utility/test.ts | 8 ++++---- locales/de.json | 2 +- locales/en.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/commands/utility/test.ts b/commands/utility/test.ts index 111e7e1..ecee076 100644 --- a/commands/utility/test.ts +++ b/commands/utility/test.ts @@ -1,5 +1,5 @@ -import { Message, MessageEmbed } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' +import { MessageEmbed } from 'discord.js' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' exports.name = 'test' @@ -7,14 +7,14 @@ exports.description = 'Prüft ob der Bot online und funktionstüchtig ist.' exports.usage = 'test' -exports.run = (client: DiscordClient, message: Message) => +exports.run = (client: DiscordClient, message: DiscordMessage) => /** * Send reply, that the bot is working as intended. */ client.reply(message, { embeds: [ new MessageEmbed() - .setTitle('🌐 This Bot is working as intended!') + .setTitle(client.translate({ key: 'commands.utility.test', lng: message.author.language })) .setFooter({ text: message.author.tag, iconURL: message.author.avatarURL({ dynamic: true }) }), ], }) diff --git a/locales/de.json b/locales/de.json index 5ce451d..ab5a3c5 100644 --- a/locales/de.json +++ b/locales/de.json @@ -55,7 +55,7 @@ "ErrorInvalidOption": "⚠️ Nicht zulässige Option!", "Info": "❔ Wenn du der Aktivität nicht beitreten kannst, **erstelle ** sie, indem du oben auf den **[Link]({{- invite}})** klickst." }, - "test": {}, + "test": "🌐Dieser Bot funktioniert einwandfrei!", "uptime": {}, "userprofile": {}, "zoom": {} diff --git a/locales/en.json b/locales/en.json index 2f3637c..71de8c3 100644 --- a/locales/en.json +++ b/locales/en.json @@ -55,7 +55,7 @@ "ErrorInvalidOption": "⚠️ Invalid option!", "Info": "❔ If you can't join the activity **create it** by clicking the **[Link]({{- invite}})** above." }, - "test": {}, + "test": "🌐 This Bot is working as intended!", "uptime": {}, "userprofile": {}, "zoom": {} From 281400288880e448024d53a595bea3314cc477e5 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 10:43:07 +0100 Subject: [PATCH 47/71] add translatiopn to uptime --- commands/utility/uptime.ts | 22 ++++++++++++++++------ locales/de.json | 6 +++++- locales/en.json | 6 +++++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/commands/utility/uptime.ts b/commands/utility/uptime.ts index 459c202..b24816a 100644 --- a/commands/utility/uptime.ts +++ b/commands/utility/uptime.ts @@ -1,5 +1,6 @@ -import { Message, MessageEmbed } from 'discord.js' -import { DiscordClient } from '../../types/customTypes' +import { MessageEmbed } from 'discord.js' +import { updateLocale } from 'moment' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' exports.name = 'uptime' @@ -7,7 +8,7 @@ exports.description = 'Wie lange ist der Bot schon online' exports.usage = 'uptime' -exports.run = (client: DiscordClient, message: Message) => { +exports.run = (client: DiscordClient, message: DiscordMessage) => { /** * Uptime in days, hours, minutes and seconds. */ @@ -19,10 +20,19 @@ exports.run = (client: DiscordClient, message: Message) => { return client.reply(message, { embeds: [ new MessageEmbed() - .setTitle('⏰Uptime') + .setTitle(client.translate({ key: 'commands.utility.uptime.Title', lng: message.author.language })) .addField( - 'Time since last restart:', - `${uptime.days} Days, ${uptime.hours} Hours, ${uptime.minutes} Minutes, ${uptime.seconds} Seconds`, + client.translate({ key: 'commands.utility.uptime.Time', lng: message.author.language }), + client.translate({ + key: 'commands.utility.uptime.Info', + options: { + days: uptime.days, + hours: uptime.hours, + minutes: uptime.minutes, + seconds: uptime.seconds, + lng: message.author.language, + }, + }), ) .setColor('#FF4040'), ], diff --git a/locales/de.json b/locales/de.json index ab5a3c5..c76af6b 100644 --- a/locales/de.json +++ b/locales/de.json @@ -56,7 +56,11 @@ "Info": "❔ Wenn du der Aktivität nicht beitreten kannst, **erstelle ** sie, indem du oben auf den **[Link]({{- invite}})** klickst." }, "test": "🌐Dieser Bot funktioniert einwandfrei!", - "uptime": {}, + "uptime": { + "Title": "⏰Betriebszeit", + "Time": "Zeit seit dem letzten neustart:", + "Info": "{{days}} Tage, {{hours}} Stunden, {{minutes}} Minuten, {{seconds}} Sekunden" + }, "userprofile": {}, "zoom": {} } diff --git a/locales/en.json b/locales/en.json index 71de8c3..b6b0953 100644 --- a/locales/en.json +++ b/locales/en.json @@ -56,7 +56,11 @@ "Info": "❔ If you can't join the activity **create it** by clicking the **[Link]({{- invite}})** above." }, "test": "🌐 This Bot is working as intended!", - "uptime": {}, + "uptime": { + "Title": "⏰Uptime", + "Time": "Time since last restart:", + "Info": "{{days}} Days, {{hours}} Hours, {{minutes}} Minutes, {{seconds}} Seconds" + }, "userprofile": {}, "zoom": {} } From cb9a18d00247c1d0be9bb9a29e202de7117a7ea5 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 10:43:33 +0100 Subject: [PATCH 48/71] remove accidentally added import --- commands/utility/uptime.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/commands/utility/uptime.ts b/commands/utility/uptime.ts index b24816a..74f8c49 100644 --- a/commands/utility/uptime.ts +++ b/commands/utility/uptime.ts @@ -1,5 +1,4 @@ import { MessageEmbed } from 'discord.js' -import { updateLocale } from 'moment' import { DiscordClient, DiscordMessage } from '../../types/customTypes' exports.name = 'uptime' From 47198e8db2c2b087e248834832c48f41adde4cd3 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 10:44:57 +0100 Subject: [PATCH 49/71] update footer --- commands/utility/userprofile.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/utility/userprofile.ts b/commands/utility/userprofile.ts index 8c078d3..a20ad1c 100644 --- a/commands/utility/userprofile.ts +++ b/commands/utility/userprofile.ts @@ -44,7 +44,7 @@ exports.run = async (client: DiscordClient, message: Message) => { true, ) .setImage(forceFetchedUser.bannerURL({ size: 4096, dynamic: true })) - .setFooter(message.author.tag, message.author.avatarURL({ dynamic: true })), + .setFooter({ text: message.author.tag, iconURL: message.author.avatarURL({ dynamic: true }) }), ], }) } From 906723f5a284dc77541206d8b53aebd39d7b9772 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 10:58:36 +0100 Subject: [PATCH 50/71] add translatiopn to profile --- commands/utility/userprofile.ts | 28 +++++++++++++++++++--------- locales/de.json | 6 +++++- locales/en.json | 6 +++++- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/commands/utility/userprofile.ts b/commands/utility/userprofile.ts index a20ad1c..a43eed2 100644 --- a/commands/utility/userprofile.ts +++ b/commands/utility/userprofile.ts @@ -1,6 +1,6 @@ -import { Message, User, MessageEmbed } from 'discord.js' +import { User, MessageEmbed } from 'discord.js' import { GuildMember } from 'discord.js/typings/index.js' -import { DiscordClient } from '../../types/customTypes' +import { DiscordClient, DiscordMessage } from '../../types/customTypes' exports.name = 'userprofile' @@ -10,7 +10,7 @@ exports.usage = 'userprofile {optional: @mentionedUser}' exports.aliases = ['profile'] -exports.run = async (client: DiscordClient, message: Message) => { +exports.run = async (client: DiscordClient, message: DiscordMessage) => { /** * Set the user to fetch information about. */ @@ -33,14 +33,24 @@ exports.run = async (client: DiscordClient, message: Message) => { return client.reply(message, { embeds: [ new MessageEmbed() - .setAuthor({ name: '👤UserProfile' }) + .setAuthor({ + name: client.translate({ key: 'commands.utility.userprofile.UserProfile', lng: message.author.language }), + }) .setTitle(forceFetchedUser.tag) .setColor(messageUser.displayColor) - .setThumbnail(messageUser.displayAvatarURL({ dynamic: true })) - .addField('Joined:', ``, true) + .setThumbnail(messageUser.displayAvatarURL({ size: 4096, dynamic: true })) + .addField( + client.translate({ key: 'commands.utility.userprofile.Joined', lng: message.author.language }), + ``, + true, + ) .addField( 'Nitro:', - `${userPremiumSinceTimestamp ? `` : 'Not currently subscribed'}`, + `${ + userPremiumSinceTimestamp + ? `` + : client.translate({ key: 'commands.utility.userprofile.NoNitroStatus', lng: message.author.language }) + }`, true, ) .setImage(forceFetchedUser.bannerURL({ size: 4096, dynamic: true })) @@ -51,13 +61,13 @@ exports.run = async (client: DiscordClient, message: Message) => { /** * - * @param {Message} message Message sent by the user + * @param {DiscordMessage} message Message sent by the user * @param {GuildMember} user User to fetch information about * @param {DiscordClient} client Bot-Client * @returns {{User, GuildMember, string, string}} */ async function getUserInfo( - message: Message, + message: DiscordMessage, user: GuildMember, client: DiscordClient, ): Promise<{ diff --git a/locales/de.json b/locales/de.json index c76af6b..47ed872 100644 --- a/locales/de.json +++ b/locales/de.json @@ -61,7 +61,11 @@ "Time": "Zeit seit dem letzten neustart:", "Info": "{{days}} Tage, {{hours}} Stunden, {{minutes}} Minuten, {{seconds}} Sekunden" }, - "userprofile": {}, + "userprofile": { + "UserProfile": "👤Benutzerprofil", + "Joined": "Beigetreten", + "NoNitroStatus": "Zurzeit nicht abboniert" + }, "zoom": {} } }, diff --git a/locales/en.json b/locales/en.json index b6b0953..e7f75d7 100644 --- a/locales/en.json +++ b/locales/en.json @@ -61,7 +61,11 @@ "Time": "Time since last restart:", "Info": "{{days}} Days, {{hours}} Hours, {{minutes}} Minutes, {{seconds}} Seconds" }, - "userprofile": {}, + "userprofile": { + "UserProfile": "👤Userprofile", + "Joined": "Joined:", + "NoNitroStatus": "Not currently subscribed" + }, "zoom": {} } }, From 3c8ea5d6dc5eea7aa9db7bdc94fea19214370c76 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 11:06:18 +0100 Subject: [PATCH 51/71] update footer --- slashCommands/help.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/slashCommands/help.ts b/slashCommands/help.ts index 0943576..c19184e 100644 --- a/slashCommands/help.ts +++ b/slashCommands/help.ts @@ -32,10 +32,10 @@ async function getCommands(client): Promise { .setColor('#ffa500') .setAuthor({ name: 'Help', iconURL: 'https://bit.ly/3CJU0lf' }) .setTimestamp() - .setFooter( - `[ID] ${client.config.ids.userID.botUserID} \nstarted`, - 'https://image.flaticon.com/icons/png/512/888/888879.png', - ) + .setFooter({ + text: `[ID] ${client.config.ids.userID.botUserID} \nstarted`, + iconURL: 'https://image.flaticon.com/icons/png/512/888/888879.png', + }) const commandFiles = await fs.promises.readdir('./commands/', null) From bac6d215a62defc45f61d519c2475538c9c0435d Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 14:19:32 +0100 Subject: [PATCH 52/71] update slashcommands to use SlashCommandsBuilder and add interactionCreate event --- events/interactionCreate.ts | 19 +++++ events/ready.ts | 13 +--- index.ts | 112 +++-------------------------- locales/de.json | 2 +- locales/en.json | 2 +- package.json | 1 + scripts/addCommands.ts | 136 ++++++++++++++++++++++++++++++++++++ slashCommands/help.ts | 27 ++----- slashCommands/issue.ts | 46 +++--------- slashCommands/ping.ts | 26 ++----- slashCommands/wochenplan.ts | 62 +++++----------- types/customTypes.ts | 60 +++++++++++++--- 12 files changed, 256 insertions(+), 250 deletions(-) create mode 100644 events/interactionCreate.ts create mode 100644 scripts/addCommands.ts diff --git a/events/interactionCreate.ts b/events/interactionCreate.ts new file mode 100644 index 0000000..eb8adab --- /dev/null +++ b/events/interactionCreate.ts @@ -0,0 +1,19 @@ +import { DiscordClient, DiscordInteraction } from '../types/customTypes' + +exports.run = (client: DiscordClient, interaction: DiscordInteraction) => { + if (interaction.isCommand()) { + /** + * File to the corrospinging slashCommand. + */ + const commandfile = client.slashCommands.get(interaction.commandName) + + /** + * Set language for user + */ + client.getLanguage(undefined, interaction) + + console.log(`${interaction.member.user.username} issued /${interaction.commandName}`) + + commandfile.respond(client, interaction) + } +} diff --git a/events/ready.ts b/events/ready.ts index 0f4f9b5..735e30c 100644 --- a/events/ready.ts +++ b/events/ready.ts @@ -1,19 +1,10 @@ -import { loadScripts, loadSlashCommands } from '../index' import { DiscordClient } from '../types/customTypes' exports.run = async (client: DiscordClient) => { - /** - * Load all scripts. - */ - await loadScripts(client) - - /** - * Load all slashCommands. - */ - await loadSlashCommands(client) - /** * Log that the bot is online and operational. */ console.log('Online!') + + console.log(client.slashCommands) } diff --git a/index.ts b/index.ts index e230dcf..4b2eec2 100644 --- a/index.ts +++ b/index.ts @@ -23,11 +23,6 @@ i18next.use(backend).init({ initImmediate: false, }) -/** - * Folder that contains all commands. - */ -const commandsFolder = './commands/' - /** * Create instance of {@link DiscordClient}. */ @@ -51,6 +46,11 @@ const client: DiscordClient = new DiscordClient({ */ client.commands = new Collection() +/** + * Set {@link DiscordClient} slashCommands to new {@link Collection} + */ +client.slashCommands = new Collection() + /** * Set config. */ @@ -61,64 +61,8 @@ client.config = config */ client.login(client.config.botToken) -fs.readdir(commandsFolder, (err, elements) => { - if (err) return console.log(err) - return elements.forEach(file => { - /** - * Loop through all elements in folder "commands". - */ - const element_in_folder = fs.statSync(`./commands/${file}`) - if (element_in_folder.isDirectory() === true) { - /** - * Check if element in folder is a subfolder. - */ - const sub_directory = `./commands/${file}/` - fs.readdir(sub_directory, (_err, files) => { - if (_err) return console.log(_err) - return files.forEach(_file => { - /** - * Adds commands from subfolder to collection. - */ - setCommands(sub_directory, _file, client) - }) - }) - return - } - - /** - * Adds commands from parentfolder to collection. - */ - setCommands(commandsFolder, file, client) - }) -}) - -/** - * Add commands to {@link DiscordClient.commands}. - * @param {string} path Path of commands folder - * @param {string} file Files to check. - * @param {DiscordClient} _client Bot-Client - * @returns {void} - */ -function setCommands(path: string, file: string, _client: DiscordClient): void { - if (!(file.endsWith('.js') || file.endsWith('.ts'))) return - - /** - * Path of event file. - */ - const props = require(`${path}${file}`) - - /** - * Name of command. - */ - const commandName = file.split('.')[0] - - /** - * Add command to {@link DiscordClient.commands}. - */ - _client.commands.set(commandName, props) - - console.log(`Successfully loaded command ${file}`) -} +const foo = require('./scripts/addCommands') +foo.run(client) /** * Load and run events. @@ -151,6 +95,7 @@ fs.readdir('./events/', (err, files) => { client.on(eventName, (...args) => eventFunc.run(client, ...args)) }) }) + /** * Load and run all scripts. * @param {DiscordClient} _client Bot-Client @@ -193,44 +138,3 @@ export async function loadScripts(_client: DiscordClient) { console.log(`Successfully executed startupScript ${file}`) }) } -/** - * Load and post all slashComamnds. - * @param {DiscordClient} _client Bot-Client - */ -export async function loadSlashCommands(_client: DiscordClient) { - /** - * Object with all files of scripts directory. - */ - let files - - try { - /** - * Read directory. - */ - files = await fs.promises.readdir('./slashCommands/') - } catch (e) { - /** - * Error handling. - */ - throw new Error(e) - } - files.forEach(file => { - /** - * Path of slashCommand. - */ - const slashCommand = require(`./slashCommands/${file}`) - - try { - /** - * Run scripts. - */ - slashCommand.run(_client) - } catch (e) { - /** - * Error handling. - */ - throw new Error(e) - } - console.log(`Successfully posted slashCommand ${file}`) - }) -} diff --git a/locales/de.json b/locales/de.json index 47ed872..e4d6165 100644 --- a/locales/de.json +++ b/locales/de.json @@ -70,7 +70,7 @@ } }, "slashCommands": { - "help": {}, + "help": "Hilfe", "issue": {}, "ping": {}, "wochenplan": {} diff --git a/locales/en.json b/locales/en.json index e7f75d7..89f96b7 100644 --- a/locales/en.json +++ b/locales/en.json @@ -70,7 +70,7 @@ } }, "slashCommands": { - "help": {}, + "help": "Help", "issue": {}, "ping": {}, "wochenplan": {} diff --git a/package.json b/package.json index 9eeb1be..d549382 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "homepage": "https://github.com/Chr1s70ph/ETIT-Master-JS#readme", "author": "Christoph Bluem", "dependencies": { + "@discordjs/rest": "^0.2.0-canary.0", "discord-api-types": "^0.26.0", "discord.js": "^14.0.0-dev.1640779371.9cdc448", "eslint-config-prettier": "^8.3.0", diff --git a/scripts/addCommands.ts b/scripts/addCommands.ts new file mode 100644 index 0000000..e5d2be3 --- /dev/null +++ b/scripts/addCommands.ts @@ -0,0 +1,136 @@ +import { readdir, statSync } from 'fs' +import { readdir as promiseReaddir } from 'fs/promises' +import { REST } from '@discordjs/rest' +import { DiscordClient } from '../types/customTypes' +const { Routes } = require('discord-api-types/v9') + +/** + * Folder that contains all commands. + */ +const commandsFolder = './commands/' + +/** + * Folder that contains all slashCommands. + */ +const slashCommandsFolder = './slashCommands/' + +exports.run = (client: DiscordClient) => { + Commands(client) + loadSlashCommands(client) +} + +function Commands(client) { + readdir(commandsFolder, (err, elements) => { + if (err) return console.log(err) + return elements.forEach(file => { + /** + * Loop through all elements in folder "commands". + */ + const element_in_folder = statSync(`./commands/${file}`) + if (element_in_folder.isDirectory() === true) { + /** + * Check if element in folder is a subfolder. + */ + const sub_directory = `./commands/${file}/` + readdir(sub_directory, (_err, files) => { + if (_err) return console.log(_err) + return files.forEach(_file => { + /** + * Adds commands from subfolder to collection. + */ + setCommands(sub_directory, _file, client) + }) + }) + return + } + + /** + * Adds commands from parentfolder to collection. + */ + setCommands(commandsFolder, file, client) + }) + }) +} + +/** + * Add commands to {@link DiscordClient.commands}. + * @param {string} path Path of commands folder + * @param {string} file Files to check. + * @param {DiscordClient} client Bot-Client + * @returns {void} + */ +function setCommands(path: string, file: string, client: DiscordClient): void { + if (!(file.endsWith('.js') || file.endsWith('.ts'))) return + + /** + * Path of command file. + */ + const props = require(`../${path}${file}`) + + /** + * Name of command. + */ + const commandName = file.split('.')[0] + + /** + * Add command to {@link DiscordClient.commands}. + */ + client.commands.set(commandName, props) + + console.log(`Successfully loaded command ${file}`) +} + +/** + * Load and post all slashComamnds. + * @param {DiscordClient} client Bot-Client + */ +export async function loadSlashCommands(client: DiscordClient) { + /** + * Object with all files of scripts directory. + */ + let files + + const slashCommandData = [] + + try { + /** + * Read directory. + */ + files = await promiseReaddir(slashCommandsFolder) + } catch (e) { + /** + * Error handling. + */ + throw new Error(e) + } + files.forEach(file => { + /** + * Path of slashCommand. + */ + const slashCommand = require(`../${slashCommandsFolder}${file}`) + + slashCommandData.push(slashCommand.data.toJSON()) + + const commandName = file.split('.')[0] + + client.slashCommands.set(commandName, slashCommand) + console.log(`Successfully posted slashCommand ${file}`) + }) + postSlashCommands(client, slashCommandData) +} + +async function postSlashCommands(client, slashCommandData) { + const rest = new REST({ version: '9' }).setToken(client.config.botToken) + try { + console.log('Started refreshing application (/) commands.') + + console.log(slashCommandData) + await rest.put(Routes.applicationGuildCommands(client.config.ids.userID.botUserID, '757981349402378331'), { + body: slashCommandData, + }) + + console.log('Successfully reloaded application (/) commands.') + } catch (error) { + console.error(error) + } +} diff --git a/slashCommands/help.ts b/slashCommands/help.ts index c19184e..e1de0af 100644 --- a/slashCommands/help.ts +++ b/slashCommands/help.ts @@ -1,28 +1,11 @@ -import { Interaction, MessageEmbed } from 'discord.js' +import { SlashCommandBuilder } from '@discordjs/builders' +import { MessageEmbed } from 'discord.js' const fs = require('fs') -exports.run = async client => { - const embed = await getCommands(client) - await postSlashCommand(client) - - client.on('interactionCreate', async (interaction: Interaction) => { - if (!interaction.isCommand()) return - const COMMAND = interaction.commandName - if (COMMAND !== 'help') return - await respond(interaction, embed) - }) -} +export const data = new SlashCommandBuilder().setName('help').setDescription('hilfe ist hier') -async function postSlashCommand(client: any): Promise { - await client.api.applications(client.user.id).commands.post({ - data: { - name: 'help', - description: 'hilfe ist hier', - }, - }) -} - -async function respond(interaction: any, embed: any): Promise { +exports.respond = async (client, interaction: any): Promise => { + const embed = await getCommands(client) console.log(`User ${interaction.user.username} issued /help`) await interaction.reply({ embeds: [embed.setTimestamp()], ephemeral: true }) } diff --git a/slashCommands/issue.ts b/slashCommands/issue.ts index 436abf6..9200363 100644 --- a/slashCommands/issue.ts +++ b/slashCommands/issue.ts @@ -1,43 +1,17 @@ -import { Interaction, MessageEmbed } from 'discord.js' +import { SlashCommandBuilder } from '@discordjs/builders' +import { MessageEmbed } from 'discord.js' +import { DiscordClient } from '../types/customTypes' const createIssue = require('github-create-issue') const REPOSITORY = 'Chr1s70ph/ETIT-Master' -exports.run = async client => { - await postSlashCommand(client) +export const data = new SlashCommandBuilder() + .setName('vorschlag') + .setDescription('Schlage etwas vor!') + .addStringOption(option => option.setName('vorschlag').setDescription('Mein Vorschlag').setRequired(true)) + .addStringOption(option => option.setName('titel').setDescription('Titel meines Vorschlages')) - client.on('interactionCreate', async (interaction: Interaction) => { - if (!interaction.isCommand()) return - const COMMAND = interaction.commandName - if (COMMAND !== 'vorschlag') return - await respond(interaction, COMMAND, client) - }) -} - -async function postSlashCommand(client: any): Promise { - await client.api.applications(client.user.id).commands.post({ - data: { - name: 'vorschlag', - description: 'Schlage etwas vor!', - options: [ - { - name: 'vorschlag', - description: 'Mein Vorschlag:', - type: 3, - required: true, - }, - { - name: 'titel', - description: 'Mein Vorschlag:', - type: 3, - required: false, - }, - ], - }, - }) -} - -async function respond(interaction, COMMAND: string, client: any): Promise { - console.log(`User ${interaction.user.username} issued /${COMMAND}`) +exports.respond = async (client: DiscordClient, interaction): Promise => { + console.log(`User ${interaction.user.username} issued /${interaction.commandName}`) const options = { token: client.config.github_token, diff --git a/slashCommands/ping.ts b/slashCommands/ping.ts index a170f66..e8160fe 100644 --- a/slashCommands/ping.ts +++ b/slashCommands/ping.ts @@ -1,26 +1,10 @@ -import { Interaction } from 'discord.js' +import { SlashCommandBuilder } from '@discordjs/builders' -exports.run = async (client: any) => { - await postSlashCommand(client) +export const data = new SlashCommandBuilder() + .setName('ping') + .setDescription('Prüft, ob der Bot ordnungsgemäß antwortet') - client.on('interactionCreate', async (interaction: Interaction) => { - if (!interaction.isCommand()) return - const COMMAND = interaction.commandName - if (COMMAND !== 'ping') return - await respond(client, interaction) - }) -} - -async function postSlashCommand(client: any): Promise { - await client.api.applications(client.user.id).commands.post({ - data: { - name: 'ping', - description: 'Prüft, ob der Bot ordnungsgemäß antwortet', - }, - }) -} - -async function respond(client: any, interaction: any): Promise { +exports.respond = async (client: any, interaction: any): Promise => { console.log(`User ${interaction.user.username} issued /ping`) await interaction.reply({ content: 'pong', ephemeral: true }) } diff --git a/slashCommands/wochenplan.ts b/slashCommands/wochenplan.ts index cde97a5..c7f88fe 100644 --- a/slashCommands/wochenplan.ts +++ b/slashCommands/wochenplan.ts @@ -1,7 +1,8 @@ -import { Interaction, MessageEmbed } from 'discord.js' +import { SlashCommandBuilder } from '@discordjs/builders' +import { MessageEmbed } from 'discord.js' import moment from 'moment-timezone' import { async } from 'node-ical' -import { DiscordClient } from '../types/customTypes' +import { DiscordClient, DiscordInteraction } from '../types/customTypes' exports.name = 'wochenplan' @@ -9,6 +10,13 @@ exports.description = '️Zeigt den Wochenplan an.' exports.usage = `wochenplan {TAG}` +export const data = new SlashCommandBuilder() + .setName('wochenplan') + .setDescription('Zeigt deinen Wochenplan an.') + .addStringOption(option => + option.setName('datum').setDescription('Das Datum, das angezeigt werden soll. Format: TT.MM.YYYY'), + ) + class Abbreviation { constructor(pEmoji, pValue) { const emoji = pEmoji @@ -54,10 +62,10 @@ function _shortenSummary(pEventSummary) { } async function wochenplan(pClient: DiscordClient, pMessageOrInteraction, pNow, pCourseAndSemester) { - let data = {} + let returnData = {} for (const entry in pClient.config.calendars) { // eslint-disable-next-line no-await-in-loop - data = { ...data, ...(await async.fromURL(pClient.config.calendars[entry])) } + returnData = { ...returnData, ...(await async.fromURL(pClient.config.calendars[entry])) } } const relevantEvents = [] @@ -68,10 +76,10 @@ async function wochenplan(pClient: DiscordClient, pMessageOrInteraction, pNow, p const rangeStart = moment(startOfWeek) const rangeEnd = rangeStart.clone().add(7, 'days') - filterEvents(data, rangeStart, rangeEnd, pCourseAndSemester, pMessageOrInteraction, relevantEvents) + filterEvents(returnData, rangeStart, rangeEnd, pCourseAndSemester, pMessageOrInteraction, relevantEvents) const embed = new MessageEmbed() - .setAuthor(`🗓️ Wochenplan für ${pMessageOrInteraction.member.user.username}`) + .setAuthor({ name: `🗓️ Wochenplan für ${pMessageOrInteraction.member.user.username}` }) .setDescription(`Woche vom ${moment(startOfWeek).format('DD.MM.yyyy')}`) const weekdayItems = {} @@ -124,16 +132,16 @@ async function wochenplan(pClient: DiscordClient, pMessageOrInteraction, pNow, p } function filterEvents( - data: any, + returnData: any, rangeStart: moment.Moment, rangeEnd: moment.Moment, pCourseAndSemester: any, pMessageOrInteraction: any, relevantEvents: any[], ) { - for (const i in data) { - const event = data[i] - if (data[i].type === 'VEVENT') { + for (const i in returnData) { + const event = returnData[i] + if (returnData[i].type === 'VEVENT') { const title = event.summary const startDate = moment(event.start) const endDate = moment(event.end) @@ -221,39 +229,7 @@ function pushToWeeksEvents(interaction, event, relevantEvents) { } } -exports.run = async client => { - await postSlashCommand(client) - - client.on('interactionCreate', async (interaction: Interaction) => { - if (!interaction.isCommand()) return - const COMMAND = interaction.commandName - if (COMMAND !== 'wochenplan') return - await respond(interaction, COMMAND, client) - }) -} - -async function postSlashCommand(client: any): Promise { - await client.api - .applications(client.user.id) - .guilds('757981349402378331') - .commands.post({ - data: { - name: 'wochenplan', - description: 'Zeigt den Wochenplan an.', - options: [ - { - name: 'datum', - description: 'Das Datum, das angezeigt werden soll. Format: TT.MM.YYYY', - type: 3, - required: false, - }, - ], - }, - }) -} - -async function respond(interaction, COMMAND: string, client: any): Promise { - console.log(`User ${interaction.user.username} issued /${COMMAND}`) +exports.respond = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { const now = new Date() const embed = wochenplan(client, interaction, now, 'all') diff --git a/types/customTypes.ts b/types/customTypes.ts index 0a46c26..ce71340 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -1,6 +1,15 @@ import { readdirSync } from 'fs' // eslint-disable-next-line @typescript-eslint/no-unused-vars -import { Client, Message, TextChannel, MessageOptions, Collection, User } from 'discord.js' +import { + Client, + Message, + TextChannel, + MessageOptions, + Collection, + User, + GuildMemberRoleManager, + MessageComponentInteraction, +} from 'discord.js' import i18next from 'i18next' /** @@ -14,6 +23,12 @@ export class DiscordClient extends Client { */ public commands: Collection + /** + * Collection of all slashCommands to use + * @type {Collection} + */ + public slashCommands: Collection + /** * Config file imported into the DiscordClient for global access * @type { [key: string]: any } @@ -99,9 +114,15 @@ export class DiscordClient extends Client { /** * Get user language. * @param {Message} message Message sent by user + * @param {DiscordInteraction} interaction Interaction used by user * @returns {string} */ - public getLanguage(message: DiscordMessage): string { + public getLanguage(message?: DiscordMessage, interaction?: DiscordInteraction): string { + /** + * Object of {@link DiscordUser} + */ + const user = message ? message.author : interaction.user + /** * List of all defined languages in './locales/'. */ @@ -119,15 +140,22 @@ export class DiscordClient extends Client { /** * Return language if match is found. */ - if (message.member?.roles?.cache.some(role => role.name === language)) { - return (message.author.language = language) + if (message) { + if (message.member?.roles?.cache.some(role => role.name === language)) { + return (user.language = language) + } + } else if (interaction) { + const userRoles = interaction.member.roles as GuildMemberRoleManager + if (userRoles.cache.some(role => role.name === language)) { + return (user.language = language) + } } } /** * Return default language if no language match is found. */ - return (message.author.language = 'en') + return (user.language = 'en') } /** @@ -143,23 +171,28 @@ export class DiscordClient extends Client { } /** - * Extended Message to hold DiscordUser. + * Extended Message to hold {@link DiscordUser}. */ export interface DiscordMessage extends Message { author: DiscordUser } +/** + * Extended Interaction to hold {@link DiscordUser} + */ +export interface DiscordInteraction extends MessageComponentInteraction { + user: DiscordUser +} + /** * Extended User to hold language. */ -class DiscordUser extends User { +export interface DiscordUser extends User { language: string } /** * Interface for translation parameters - * @readonly - * @private */ interface translation_options { key: string | string[] @@ -169,8 +202,6 @@ interface translation_options { /** * Interface of Command structure - * @readonly - * @private */ interface Command extends Object { name: string @@ -179,3 +210,10 @@ interface Command extends Object { example: string aliases: string[] } + +interface SlashCommand extends Object { + name: string + description: string + usage: string + respond: any +} From 829777c5229fe4dcb139fc3c2383aa33714dc922 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 14:29:11 +0100 Subject: [PATCH 53/71] rename var --- index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.ts b/index.ts index 4b2eec2..fd43757 100644 --- a/index.ts +++ b/index.ts @@ -61,8 +61,8 @@ client.config = config */ client.login(client.config.botToken) -const foo = require('./scripts/addCommands') -foo.run(client) +const LoadCommands = require('./scripts/addCommands') +LoadCommands.run(client) /** * Load and run events. From 22dc3e4a332558024d45d08e093984e47fd0f548 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 14:29:59 +0100 Subject: [PATCH 54/71] update log message --- index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.ts b/index.ts index fd43757..3bf375a 100644 --- a/index.ts +++ b/index.ts @@ -135,6 +135,6 @@ export async function loadScripts(_client: DiscordClient) { */ throw new Error(e) } - console.log(`Successfully executed startupScript ${file}`) + console.log(`Successfully started script ${file}`) }) } From e34f1a6715134b14eacb47ff746b522f1a577730 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 14:30:40 +0100 Subject: [PATCH 55/71] move eslint comment --- types/customTypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/customTypes.ts b/types/customTypes.ts index ce71340..0c56758 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -1,8 +1,8 @@ import { readdirSync } from 'fs' -// eslint-disable-next-line @typescript-eslint/no-unused-vars import { Client, Message, + // eslint-disable-next-line @typescript-eslint/no-unused-vars TextChannel, MessageOptions, Collection, From 04b44fb0ffc5861eafd53d2b86fefb2b73cae2d8 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 14:32:58 +0100 Subject: [PATCH 56/71] rm logs --- events/ready.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/events/ready.ts b/events/ready.ts index 735e30c..52577ac 100644 --- a/events/ready.ts +++ b/events/ready.ts @@ -1,10 +1,5 @@ -import { DiscordClient } from '../types/customTypes' - -exports.run = async (client: DiscordClient) => { +exports.run = () => /** * Log that the bot is online and operational. */ console.log('Online!') - - console.log(client.slashCommands) -} From 7e7c3eded2b41f56876eb17f48a4e0a25a28010f Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 14:36:26 +0100 Subject: [PATCH 57/71] add translation to help --- slashCommands/help.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/slashCommands/help.ts b/slashCommands/help.ts index e1de0af..286a861 100644 --- a/slashCommands/help.ts +++ b/slashCommands/help.ts @@ -1,19 +1,23 @@ import { SlashCommandBuilder } from '@discordjs/builders' import { MessageEmbed } from 'discord.js' +import { DiscordClient, DiscordInteraction } from '../types/customTypes' const fs = require('fs') export const data = new SlashCommandBuilder().setName('help').setDescription('hilfe ist hier') -exports.respond = async (client, interaction: any): Promise => { - const embed = await getCommands(client) +exports.respond = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { + const embed = await getCommands(client, interaction) console.log(`User ${interaction.user.username} issued /help`) await interaction.reply({ embeds: [embed.setTimestamp()], ephemeral: true }) } -async function getCommands(client): Promise { +async function getCommands(client: DiscordClient, interaction: DiscordInteraction): Promise { const commandsEmbed = new MessageEmbed() .setColor('#ffa500') - .setAuthor({ name: 'Help', iconURL: 'https://bit.ly/3CJU0lf' }) + .setAuthor({ + name: client.translate({ key: 'slashCommands.help', lng: interaction.user.language }), + iconURL: 'https://bit.ly/3CJU0lf', + }) .setTimestamp() .setFooter({ text: `[ID] ${client.config.ids.userID.botUserID} \nstarted`, @@ -32,7 +36,7 @@ async function getCommands(client): Promise { return commandsEmbed } -async function addCommandsFromSubFolder(_commandsEmbed, file): Promise { +async function addCommandsFromSubFolder(embed: MessageEmbed, file: string): Promise { const sub_directory = `./commands/${file}/` try { const files = await fs.promises.readdir(sub_directory) @@ -41,7 +45,7 @@ async function addCommandsFromSubFolder(_commandsEmbed, file): Promise { const slicedFileName = command.split('.ts')[0] commandsInSubfolder += `${slicedFileName}\n` } - _commandsEmbed.addFields({ + embed.addFields({ name: file, value: commandsInSubfolder, inline: true, From 6bd1183077cd029d64a68e6e3ac2b23814277e22 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 14:42:55 +0100 Subject: [PATCH 58/71] update type --- types/customTypes.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/customTypes.ts b/types/customTypes.ts index 0c56758..3b407c7 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -8,7 +8,7 @@ import { Collection, User, GuildMemberRoleManager, - MessageComponentInteraction, + CommandInteraction, } from 'discord.js' import i18next from 'i18next' @@ -180,7 +180,7 @@ export interface DiscordMessage extends Message { /** * Extended Interaction to hold {@link DiscordUser} */ -export interface DiscordInteraction extends MessageComponentInteraction { +export interface DiscordInteraction extends CommandInteraction { user: DiscordUser } From 0d0340a1a472d56c72d64fa9277924fc534700a5 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 14:47:28 +0100 Subject: [PATCH 59/71] add translation to issue --- locales/de.json | 7 ++++++- locales/en.json | 7 ++++++- slashCommands/issue.ts | 14 +++++++------- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/locales/de.json b/locales/de.json index e4d6165..478ba96 100644 --- a/locales/de.json +++ b/locales/de.json @@ -71,7 +71,12 @@ }, "slashCommands": { "help": "Hilfe", - "issue": {}, + "issue": { + "Recieved": "Vorschlag angekommen!", + "Thanks": "Vielen Dank für deinen Vorschlag!", + "Error": "⚠Fehler", + "TryAgain": "Es ist ein Fehler aufgetreten. Bitte versuche es später erneut." + }, "ping": {}, "wochenplan": {} } diff --git a/locales/en.json b/locales/en.json index 89f96b7..a0fb4cd 100644 --- a/locales/en.json +++ b/locales/en.json @@ -71,7 +71,12 @@ }, "slashCommands": { "help": "Help", - "issue": {}, + "issue": { + "Recieved": "Issue recieved!", + "Thanks": "Thank you for submitting your issue!", + "Error": "⚠Error", + "TryAgain": "An error occured. Please try again later." + }, "ping": {}, "wochenplan": {} } diff --git a/slashCommands/issue.ts b/slashCommands/issue.ts index 9200363..021637d 100644 --- a/slashCommands/issue.ts +++ b/slashCommands/issue.ts @@ -1,6 +1,6 @@ import { SlashCommandBuilder } from '@discordjs/builders' import { MessageEmbed } from 'discord.js' -import { DiscordClient } from '../types/customTypes' +import { DiscordClient, DiscordInteraction } from '../types/customTypes' const createIssue = require('github-create-issue') const REPOSITORY = 'Chr1s70ph/ETIT-Master' @@ -10,9 +10,7 @@ export const data = new SlashCommandBuilder() .addStringOption(option => option.setName('vorschlag').setDescription('Mein Vorschlag').setRequired(true)) .addStringOption(option => option.setName('titel').setDescription('Titel meines Vorschlages')) -exports.respond = async (client: DiscordClient, interaction): Promise => { - console.log(`User ${interaction.user.username} issued /${interaction.commandName}`) - +exports.respond = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { const options = { token: client.config.github_token, body: interaction.options.getString('vorschlag'), @@ -30,7 +28,9 @@ exports.respond = async (client: DiscordClient, interaction): Promise => { await interaction.reply({ embeds: [ - new MessageEmbed().setTitle('Vorschlag angekommen!').setDescription('Vielen Dank für deinen Vorschlag!'), + new MessageEmbed() + .setTitle(client.translate({ key: 'slashCommands.issue.Recieved', lng: interaction.user.language })) + .setDescription(client.translate({ key: 'slashCommands.issue.Thanks', lng: interaction.user.language })), ], ephemeral: true, }) @@ -38,8 +38,8 @@ exports.respond = async (client: DiscordClient, interaction): Promise => { await interaction.reply({ embeds: [ new MessageEmbed() - .setTitle('⚠Fehler') - .setDescription('Es ist ein Fehler aufgetreten. Bitte versuche es später erneut.'), + .setTitle(client.translate({ key: 'slashCommands.issue.Error', lng: interaction.user.language })) + .setDescription(client.translate({ key: 'slashCommands.issue.TryAgain', lng: interaction.user.language })), ], }) throw new Error(error) From 41eeedaf2f01d95c0eea8173e3b430bcb5e57ac0 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 14:48:06 +0100 Subject: [PATCH 60/71] update types --- slashCommands/ping.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slashCommands/ping.ts b/slashCommands/ping.ts index e8160fe..0ab8846 100644 --- a/slashCommands/ping.ts +++ b/slashCommands/ping.ts @@ -1,10 +1,10 @@ import { SlashCommandBuilder } from '@discordjs/builders' +import { DiscordClient, DiscordInteraction } from '../types/customTypes' export const data = new SlashCommandBuilder() .setName('ping') .setDescription('Prüft, ob der Bot ordnungsgemäß antwortet') -exports.respond = async (client: any, interaction: any): Promise => { - console.log(`User ${interaction.user.username} issued /ping`) +exports.respond = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { await interaction.reply({ content: 'pong', ephemeral: true }) } From 229779fbb113bb2aa1231de3451cda7e72f780b2 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 14:56:20 +0100 Subject: [PATCH 61/71] add translation to wochenplan --- locales/de.json | 5 ++++- locales/en.json | 5 ++++- slashCommands/wochenplan.ts | 25 +++++++++++++++++++------ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/locales/de.json b/locales/de.json index 478ba96..fca25f6 100644 --- a/locales/de.json +++ b/locales/de.json @@ -78,6 +78,9 @@ "TryAgain": "Es ist ein Fehler aufgetreten. Bitte versuche es später erneut." }, "ping": {}, - "wochenplan": {} + "wochenplan": { + "Schedule": "🗓️ Wochenplan für {{user}}", + "Week": "Woche vom {{date}}" + } } } \ No newline at end of file diff --git a/locales/en.json b/locales/en.json index a0fb4cd..21d85ca 100644 --- a/locales/en.json +++ b/locales/en.json @@ -78,6 +78,9 @@ "TryAgain": "An error occured. Please try again later." }, "ping": {}, - "wochenplan": {} + "wochenplan": { + "Schedule": "🗓️ Weekly schedule for {{user}}", + "Week": "Week of {{date}}" + } } } \ No newline at end of file diff --git a/slashCommands/wochenplan.ts b/slashCommands/wochenplan.ts index c7f88fe..eccba1a 100644 --- a/slashCommands/wochenplan.ts +++ b/slashCommands/wochenplan.ts @@ -61,11 +61,11 @@ function _shortenSummary(pEventSummary) { return pEventSummary } -async function wochenplan(pClient: DiscordClient, pMessageOrInteraction, pNow, pCourseAndSemester) { +async function wochenplan(client: DiscordClient, interaction: DiscordInteraction, pNow, pCourseAndSemester) { let returnData = {} - for (const entry in pClient.config.calendars) { + for (const entry in client.config.calendars) { // eslint-disable-next-line no-await-in-loop - returnData = { ...returnData, ...(await async.fromURL(pClient.config.calendars[entry])) } + returnData = { ...returnData, ...(await async.fromURL(client.config.calendars[entry])) } } const relevantEvents = [] @@ -76,11 +76,24 @@ async function wochenplan(pClient: DiscordClient, pMessageOrInteraction, pNow, p const rangeStart = moment(startOfWeek) const rangeEnd = rangeStart.clone().add(7, 'days') - filterEvents(returnData, rangeStart, rangeEnd, pCourseAndSemester, pMessageOrInteraction, relevantEvents) + filterEvents(returnData, rangeStart, rangeEnd, pCourseAndSemester, interaction, relevantEvents) const embed = new MessageEmbed() - .setAuthor({ name: `🗓️ Wochenplan für ${pMessageOrInteraction.member.user.username}` }) - .setDescription(`Woche vom ${moment(startOfWeek).format('DD.MM.yyyy')}`) + .setAuthor({ + name: client.translate({ + key: 'slashCommands.wochenplan.Schedule', + options: { + user: interaction.user.username, + lng: interaction.user.language, + }, + }), + }) + .setDescription( + client.translate({ + key: 'slashCommands.wochenplan.Week', + options: { date: moment(startOfWeek).format('DD.MM.yyyy'), lng: interaction.user.language }, + }), + ) const weekdayItems = {} From de2b567b0f56ecb662095b29d72beb121bb21e22 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 15:25:42 +0100 Subject: [PATCH 62/71] rm logs --- scripts/addCommands.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/addCommands.ts b/scripts/addCommands.ts index e5d2be3..a65d855 100644 --- a/scripts/addCommands.ts +++ b/scripts/addCommands.ts @@ -124,7 +124,6 @@ async function postSlashCommands(client, slashCommandData) { try { console.log('Started refreshing application (/) commands.') - console.log(slashCommandData) await rest.put(Routes.applicationGuildCommands(client.config.ids.userID.botUserID, '757981349402378331'), { body: slashCommandData, }) From 0dc78c96256fc124df4c5eceef90f6370dfbe764 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 16:00:52 +0100 Subject: [PATCH 63/71] add inital lanuage selector --- locales/de.json | 6 ++++ locales/en.json | 6 ++++ slashCommands/language.ts | 68 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 slashCommands/language.ts diff --git a/locales/de.json b/locales/de.json index fca25f6..7342c0f 100644 --- a/locales/de.json +++ b/locales/de.json @@ -1,4 +1,6 @@ { + "language": "Deutsch", + "flag": "🇩🇪", "commands": { "admin": { "missingPermission": "Du bist nicht berechtigt, diesen Befehl auszuführen.", @@ -81,6 +83,10 @@ "wochenplan": { "Schedule": "🗓️ Wochenplan für {{user}}", "Week": "Woche vom {{date}}" + }, + "language": { + "Select": "Wähle deine bevorzugte Sprache", + "DefaultSelect": "Nichts ausgewählt" } } } \ No newline at end of file diff --git a/locales/en.json b/locales/en.json index 21d85ca..57545c4 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1,4 +1,6 @@ { + "language": "English", + "flag": "🇺🇸", "commands": { "admin": { "missingPermission": "You do not have permission to perform that command.", @@ -81,6 +83,10 @@ "wochenplan": { "Schedule": "🗓️ Weekly schedule for {{user}}", "Week": "Week of {{date}}" + }, + "language": { + "Select": "Select your desired language", + "DefaultSelect": "Nothing Selected" } } } \ No newline at end of file diff --git a/slashCommands/language.ts b/slashCommands/language.ts new file mode 100644 index 0000000..e3ca12d --- /dev/null +++ b/slashCommands/language.ts @@ -0,0 +1,68 @@ +import { readdir } from 'fs/promises' +import { SlashCommandBuilder } from '@discordjs/builders' +import { MessageActionRow, MessageSelectMenu } from 'discord.js' +import { DiscordClient, DiscordInteraction } from '../types/customTypes' + +export const data = new SlashCommandBuilder().setName('language').setDescription('Choose your language') + +exports.respond = async (client: DiscordClient, interaction: DiscordInteraction) => { + /** + * Array containing names of all language files + */ + const langFiles = await readdir('./locales/') + + /** + * Otions for {@link MessageActionRow} + */ + let options = [] + + /** + * Lopp through all languages + */ + for (const file in langFiles) { + /** + * Language indicator + */ + const lang = langFiles[file].split('.')[0] + + /** + * Language fully written out + */ + const languageName = client.translate({ key: 'language', lng: lang }) + + /** + * Option for {@link MessageActionRow} + */ + const option = { + label: `${client.translate({ key: 'flag', lng: lang })} ${languageName}`, + description: languageName, + value: lang, + } + + /** + * Add option to Array of all possible options + */ + options = [...options, option] + } + + /** + * Create new {@link MessageActionRow} + */ + const row = new MessageActionRow().addComponents( + /** + * Add {@link MessageSelectMenu} + */ + new MessageSelectMenu() + .setCustomId('languageSelector') + .setPlaceholder(client.translate({ key: 'slashCommands.language.DefaultSelect', lng: interaction.user.language })) + .addOptions(options), + ) + + /** + * Reply with {@link row} to interaction + */ + await interaction.reply({ + content: client.translate({ key: 'slashCommands.language.Select', lng: interaction.user.language }), + components: [row], + }) +} From f0e52cdfcc5a717b949b3d39b157423680ed97fd Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Fri, 31 Dec 2021 16:26:51 +0100 Subject: [PATCH 64/71] add inital lanuage selector response --- events/interactionCreate.ts | 32 ++++++++++++++++++++------------ slashCommands/help.ts | 1 - slashCommands/language.ts | 11 +++++++++-- types/customTypes.ts | 6 ++++++ 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/events/interactionCreate.ts b/events/interactionCreate.ts index eb8adab..cf020d3 100644 --- a/events/interactionCreate.ts +++ b/events/interactionCreate.ts @@ -1,19 +1,27 @@ import { DiscordClient, DiscordInteraction } from '../types/customTypes' -exports.run = (client: DiscordClient, interaction: DiscordInteraction) => { - if (interaction.isCommand()) { - /** - * File to the corrospinging slashCommand. - */ - const commandfile = client.slashCommands.get(interaction.commandName) - - /** - * Set language for user - */ - client.getLanguage(undefined, interaction) +exports.run = (client: DiscordClient, interaction: any) => { + /** + * File to the corrospinging slashCommand. + */ + const commandfile = client.slashCommands.get(interaction.commandName) - console.log(`${interaction.member.user.username} issued /${interaction.commandName}`) + /** + * Set language for user + */ + client.getLanguage(undefined, interaction) + console.log(`${interaction.member.user.username} issued /${interaction.commandName}`) + if (interaction.isCommand()) { commandfile.respond(client, interaction) + } else if (interaction.isSelectMenu()) { + try { + /** + * TODO commandfile is undefined + */ + commandfile.selectMenuResponse(client, interaction) + } catch (error) { + console.log(error) + } } } diff --git a/slashCommands/help.ts b/slashCommands/help.ts index 286a861..0c98c40 100644 --- a/slashCommands/help.ts +++ b/slashCommands/help.ts @@ -7,7 +7,6 @@ export const data = new SlashCommandBuilder().setName('help').setDescription('hi exports.respond = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { const embed = await getCommands(client, interaction) - console.log(`User ${interaction.user.username} issued /help`) await interaction.reply({ embeds: [embed.setTimestamp()], ephemeral: true }) } diff --git a/slashCommands/language.ts b/slashCommands/language.ts index e3ca12d..0f0feba 100644 --- a/slashCommands/language.ts +++ b/slashCommands/language.ts @@ -1,7 +1,7 @@ import { readdir } from 'fs/promises' import { SlashCommandBuilder } from '@discordjs/builders' import { MessageActionRow, MessageSelectMenu } from 'discord.js' -import { DiscordClient, DiscordInteraction } from '../types/customTypes' +import { DiscordClient, DiscordContextMenuInteraction, DiscordInteraction } from '../types/customTypes' export const data = new SlashCommandBuilder().setName('language').setDescription('Choose your language') @@ -53,7 +53,7 @@ exports.respond = async (client: DiscordClient, interaction: DiscordInteraction) * Add {@link MessageSelectMenu} */ new MessageSelectMenu() - .setCustomId('languageSelector') + .setCustomId('language') .setPlaceholder(client.translate({ key: 'slashCommands.language.DefaultSelect', lng: interaction.user.language })) .addOptions(options), ) @@ -66,3 +66,10 @@ exports.respond = async (client: DiscordClient, interaction: DiscordInteraction) components: [row], }) } + +exports.selectMenuResponse = (client: DiscordClient, interaction: DiscordContextMenuInteraction) => { + /** + * TODO reply to select menu + */ + console.log('HERE') +} diff --git a/types/customTypes.ts b/types/customTypes.ts index 3b407c7..44a6d28 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -9,6 +9,7 @@ import { User, GuildMemberRoleManager, CommandInteraction, + ContextMenuInteraction, } from 'discord.js' import i18next from 'i18next' @@ -184,6 +185,10 @@ export interface DiscordInteraction extends CommandInteraction { user: DiscordUser } +export interface DiscordContextMenuInteraction extends ContextMenuInteraction { + user: DiscordUser +} + /** * Extended User to hold language. */ @@ -216,4 +221,5 @@ interface SlashCommand extends Object { description: string usage: string respond: any + selectMenuResponse?: any } From 571a92f51350a389a7f2aba61cb05e50965eb9c7 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 3 Jan 2022 20:50:43 +0100 Subject: [PATCH 65/71] add functionality for multiple interaction types --- events/interactionCreate.ts | 20 ++++++++++--------- index.ts | 6 +++--- .../{addCommands.ts => addInteractions.ts} | 2 +- slashCommands/help.ts | 2 +- slashCommands/issue.ts | 4 +--- slashCommands/language.ts | 4 ++-- slashCommands/ping.ts | 2 +- slashCommands/wochenplan.ts | 2 +- types/customTypes.ts | 19 ++++++++++++------ 9 files changed, 34 insertions(+), 27 deletions(-) rename scripts/{addCommands.ts => addInteractions.ts} (98%) diff --git a/events/interactionCreate.ts b/events/interactionCreate.ts index cf020d3..9f17303 100644 --- a/events/interactionCreate.ts +++ b/events/interactionCreate.ts @@ -1,25 +1,27 @@ -import { DiscordClient, DiscordInteraction } from '../types/customTypes' +import { DiscordClient } from '../types/customTypes' exports.run = (client: DiscordClient, interaction: any) => { /** - * File to the corrospinging slashCommand. + * Name of the interaction */ - const commandfile = client.slashCommands.get(interaction.commandName) + const commandName = interaction.customId?.split('.')[0] ?? interaction.commandName + + /** + * File to the corrospinging interaction. + */ + const commandfile = client.interactions.get(commandName) /** * Set language for user */ client.getLanguage(undefined, interaction) - console.log(`${interaction.member.user.username} issued /${interaction.commandName}`) + console.log(`${interaction.member.user.username} used ${commandName}`) if (interaction.isCommand()) { - commandfile.respond(client, interaction) + commandfile.Command(client, interaction) } else if (interaction.isSelectMenu()) { try { - /** - * TODO commandfile is undefined - */ - commandfile.selectMenuResponse(client, interaction) + commandfile.SelectMenu(client, interaction) } catch (error) { console.log(error) } diff --git a/index.ts b/index.ts index 3bf375a..5868e0e 100644 --- a/index.ts +++ b/index.ts @@ -47,9 +47,9 @@ const client: DiscordClient = new DiscordClient({ client.commands = new Collection() /** - * Set {@link DiscordClient} slashCommands to new {@link Collection} + * Set {@link DiscordClient} interactions to new {@link Collection} */ -client.slashCommands = new Collection() +client.interactions = new Collection() /** * Set config. @@ -61,7 +61,7 @@ client.config = config */ client.login(client.config.botToken) -const LoadCommands = require('./scripts/addCommands') +const LoadCommands = require('./scripts/addInteractions') LoadCommands.run(client) /** diff --git a/scripts/addCommands.ts b/scripts/addInteractions.ts similarity index 98% rename from scripts/addCommands.ts rename to scripts/addInteractions.ts index a65d855..92ed9fb 100644 --- a/scripts/addCommands.ts +++ b/scripts/addInteractions.ts @@ -113,7 +113,7 @@ export async function loadSlashCommands(client: DiscordClient) { const commandName = file.split('.')[0] - client.slashCommands.set(commandName, slashCommand) + client.interactions.set(commandName, slashCommand) console.log(`Successfully posted slashCommand ${file}`) }) postSlashCommands(client, slashCommandData) diff --git a/slashCommands/help.ts b/slashCommands/help.ts index 0c98c40..6ffa417 100644 --- a/slashCommands/help.ts +++ b/slashCommands/help.ts @@ -5,7 +5,7 @@ const fs = require('fs') export const data = new SlashCommandBuilder().setName('help').setDescription('hilfe ist hier') -exports.respond = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { +exports.Command = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { const embed = await getCommands(client, interaction) await interaction.reply({ embeds: [embed.setTimestamp()], ephemeral: true }) } diff --git a/slashCommands/issue.ts b/slashCommands/issue.ts index 94cbfcc..bd8d73a 100644 --- a/slashCommands/issue.ts +++ b/slashCommands/issue.ts @@ -10,7 +10,7 @@ export const data = new SlashCommandBuilder() .addStringOption(option => option.setName('vorschlag').setDescription('Mein Vorschlag').setRequired(true)) .addStringOption(option => option.setName('titel').setDescription('Titel meines Vorschlages')) -exports.respond = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { +exports.Command = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { const options = { token: client.config.github_token, body: interaction.options.getString('vorschlag'), @@ -31,7 +31,6 @@ exports.respond = async (client: DiscordClient, interaction: DiscordInteraction) new MessageEmbed() .setTitle(client.translate({ key: 'slashCommands.issue.Recieved', lng: interaction.user.language })) .setDescription(client.translate({ key: 'slashCommands.issue.Thanks', lng: interaction.user.language })), - ], ephemeral: true, }) @@ -41,7 +40,6 @@ exports.respond = async (client: DiscordClient, interaction: DiscordInteraction) new MessageEmbed() .setTitle(client.translate({ key: 'slashCommands.issue.Error', lng: interaction.user.language })) .setDescription(client.translate({ key: 'slashCommands.issue.TryAgain', lng: interaction.user.language })), - ], }) throw new Error(error) diff --git a/slashCommands/language.ts b/slashCommands/language.ts index 0f0feba..41d8f37 100644 --- a/slashCommands/language.ts +++ b/slashCommands/language.ts @@ -5,7 +5,7 @@ import { DiscordClient, DiscordContextMenuInteraction, DiscordInteraction } from export const data = new SlashCommandBuilder().setName('language').setDescription('Choose your language') -exports.respond = async (client: DiscordClient, interaction: DiscordInteraction) => { +exports.Command = async (client: DiscordClient, interaction: DiscordInteraction) => { /** * Array containing names of all language files */ @@ -67,7 +67,7 @@ exports.respond = async (client: DiscordClient, interaction: DiscordInteraction) }) } -exports.selectMenuResponse = (client: DiscordClient, interaction: DiscordContextMenuInteraction) => { +exports.SelectMenu = (client: DiscordClient, interaction: DiscordContextMenuInteraction) => { /** * TODO reply to select menu */ diff --git a/slashCommands/ping.ts b/slashCommands/ping.ts index 0ab8846..12106f0 100644 --- a/slashCommands/ping.ts +++ b/slashCommands/ping.ts @@ -5,6 +5,6 @@ export const data = new SlashCommandBuilder() .setName('ping') .setDescription('Prüft, ob der Bot ordnungsgemäß antwortet') -exports.respond = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { +exports.Command = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { await interaction.reply({ content: 'pong', ephemeral: true }) } diff --git a/slashCommands/wochenplan.ts b/slashCommands/wochenplan.ts index eccba1a..0486936 100644 --- a/slashCommands/wochenplan.ts +++ b/slashCommands/wochenplan.ts @@ -242,7 +242,7 @@ function pushToWeeksEvents(interaction, event, relevantEvents) { } } -exports.respond = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { +exports.Command = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { const now = new Date() const embed = wochenplan(client, interaction, now, 'all') diff --git a/types/customTypes.ts b/types/customTypes.ts index 44a6d28..d94205c 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -25,10 +25,10 @@ export class DiscordClient extends Client { public commands: Collection /** - * Collection of all slashCommands to use - * @type {Collection} + * Collection of all interactions to use + * @type {Collection} */ - public slashCommands: Collection + public interactions: Collection /** * Config file imported into the DiscordClient for global access @@ -216,10 +216,17 @@ interface Command extends Object { aliases: string[] } -interface SlashCommand extends Object { +interface Interaction extends Object { name: string description: string usage: string - respond: any - selectMenuResponse?: any + ApplicationCommand?: any + Autocomplete?: any + Button?: any + Command?: any + ContextMenu?: any + MessageComponent?: any + MessageContextMenu?: any + SelectMenu?: any + UserContextMenu?: any } From e9c326a51ebe8e038548de430378c75c40b81972 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 3 Jan 2022 21:15:57 +0100 Subject: [PATCH 66/71] rm double types and add case handlign --- events/interactionCreate.ts | 17 +++++++++++------ types/customTypes.ts | 3 --- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/events/interactionCreate.ts b/events/interactionCreate.ts index 9f17303..aafa441 100644 --- a/events/interactionCreate.ts +++ b/events/interactionCreate.ts @@ -17,13 +17,18 @@ exports.run = (client: DiscordClient, interaction: any) => { client.getLanguage(undefined, interaction) console.log(`${interaction.member.user.username} used ${commandName}`) - if (interaction.isCommand()) { + + if (interaction.isAutocomplete()) { + commandfile.Autocomplete(client, interaction) + } else if (interaction.isButton()) { + commandfile.Button(client, interaction) + } else if (interaction.isCommand()) { commandfile.Command(client, interaction) + } else if (interaction.isMessageContextMenu()) { + commandfile.MessageContextMenu(client, interaction) } else if (interaction.isSelectMenu()) { - try { - commandfile.SelectMenu(client, interaction) - } catch (error) { - console.log(error) - } + commandfile.SelectMenu(client, interaction) + } else if (interaction.isUserContextMenu()) { + commandfile.UserContextMenu(client, interaction) } } diff --git a/types/customTypes.ts b/types/customTypes.ts index d94205c..accac63 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -220,12 +220,9 @@ interface Interaction extends Object { name: string description: string usage: string - ApplicationCommand?: any Autocomplete?: any Button?: any Command?: any - ContextMenu?: any - MessageComponent?: any MessageContextMenu?: any SelectMenu?: any UserContextMenu?: any From 4a7253622c321262a80da242c7965f1c340c0b88 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 3 Jan 2022 21:35:20 +0100 Subject: [PATCH 67/71] add propper interaction types --- events/interactionCreate.ts | 28 ++++++++++++++----- slashCommands/help.ts | 6 ++--- slashCommands/issue.ts | 4 +-- slashCommands/language.ts | 6 ++--- slashCommands/ping.ts | 4 +-- slashCommands/wochenplan.ts | 6 ++--- types/customTypes.ts | 54 ++++++++++++++++++++++++++++++------- 7 files changed, 79 insertions(+), 29 deletions(-) diff --git a/events/interactionCreate.ts b/events/interactionCreate.ts index aafa441..77e4173 100644 --- a/events/interactionCreate.ts +++ b/events/interactionCreate.ts @@ -1,4 +1,12 @@ -import { DiscordClient } from '../types/customTypes' +import { + DiscordAutocompleteInteraction, + DiscordButtonInteraction, + DiscordClient, + DiscordCommandInteraction, + DiscordMessageContextMenuInteraction, + DiscordSelectMenuInteraction, + DiscordUserContextMenuInteraction, +} from '../types/customTypes' exports.run = (client: DiscordClient, interaction: any) => { /** @@ -19,16 +27,22 @@ exports.run = (client: DiscordClient, interaction: any) => { console.log(`${interaction.member.user.username} used ${commandName}`) if (interaction.isAutocomplete()) { - commandfile.Autocomplete(client, interaction) + const DiscordInteraction = interaction as DiscordAutocompleteInteraction + commandfile.Autocomplete(client, DiscordInteraction) } else if (interaction.isButton()) { - commandfile.Button(client, interaction) + const DiscordInteraction = interaction as DiscordButtonInteraction + commandfile.Button(client, DiscordInteraction) } else if (interaction.isCommand()) { - commandfile.Command(client, interaction) + const DiscordInteraction = interaction as DiscordCommandInteraction + commandfile.Command(client, DiscordInteraction) } else if (interaction.isMessageContextMenu()) { - commandfile.MessageContextMenu(client, interaction) + const DiscordInteraction = interaction as DiscordMessageContextMenuInteraction + commandfile.MessageContextMenu(client, DiscordInteraction) } else if (interaction.isSelectMenu()) { - commandfile.SelectMenu(client, interaction) + const DiscordInteraction = interaction as DiscordSelectMenuInteraction + commandfile.SelectMenu(client, DiscordInteraction) } else if (interaction.isUserContextMenu()) { - commandfile.UserContextMenu(client, interaction) + const DiscordInteraction = interaction as DiscordUserContextMenuInteraction + commandfile.UserContextMenu(client, DiscordInteraction) } } diff --git a/slashCommands/help.ts b/slashCommands/help.ts index 6ffa417..1038d45 100644 --- a/slashCommands/help.ts +++ b/slashCommands/help.ts @@ -1,16 +1,16 @@ import { SlashCommandBuilder } from '@discordjs/builders' import { MessageEmbed } from 'discord.js' -import { DiscordClient, DiscordInteraction } from '../types/customTypes' +import { DiscordClient, DiscordCommandInteraction } from '../types/customTypes' const fs = require('fs') export const data = new SlashCommandBuilder().setName('help').setDescription('hilfe ist hier') -exports.Command = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { +exports.Command = async (client: DiscordClient, interaction: DiscordCommandInteraction): Promise => { const embed = await getCommands(client, interaction) await interaction.reply({ embeds: [embed.setTimestamp()], ephemeral: true }) } -async function getCommands(client: DiscordClient, interaction: DiscordInteraction): Promise { +async function getCommands(client: DiscordClient, interaction: DiscordCommandInteraction): Promise { const commandsEmbed = new MessageEmbed() .setColor('#ffa500') .setAuthor({ diff --git a/slashCommands/issue.ts b/slashCommands/issue.ts index bd8d73a..6cf04b3 100644 --- a/slashCommands/issue.ts +++ b/slashCommands/issue.ts @@ -1,6 +1,6 @@ import { SlashCommandBuilder } from '@discordjs/builders' import { MessageEmbed } from 'discord.js' -import { DiscordClient, DiscordInteraction } from '../types/customTypes' +import { DiscordClient, DiscordCommandInteraction } from '../types/customTypes' const createIssue = require('github-create-issue') const REPOSITORY = 'Chr1s70ph/ETIT-Master' @@ -10,7 +10,7 @@ export const data = new SlashCommandBuilder() .addStringOption(option => option.setName('vorschlag').setDescription('Mein Vorschlag').setRequired(true)) .addStringOption(option => option.setName('titel').setDescription('Titel meines Vorschlages')) -exports.Command = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { +exports.Command = async (client: DiscordClient, interaction: DiscordCommandInteraction): Promise => { const options = { token: client.config.github_token, body: interaction.options.getString('vorschlag'), diff --git a/slashCommands/language.ts b/slashCommands/language.ts index 41d8f37..2d92a57 100644 --- a/slashCommands/language.ts +++ b/slashCommands/language.ts @@ -1,11 +1,11 @@ import { readdir } from 'fs/promises' import { SlashCommandBuilder } from '@discordjs/builders' import { MessageActionRow, MessageSelectMenu } from 'discord.js' -import { DiscordClient, DiscordContextMenuInteraction, DiscordInteraction } from '../types/customTypes' +import { DiscordClient, DiscordCommandInteraction, DiscordSelectMenuInteraction } from '../types/customTypes' export const data = new SlashCommandBuilder().setName('language').setDescription('Choose your language') -exports.Command = async (client: DiscordClient, interaction: DiscordInteraction) => { +exports.Command = async (client: DiscordClient, interaction: DiscordCommandInteraction) => { /** * Array containing names of all language files */ @@ -67,7 +67,7 @@ exports.Command = async (client: DiscordClient, interaction: DiscordInteraction) }) } -exports.SelectMenu = (client: DiscordClient, interaction: DiscordContextMenuInteraction) => { +exports.SelectMenu = (client: DiscordClient, interaction: DiscordSelectMenuInteraction) => { /** * TODO reply to select menu */ diff --git a/slashCommands/ping.ts b/slashCommands/ping.ts index 12106f0..2a433f7 100644 --- a/slashCommands/ping.ts +++ b/slashCommands/ping.ts @@ -1,10 +1,10 @@ import { SlashCommandBuilder } from '@discordjs/builders' -import { DiscordClient, DiscordInteraction } from '../types/customTypes' +import { DiscordClient, DiscordCommandInteraction } from '../types/customTypes' export const data = new SlashCommandBuilder() .setName('ping') .setDescription('Prüft, ob der Bot ordnungsgemäß antwortet') -exports.Command = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { +exports.Command = async (client: DiscordClient, interaction: DiscordCommandInteraction): Promise => { await interaction.reply({ content: 'pong', ephemeral: true }) } diff --git a/slashCommands/wochenplan.ts b/slashCommands/wochenplan.ts index 0486936..724c667 100644 --- a/slashCommands/wochenplan.ts +++ b/slashCommands/wochenplan.ts @@ -2,7 +2,7 @@ import { SlashCommandBuilder } from '@discordjs/builders' import { MessageEmbed } from 'discord.js' import moment from 'moment-timezone' import { async } from 'node-ical' -import { DiscordClient, DiscordInteraction } from '../types/customTypes' +import { DiscordClient, DiscordCommandInteraction } from '../types/customTypes' exports.name = 'wochenplan' @@ -61,7 +61,7 @@ function _shortenSummary(pEventSummary) { return pEventSummary } -async function wochenplan(client: DiscordClient, interaction: DiscordInteraction, pNow, pCourseAndSemester) { +async function wochenplan(client: DiscordClient, interaction: DiscordCommandInteraction, pNow, pCourseAndSemester) { let returnData = {} for (const entry in client.config.calendars) { // eslint-disable-next-line no-await-in-loop @@ -242,7 +242,7 @@ function pushToWeeksEvents(interaction, event, relevantEvents) { } } -exports.Command = async (client: DiscordClient, interaction: DiscordInteraction): Promise => { +exports.Command = async (client: DiscordClient, interaction: DiscordCommandInteraction): Promise => { const now = new Date() const embed = wochenplan(client, interaction, now, 'all') diff --git a/types/customTypes.ts b/types/customTypes.ts index accac63..5708d60 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -4,12 +4,17 @@ import { Message, // eslint-disable-next-line @typescript-eslint/no-unused-vars TextChannel, + Interaction, MessageOptions, Collection, User, GuildMemberRoleManager, CommandInteraction, - ContextMenuInteraction, + AutocompleteInteraction, + ButtonInteraction, + MessageContextMenuInteraction, + SelectMenuInteraction, + UserContextMenuInteraction, } from 'discord.js' import i18next from 'i18next' @@ -26,9 +31,9 @@ export class DiscordClient extends Client { /** * Collection of all interactions to use - * @type {Collection} + * @type {Collection} */ - public interactions: Collection + public interactions: Collection /** * Config file imported into the DiscordClient for global access @@ -118,11 +123,11 @@ export class DiscordClient extends Client { * @param {DiscordInteraction} interaction Interaction used by user * @returns {string} */ - public getLanguage(message?: DiscordMessage, interaction?: DiscordInteraction): string { + public getLanguage(message?: DiscordMessage, interaction?: Interaction): string { /** * Object of {@link DiscordUser} */ - const user = message ? message.author : interaction.user + const user = message ? message.author : (interaction.user as DiscordUser) /** * List of all defined languages in './locales/'. @@ -179,13 +184,44 @@ export interface DiscordMessage extends Message { } /** - * Extended Interaction to hold {@link DiscordUser} + * Extended {@link AutocompleteInteraction} to hold {@link DiscordUser} */ -export interface DiscordInteraction extends CommandInteraction { +export interface DiscordAutocompleteInteraction extends AutocompleteInteraction { user: DiscordUser } -export interface DiscordContextMenuInteraction extends ContextMenuInteraction { +/** + * Extended {@link ButtonInteraction} to hold {@link DiscordUser} + */ +export interface DiscordButtonInteraction extends ButtonInteraction { + user: DiscordUser +} + +/** + * Extended {@link CommandInteraction} to hold {@link DiscordUser} + */ +export interface DiscordCommandInteraction extends CommandInteraction { + user: DiscordUser +} + +/** + * Extended {@link MessageContextMenuInteraction} to hold {@link DiscordUser} + */ +export interface DiscordMessageContextMenuInteraction extends MessageContextMenuInteraction { + user: DiscordUser +} + +/** + * Extended {@link SelectMenuInteraction} to hold {@link DiscordUser} + */ +export interface DiscordSelectMenuInteraction extends SelectMenuInteraction { + user: DiscordUser +} + +/** + * Extended {@link UserContextMenuInteraction} to hold {@link DiscordUser} + */ +export interface DiscordUserContextMenuInteraction extends UserContextMenuInteraction { user: DiscordUser } @@ -216,7 +252,7 @@ interface Command extends Object { aliases: string[] } -interface Interaction extends Object { +interface InteractionCommands extends Object { name: string description: string usage: string From 7f77e025927874396c973d4f2f8b33afb366856c Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 3 Jan 2022 22:46:52 +0100 Subject: [PATCH 68/71] add role giving thing --- index.ts | 2 +- {slashCommands => interactions}/help.ts | 0 {slashCommands => interactions}/issue.ts | 0 {slashCommands => interactions}/language.ts | 54 +++++++++++++++++-- {slashCommands => interactions}/ping.ts | 0 {slashCommands => interactions}/wochenplan.ts | 0 locales/de.json | 3 +- locales/en.json | 3 +- scripts/addInteractions.ts | 2 +- types/customTypes.ts | 8 +++ 10 files changed, 63 insertions(+), 9 deletions(-) rename {slashCommands => interactions}/help.ts (100%) rename {slashCommands => interactions}/issue.ts (100%) rename {slashCommands => interactions}/language.ts (50%) rename {slashCommands => interactions}/ping.ts (100%) rename {slashCommands => interactions}/wochenplan.ts (100%) diff --git a/index.ts b/index.ts index 5868e0e..fba4bfe 100644 --- a/index.ts +++ b/index.ts @@ -13,7 +13,7 @@ const backend = new Backend({ i18next.use(backend).init({ lng: 'en', fallbackLng: 'en', - preload: ['en', 'de'], + preload: ['en', 'de', 'fr'], ns: ['translation'], defaultNS: 'translation', debug: true, diff --git a/slashCommands/help.ts b/interactions/help.ts similarity index 100% rename from slashCommands/help.ts rename to interactions/help.ts diff --git a/slashCommands/issue.ts b/interactions/issue.ts similarity index 100% rename from slashCommands/issue.ts rename to interactions/issue.ts diff --git a/slashCommands/language.ts b/interactions/language.ts similarity index 50% rename from slashCommands/language.ts rename to interactions/language.ts index 2d92a57..67fc7b2 100644 --- a/slashCommands/language.ts +++ b/interactions/language.ts @@ -1,7 +1,7 @@ import { readdir } from 'fs/promises' import { SlashCommandBuilder } from '@discordjs/builders' -import { MessageActionRow, MessageSelectMenu } from 'discord.js' -import { DiscordClient, DiscordCommandInteraction, DiscordSelectMenuInteraction } from '../types/customTypes' +import { MessageActionRow, MessageEmbed, MessageSelectMenu, SelectMenuInteraction } from 'discord.js' +import { DiscordClient, DiscordCommandInteraction } from '../types/customTypes' export const data = new SlashCommandBuilder().setName('language').setDescription('Choose your language') @@ -64,12 +64,56 @@ exports.Command = async (client: DiscordClient, interaction: DiscordCommandInter await interaction.reply({ content: client.translate({ key: 'slashCommands.language.Select', lng: interaction.user.language }), components: [row], + ephemeral: true, }) } -exports.SelectMenu = (client: DiscordClient, interaction: DiscordSelectMenuInteraction) => { +exports.SelectMenu = async (client: DiscordClient, interaction: SelectMenuInteraction) => { + const interactionUser = await interaction.guild.members.fetch(interaction.user.id) + const userRoles = interactionUser.roles.cache.map(role => role) + + /** + * Remove all language roles + */ + await interactionUser.roles.remove(userRoles.filter(role => role.name.length === 2)) + if (interaction.values[0] !== 'en') { + /** + * Fetch language Role + */ + const languageRole = await interaction.guild.roles.cache.find(role => role.name === interaction.values[0]) + /** + * Give user language Role + */ + interactionUser.roles.add(languageRole) + console.log(`Gave ${interactionUser.displayName} languageRole: ${languageRole}`) + } /** - * TODO reply to select menu + * Flag of selected language */ - console.log('HERE') + const flag = client.translate({ key: 'flag', lng: interaction.values[0] }) + + /** + * Name of selected language + */ + const language = client.translate({ key: 'language', lng: interaction.values[0] }) + + /** + * Notify user, that language has been updated + */ + interaction.update({ + embeds: [ + new MessageEmbed() + .setTitle( + client.translate({ + key: 'slashCommands.language.LanguageUpdated', + options: { + language: `${flag} ${language}`, + lng: interaction.values[0], + }, + }), + ) + .setFooter({ text: client.user.username, iconURL: client.user.avatarURL() }), + ], + components: [], + }) } diff --git a/slashCommands/ping.ts b/interactions/ping.ts similarity index 100% rename from slashCommands/ping.ts rename to interactions/ping.ts diff --git a/slashCommands/wochenplan.ts b/interactions/wochenplan.ts similarity index 100% rename from slashCommands/wochenplan.ts rename to interactions/wochenplan.ts diff --git a/locales/de.json b/locales/de.json index 7342c0f..4102b22 100644 --- a/locales/de.json +++ b/locales/de.json @@ -86,7 +86,8 @@ }, "language": { "Select": "Wähle deine bevorzugte Sprache", - "DefaultSelect": "Nichts ausgewählt" + "DefaultSelect": "Nichts ausgewählt", + "LanguageUpdated": "Sprache wurde erfolgreich zu {{language}} geändert." } } } \ No newline at end of file diff --git a/locales/en.json b/locales/en.json index 57545c4..44c48e6 100644 --- a/locales/en.json +++ b/locales/en.json @@ -86,7 +86,8 @@ }, "language": { "Select": "Select your desired language", - "DefaultSelect": "Nothing Selected" + "DefaultSelect": "Nothing Selected", + "LanguageUpdated": "Language has been successfully updated to {{language}}." } } } \ No newline at end of file diff --git a/scripts/addInteractions.ts b/scripts/addInteractions.ts index 92ed9fb..901c8a6 100644 --- a/scripts/addInteractions.ts +++ b/scripts/addInteractions.ts @@ -12,7 +12,7 @@ const commandsFolder = './commands/' /** * Folder that contains all slashCommands. */ -const slashCommandsFolder = './slashCommands/' +const slashCommandsFolder = './interactions/' exports.run = (client: DiscordClient) => { Commands(client) diff --git a/types/customTypes.ts b/types/customTypes.ts index 5708d60..575a5bd 100644 --- a/types/customTypes.ts +++ b/types/customTypes.ts @@ -15,6 +15,7 @@ import { MessageContextMenuInteraction, SelectMenuInteraction, UserContextMenuInteraction, + ApplicationCommand, } from 'discord.js' import i18next from 'i18next' @@ -263,3 +264,10 @@ interface InteractionCommands extends Object { SelectMenu?: any UserContextMenu?: any } + +/** + * Extended {@link ApplicationCommand} to hold {@link DiscordUser} + */ +export interface DiscordApplicationCommand extends ApplicationCommand { + user: DiscordUser +} From 47bae87f6b39941f86bf697eacd387728de9304a Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 3 Jan 2022 22:47:34 +0100 Subject: [PATCH 69/71] rm debugging var --- index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.ts b/index.ts index fba4bfe..5868e0e 100644 --- a/index.ts +++ b/index.ts @@ -13,7 +13,7 @@ const backend = new Backend({ i18next.use(backend).init({ lng: 'en', fallbackLng: 'en', - preload: ['en', 'de', 'fr'], + preload: ['en', 'de'], ns: ['translation'], defaultNS: 'translation', debug: true, From 6577dab0acb8caa325f16880d7436024a4343131 Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 3 Jan 2022 22:49:36 +0100 Subject: [PATCH 70/71] rm content and update log --- interactions/language.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interactions/language.ts b/interactions/language.ts index 67fc7b2..85005ea 100644 --- a/interactions/language.ts +++ b/interactions/language.ts @@ -85,7 +85,7 @@ exports.SelectMenu = async (client: DiscordClient, interaction: SelectMenuIntera * Give user language Role */ interactionUser.roles.add(languageRole) - console.log(`Gave ${interactionUser.displayName} languageRole: ${languageRole}`) + console.log(`Gave ${interactionUser.displayName} languageRole: ${languageRole.name}`) } /** * Flag of selected language @@ -101,6 +101,7 @@ exports.SelectMenu = async (client: DiscordClient, interaction: SelectMenuIntera * Notify user, that language has been updated */ interaction.update({ + content: null, embeds: [ new MessageEmbed() .setTitle( From 68f836439a9eed4071fe5bdcc72f5d4145e1f34a Mon Sep 17 00:00:00 2001 From: Christoph <29735603+Chr1s70ph@users.noreply.github.com> Date: Mon, 3 Jan 2022 23:04:10 +0100 Subject: [PATCH 71/71] fix scripts not loading --- events/ready.ts | 38 ++++++++++++++- index.ts | 46 ------------------- .../{addInteractions.ts => addCommands.ts} | 0 scripts/loginMessage.ts | 6 +-- 4 files changed, 40 insertions(+), 50 deletions(-) rename scripts/{addInteractions.ts => addCommands.ts} (100%) diff --git a/events/ready.ts b/events/ready.ts index 52577ac..d13ff36 100644 --- a/events/ready.ts +++ b/events/ready.ts @@ -1,5 +1,41 @@ -exports.run = () => +import { readdir } from 'fs/promises' +import { DiscordClient } from '../types/customTypes' + +exports.run = async (client: DiscordClient) => { + await loadScripts(client) /** * Log that the bot is online and operational. */ console.log('Online!') +} + +/** + * Load and run all scripts. + * @param {DiscordClient} client Bot-Client + */ +async function loadScripts(client) { + /** + * Read directory. + */ + const files = await readdir('./scripts/') + + files.forEach(file => { + /** + * Path of script. + */ + const script = require(`../scripts/${file}`) + + try { + /** + * Run scripts. + */ + script.run(client) + } catch (e) { + /** + * Error handling. + */ + throw new Error(e) + } + console.log(`Successfully started script ${file}`) + }) +} diff --git a/index.ts b/index.ts index 5868e0e..ea3d29b 100644 --- a/index.ts +++ b/index.ts @@ -61,9 +61,6 @@ client.config = config */ client.login(client.config.botToken) -const LoadCommands = require('./scripts/addInteractions') -LoadCommands.run(client) - /** * Load and run events. */ @@ -95,46 +92,3 @@ fs.readdir('./events/', (err, files) => { client.on(eventName, (...args) => eventFunc.run(client, ...args)) }) }) - -/** - * Load and run all scripts. - * @param {DiscordClient} _client Bot-Client - */ -export async function loadScripts(_client: DiscordClient) { - /** - * Object with all files of scripts directory. - */ - let files - - try { - /** - * Read directory. - */ - files = await fs.promises.readdir('./scripts/') - } catch (e) { - /** - * Error handling. - */ - throw new Error(e) - } - - files.forEach(file => { - /** - * Path of script. - */ - const script = require(`./scripts/${file}`) - - try { - /** - * Run scripts. - */ - script.run(_client) - } catch (e) { - /** - * Error handling. - */ - throw new Error(e) - } - console.log(`Successfully started script ${file}`) - }) -} diff --git a/scripts/addInteractions.ts b/scripts/addCommands.ts similarity index 100% rename from scripts/addInteractions.ts rename to scripts/addCommands.ts diff --git a/scripts/loginMessage.ts b/scripts/loginMessage.ts index 8cf098c..61bd553 100644 --- a/scripts/loginMessage.ts +++ b/scripts/loginMessage.ts @@ -19,12 +19,12 @@ exports.run = async (client: DiscordClient) => { /** * List of slashCommands. */ - const slashCount = await readdir_promise('./slashCommands') + const interactionCount = await readdir_promise('./interactions/') /** * Login message {@link MessageEmbed}. */ - const loginMessage = createEmbed(client, commands, slashCount) + const loginMessage = createEmbed(client, commands, interactionCount) /** * Channel to send {@link loginMessage} to. @@ -75,7 +75,7 @@ function createEmbed(client: DiscordClient, commands: any[], slashCount: string[ inline: true, }, { - name: 'SlashCommands geladen:', + name: 'Interactions geladen:', value: slashCount.length.toString(), inline: true, },