From c597f951cf8cc4c92135e15a2f52514067186d5c Mon Sep 17 00:00:00 2001 From: evermake Date: Mon, 8 Apr 2024 20:13:47 +0300 Subject: [PATCH 1/6] add bot's commands and descriptions, add option to run `setMy...` commands --- backend/package.json | 2 ++ backend/src/main.ts | 50 ++++++++++++++++++++++++++++++++ backend/src/translations/_en.tsx | 7 +++++ backend/src/translations/_ru.tsx | 7 +++++ pnpm-lock.yaml | 8 +++++ 5 files changed, 74 insertions(+) diff --git a/backend/package.json b/backend/package.json index 95a8dca..3240d2e 100644 --- a/backend/package.json +++ b/backend/package.json @@ -5,6 +5,7 @@ "scripts": { "dev": "tsx --watch ./src/main.ts", "start": "tsx ./src/main.ts", + "start:set-my": "tsx ./src/main.ts --set-my", "typecheck": "tsc --noEmit", "prisma:studio": "prisma studio --schema ./src/services/database/schema.prisma", "prisma:generate": "prisma generate --schema ./src/services/database/schema.prisma", @@ -20,6 +21,7 @@ "@telegum/grammy-messages": "^0.5.1", "@telegum/tgx": "^0.2.1", "axios": "^1.6.8", + "commander": "^12.0.0", "dotenv": "^16.4.5", "grammy": "^1.22.4", "jsdom": "^24.0.0", diff --git a/backend/src/main.ts b/backend/src/main.ts index 6b1d07e..62fd038 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -1,5 +1,7 @@ import process from 'node:process' +import { program } from 'commander' import { run } from '@grammyjs/runner' +import { Bot } from 'grammy' import { loadConfigFromEnv } from './config' import { createLogger } from './utils/logging' import { createBot } from './bot' @@ -7,8 +9,56 @@ import { Domain } from './domain' import { createDatabase } from './services/database' import { SportClient } from './services/sport' import { InnohassleClient } from './services/innohassle' +import translations from './translations' async function main() { + program + .option('--set-my', 'Only call bot\'s `setMy...` methods.', false) + + program.parse() + + const options = program.opts() + + if (options.setMy) { + await setMy() + } else { + runBot() + } +} + +async function setMy() { + const config = loadConfigFromEnv() + const logger = createLogger( + config.environment === 'development' + ? { level: 'debug', pretty: true } + : { level: 'info', pretty: false }, + ) + const bot = new Bot(config.bot.token) + + logger.info('setMyCommands(default)...') + await bot.api.setMyCommands( + Object.entries(translations.en['Bot.Commands']).map(([command, description]) => ({ command, description })), + { scope: { type: 'all_private_chats' } }, + ) + logger.info('setMyDescription(default)...') + await bot.api.setMyDescription(translations.en['Bot.About']) + logger.info('setMyShortDescription(default)...') + await bot.api.setMyShortDescription(translations.en['Bot.Bio']) + + for (const [language, translation] of Object.entries(translations).filter(([lang]) => lang !== 'en')) { + logger.info(`setMyCommands(${language})...`) + await bot.api.setMyCommands( + Object.entries(translation['Bot.Commands']).map(([command, description]) => ({ command, description })), + { scope: { type: 'all_private_chats' }, language_code: language }, + ) + logger.info(`setMyDescription(${language})...`) + await bot.api.setMyDescription(translation['Bot.About'], { language_code: language }) + logger.info(`setMyShortDescription(${language})...`) + await bot.api.setMyShortDescription(translation['Bot.Bio'], { language_code: language }) + } +} + +async function runBot() { const config = loadConfigFromEnv() const logger = createLogger( config.environment === 'development' diff --git a/backend/src/translations/_en.tsx b/backend/src/translations/_en.tsx index 4d6f057..adf3dd8 100644 --- a/backend/src/translations/_en.tsx +++ b/backend/src/translations/_en.tsx @@ -46,6 +46,13 @@ const INSPIRING_QUOTES = [ ] export default { + 'Bot.Commands': { + menu: 'send main menu', + help: 'about this bot', + }, + 'Bot.About': 'I help Innopolis University students to track their sports progress, check-in for training classes and export personal calendar.', + 'Bot.Bio': 'Easy sports management for Innopolis University students.\n\ngithub.com/one-zero-eight/sport-bot', + 'Messages.WelcomeUnauthorized': ( <> Welcome to IU Sport Bot! 💪 diff --git a/backend/src/translations/_ru.tsx b/backend/src/translations/_ru.tsx index e026cef..1c7e266 100644 --- a/backend/src/translations/_ru.tsx +++ b/backend/src/translations/_ru.tsx @@ -55,6 +55,13 @@ const INSPIRING_QUOTES = [ ] export default { + 'Bot.Commands': { + menu: 'главное меню', + help: 'о боте', + }, + 'Bot.About': 'Я помогаю студентам Иннополиса следить за прогрессом по спорту и записываться на занятия в пару кликов, а ещё показываю личный календарь со всеми занятиями.', + 'Bot.Bio': 'Помогаю закрывать спорт студентам Иннополиса.\n\ngithub.com/one-zero-eight/sport-bot', + 'Messages.WelcomeUnauthorized': ( <> Привет, я IU Sport бот! 💪 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2eb7f2f..c9249c3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -59,6 +59,9 @@ importers: axios: specifier: ^1.6.8 version: 1.6.8 + commander: + specifier: ^12.0.0 + version: 12.0.0 dotenv: specifier: ^16.4.5 version: 16.4.5 @@ -2222,6 +2225,11 @@ packages: engines: {node: '>=16'} dev: true + /commander@12.0.0: + resolution: {integrity: sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==} + engines: {node: '>=18'} + dev: false + /comment-parser@1.4.1: resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} engines: {node: '>= 12.0.0'} From 51cce1f58414df16d81ec2fc0bcfbdf01533359c Mon Sep 17 00:00:00 2001 From: evermake Date: Mon, 8 Apr 2024 20:17:47 +0300 Subject: [PATCH 2/6] add missing `await` --- backend/src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main.ts b/backend/src/main.ts index 62fd038..56a9b69 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -22,7 +22,7 @@ async function main() { if (options.setMy) { await setMy() } else { - runBot() + await runBot() } } From 02a4bcb04474d9b271a96410e3c2ff0cb1ba0385 Mon Sep 17 00:00:00 2001 From: evermake Date: Mon, 8 Apr 2024 20:44:51 +0300 Subject: [PATCH 3/6] update running options --- backend/src/main.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/backend/src/main.ts b/backend/src/main.ts index 56a9b69..55d268e 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -13,17 +13,23 @@ import translations from './translations' async function main() { program - .option('--set-my', 'Only call bot\'s `setMy...` methods.', false) + .option('--set-my', 'Call bot\'s `setMy...` methods before starting.', false) + .option('--set-my-only', 'Only call bot\'s `setMy...` methods without starting bot.', false) program.parse() const options = program.opts() + if (options.setMyOnly) { + await setMy() + return + } + if (options.setMy) { await setMy() - } else { - await runBot() } + + await runBot() } async function setMy() { From 2b2b4813e013171c066f5f39299fc584f5640206 Mon Sep 17 00:00:00 2001 From: evermake Date: Mon, 8 Apr 2024 20:52:39 +0300 Subject: [PATCH 4/6] refactor bot starting, add try catch for `setMy...` --- backend/src/main.ts | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/backend/src/main.ts b/backend/src/main.ts index 55d268e..21ee8c2 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -2,7 +2,9 @@ import process from 'node:process' import { program } from 'commander' import { run } from '@grammyjs/runner' import { Bot } from 'grammy' +import type { Config } from './config' import { loadConfigFromEnv } from './config' +import type { Logger } from './utils/logging' import { createLogger } from './utils/logging' import { createBot } from './bot' import { Domain } from './domain' @@ -14,31 +16,35 @@ import translations from './translations' async function main() { program .option('--set-my', 'Call bot\'s `setMy...` methods before starting.', false) - .option('--set-my-only', 'Only call bot\'s `setMy...` methods without starting bot.', false) + .option('--set-my-only', 'Only call bot\'s `setMy...` methods without starting the bot.', false) program.parse() const options = program.opts() + const config = loadConfigFromEnv() + const logger = createLogger( + config.environment === 'development' + ? { level: 'debug', pretty: true } + : { level: 'info', pretty: false }, + ) if (options.setMyOnly) { - await setMy() + await setMy(config, logger) return } if (options.setMy) { - await setMy() + try { + await setMy(config, logger) + } catch (err) { + console.warn('Error calling \'setMy...\' methods:', err) + } } - await runBot() + await runBot(config, logger) } -async function setMy() { - const config = loadConfigFromEnv() - const logger = createLogger( - config.environment === 'development' - ? { level: 'debug', pretty: true } - : { level: 'info', pretty: false }, - ) +async function setMy(config: Config, logger: Logger) { const bot = new Bot(config.bot.token) logger.info('setMyCommands(default)...') @@ -64,14 +70,7 @@ async function setMy() { } } -async function runBot() { - const config = loadConfigFromEnv() - const logger = createLogger( - config.environment === 'development' - ? { level: 'debug', pretty: true } - : { level: 'info', pretty: false }, - ) - +async function runBot(config: Config, logger: Logger) { const db = await createDatabase({ logger: logger.child({ tag: 'database' }), connectionUrl: config.postgresUrl, From 513b9c068def62d22bbb4c2441d6e60b8d61a0b0 Mon Sep 17 00:00:00 2001 From: evermake Date: Mon, 8 Apr 2024 20:56:24 +0300 Subject: [PATCH 5/6] run bot with `start:set-my` in Docker --- bot.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.Dockerfile b/bot.Dockerfile index 18f9ca5..61623f5 100644 --- a/bot.Dockerfile +++ b/bot.Dockerfile @@ -12,4 +12,4 @@ COPY ./backend ./backend RUN pnpm run -C backend prisma:generate -CMD ["pnpm", "run", "-C", "backend", "start"] +CMD ["pnpm", "run", "-C", "backend", "start:set-my"] From 6fd499ddfa1aad306265809eac3c8a3cc351bf00 Mon Sep 17 00:00:00 2001 From: evermake Date: Mon, 8 Apr 2024 20:57:40 +0300 Subject: [PATCH 6/6] update option description --- backend/src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main.ts b/backend/src/main.ts index 21ee8c2..1a25e51 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -15,7 +15,7 @@ import translations from './translations' async function main() { program - .option('--set-my', 'Call bot\'s `setMy...` methods before starting.', false) + .option('--set-my', 'Call bot\'s `setMy...` methods before starting the bot.', false) .option('--set-my-only', 'Only call bot\'s `setMy...` methods without starting the bot.', false) program.parse()