команда регистрации красиво работает

This commit is contained in:
bogdan zažigin 2022-12-14 00:48:24 +03:00
parent 15b40dfc3b
commit 60e5a7e163
12 changed files with 226 additions and 64 deletions

View file

@ -1,5 +1,5 @@
# Бот в Telegram для управления Личным кабинетом в ИТ-студии Зажигина # Бот в Telegram для управления Личным кабинетом в ИТ-студии Зажигина
Бот описан в [`src/bot.ts`](../src/index.ts) на [TypeScript](https://www.typescriptlang.org/docs "Документация TypeScript") с помощью фреймворка [Grammy](https://grammy.dev/guide "Документация Grammy") над [Telegram Bot API](https://core.telegram.org/bots/api "Документация Telegram Bot API"). Предназначен для запуска в контейнере [Docker](https://docs.docker.com/reference "Документация Docker") через [NodeJS](https://nodejs.org/api/ "Документация NodeJS"), файл сборки можно видеть под названием [`src/dockerfile`](../src/dockerfile). Главный метод запуска проекта — через файл [Bash](https://www.gnu.org/software/bash/manual/bash.html "Документация Bash") скрипта [`start.sh`](../start.sh) от имени администратора. Бот описан в [`src/bot/bot.ts`](../src/index.ts) на [TypeScript](https://www.typescriptlang.org/docs "Документация TypeScript") с помощью фреймворка [Grammy](https://grammy.dev/guide "Документация Grammy") над [Telegram Bot API](https://core.telegram.org/bots/api "Документация Telegram Bot API"). Предназначен для запуска в контейнере [Docker](https://docs.docker.com/reference "Документация Docker") через [NodeJS](https://nodejs.org/api/ "Документация NodeJS"), файл сборки можно видеть под названием [`src/dockerfile`](../src/dockerfile). Главный метод запуска проекта — через файл [Bash](https://www.gnu.org/software/bash/manual/bash.html "Документация Bash") скрипта [`start.sh`](../start.sh) от имени администратора.
Официально запускается от имени [@emp_zaboal_bot](https://emp_zaboal_bot.t.me) и администрируется [Богданом](https://zaboal.t.me). Руководство по запуску описано в [`docs/start.md`](start.md). Официально запускается от имени [@emp_zaboal_bot](https://emp_zaboal_bot.t.me) и администрируется [Богданом](https://zaboal.t.me). Руководство по запуску описано в [`docs/start.md`](start.md).

24
docs/settings.md Normal file
View file

@ -0,0 +1,24 @@
## Настройки бота
Настройки бота расположены в директории [`src/bot/settings`](../src/bot/bot.ts) для Telegram Bot API и в файле переменных окружения [`env`](../env) для команды `source`. Файл переменных окружения имеет жизненно необходимые значения, их обязательно требуется указать.
### [`env`](../env) — переменные окружения
Для запуска бота требуется три константы в формате Bash:
* `BOT_TOKEN` — токен бота, получаемый от [BotFather](https://t.me/BotFather);
* `BOT_DB_PATH` — путь к базе данных SQLite бота на хосте, с данными об идентификаторах пользователя Телеграм людей зарегистрированных в организации (схема базы данных описана [здесь](/home/zaboal/work/templates/database-schemas/sql/organizational_structure/organizational_structure.sql));
* `ORG_BD_PATH` — путь к базе данных SQLite орагнизации, с данными об подразделениях, рабочих и т.д. (схема базы данных описана [здесь](/home/zaboal/work/templates/database-schemas/sql/organizational_structure/organizational_structure.sql)).
Данные будут переданы в контейнер Docker в процессе Bash скрипта запуска проекта [`start.sh`](../start.sh). По путям к базам данных на хосте в контейнер будут примонтированы соответствующие файлы SQLite под программными названиями.
### [`src/bot/settings`](../src/bot/bot.ts) — переменные для Telegram Bot API
При запуске бот передаст Telegram Bot API файлы конфигурации в формате json из директории [`settings`](../src/bot/settings/):
* [`commands.json`](../src/bot/settings/commands.json) — список команд и их описаний бота;
* [`default_administrator_rights.json`](../src/bot/settings/default_administrator_rights.json) — предлагаемый набор прав администратора бота при добавлении в группу.
Эти настройки формируются согласно изменениям кода самого бота. Изменять их рекомендуются только разработчикам, внёсшим изменения.

View file

@ -1,6 +1,6 @@
## Запуск бота ## Запуск бота
Для запуска требуются 2 переменных окружения: `BOT_TOKEN`, токен бота Telegram получаемый от [BotFather](https://t.me/BotFather), и `DB_PATH`, путь к базе данных SQLite на хосте. Указывать их нужно в файле [env](../env) сковывая в двойные кавычки. С помощью команды `source` в [`start.sh`](../start.sh) на основе этих переменных в создаваемый контейнер от образа [`dockerfile`](../src/dockerfile) будет примонтирован файл базы данных и передан токен. Перед запуском требуется заполнить переменные окружения в [`env`](../env), руководство — [`settings.md`](./settings.md#env--переменные-окружения). С помощью команды `source` в [`start.sh`](../start.sh) на основе этих переменных в создаваемый контейнер от образа [`dockerfile`](../src/dockerfile) будет примонтированы файлы баз данных и передан токен.
Если все переменные указаны верно, можно запускать файл [`start.sh`](../start.sh) от имени администратора: Если все переменные указаны верно, можно запускать файл [`start.sh`](../start.sh) от имени администратора:
```bash ```bash

14
env
View file

@ -1,5 +1,11 @@
# Токен Telegram Bot API получаемый от BotFather (https://t.me/BotFather) # Файл переменных окружения проекта
BOT_TOKEN="5715517585:AAFgAdmzsDokDcCEfy6hO_cI7nrsVeMTx8M" # Настройка проекта подробно описана в docs/settings.md.
# Путь к базе данных управляемой SQLite на хосте # Токен Telegram Bot API получаемый от BotFather
DB_PATH="/home/zaboal/work/organizations/zazhigin-s_it-studio/databases/local_organizational-structure.db" BOT_TOKEN=""
# Путь к базе данных SQLite бота на хосте
BOT_DB_PATH=""
# Путь к базе данных SQLite организации на хосте
ORG_DB_PATH=""

View file

@ -1,39 +0,0 @@
import { Bot } from "grammy";
const bot = new Bot(`${process.env.BOT_TOKEN}`);
import { Database } from "sqlite3";
const database = new Database(`${process.env.DB_PATH}`)
bot.command("start", (ctx) => {
ctx.reply(
"Вы можете ознакомиться с тем как использовать данного бота по команде `/help`",
{ parse_mode: "MarkdownV2" }
);
});
bot.command("help", (ctx) => {
ctx.reply(
"Список команд доступен в сплывающем меню от знака «/» в поле ввода сообщения\\. Но если Вы ещё не зарегистрированы в системе, сделайте это в первую очередь в формате SQL по команде: `/register \"[полное имя]\", \"[электропочта]\"`",
{ parse_mode: "MarkdownV2" },
);
});
bot.command("register", (ctx) => {
// В ctx.match берутся аргументы команды /register и используются как данные вводимые в таблицу
database.run(`INSERT INTO people(per_name, per_email) VALUES (${ctx.match})`, (error) => {
if (error == null) {
ctx.reply(`Регистрация прошла успешно`)
} else {
// Отправить «сухую» ошибку пользователю
ctx.reply(
`Регистрация не удалась, SQLite сообщает об ошибке: «\`${error}\`»\\. Вы можете запросить трактовку и рекомендации у @zaboal`,
{ parse_mode: "MarkdownV2" }
);
}
});
});
bot.start();

137
src/bot/bot.ts Normal file
View file

@ -0,0 +1,137 @@
import { Bot } from "grammy";
const bot = new Bot(`${process.env.BOT_TOKEN}`);
import { Database } from "sqlite3";
const database = new Database(`${process.env.BOT_DB_PATH}`);
// Применение настроек из директории «settings»
import commands from "./settings/commands.json";
bot.api.setMyCommands(commands, {
scope: { type: "all_private_chats" },
language_code: "ru"
});
import rights from "./settings/default_administrator_rights.json";
bot.api.setMyDefaultAdministratorRights({rights,
for_channels: false
});
// Подключение базы данных организации
database.run(`ATTACH DATABASE "/usr/src/app/${process.env.ORG_DB_PATH}" AS org`);
// Обработка команд бота
bot.command("start", ctx => { // Команда начала диалога, подсказывает первые шаги
ctx.reply(
"Вы можете ознакомиться с тем как использовать данного бота по команде `/help`",
{ parse_mode: "MarkdownV2" }
);
});
bot.command("help", ctx => { // Команда инструктирования
ctx.reply(
"Список команд доступен в сплывающем меню от знака «/» в поле ввода сообщения"
+ "\\. Но если Вы ещё не зарегистрированы в системе, сделайте это в первую очередь в формате SQL по команде: "
+ "`/register [полное имя], [электропочта]`",
{ parse_mode: "MarkdownV2" },
);
});
bot.command("register", ctx => { // Команда регистрации в организации
// В ctx.match берутся аргументы команды /register и используются как данные вводимые в таблицу
const command_arguments = ctx.match.split(", ")
const name: string = command_arguments[0];
const email: string = command_arguments[1];
// Заносятся соответствующие данные в БД организации, полученный идентификатор запоминает бот
database.get(`SELECT user_per_rowid FROM users WHERE user_id = "${ctx.msg.chat.id}"`, (error, result) => {
if (result == undefined) {
if (ctx.match == "") {
ctx.reply(
"Данная команда требует аргументы, через запятую: `[полное имя]` и `[электро@поч.та]`",
{ parse_mode: "MarkdownV2" }
);
} else {
database.run(`INSERT INTO people(per_name, per_email) VALUES ("${name}", "${email}")`, (error) => {
if (error == null) {
ctx.reply(`Регистрация прошла успешно`);
database.get(`SELECT rowid FROM people where per_email = "${email}"`, (error, select) => {
if (error == null){
database.run(`INSERT INTO users VALUES ("${select.rowid}", "${ctx.msg.chat.id}")`);
} else {
ctx.reply(
`Регистрация не удалась, SQLite сообщает об ошибке: «\`${error}\`»`
+ "\\. [Богдан](tg://user?id=987595197) может Вам её разъяснить и помочь с решением",
{ parse_mode: "MarkdownV2" }
);
}
});
} else {
ctx.reply(
`Регистрация не удалась, SQLite сообщает об ошибке: «\`${error}\`»`
+ "\\. [Богдан](tg://user?id=987595197) может Вам её разъяснить и помочь с решением",
{ parse_mode: "MarkdownV2" }
);
}
});
}
} else {
ctx.reply(
"Вы уже зарегистрированы",
{ parse_mode: "MarkdownV2" }
);
}
});
});
bot.command("sqlite", ctx => { // Команда исследования баз данных (для разработчиков)
database.get(`${ctx.match}`, (err, row) => {
if (err == null) {
ctx.reply(
"`" + ((row == undefined) ? "Ничего не найдено" : JSON.stringify(row)) + "`",
{ parse_mode: "MarkdownV2" }
);
} else {
ctx.reply(
"`" + JSON.stringify(err) + "`",
{ parse_mode: "MarkdownV2" }
);
}
});
})
// Запуск бота
bot.start({
limit: 1,
timeout: 1,
allowed_updates: ["message"],
drop_pending_updates: true,
onStart: bot => {
console.log(
`Бот запущен как «${bot.first_name}»`
+ ` под именем пользователя @${bot.username}`
+ ` с идентификатором ${bot.id}.`,
(bot.can_join_groups == true) ? "Он может присоединяться к группам," : "Он не может присоединяться к группам,",
(bot.can_read_all_group_messages == true) ? "читает сообщения в которых уже есть;" : "не читает сообщения в них;",
(bot.supports_inline_queries == true) ? "поддерживает инлайн-режим." : "не поддерживает инлайн-режим."
+ "\n"
);
}
});
process.on("exit", code => {
console.log("Запущен протокол выхода…");
bot.stop();
});
process.on("SIGINT", () => {
console.log("\n\nПолучен сигнал POSIX — «SIGINT».");
process.exit(0);
});

View file

@ -0,0 +1,10 @@
[
{
"command": "register",
"description": "регистрация в организации"
},
{
"command": "employ",
"description": "собеседование по вакансии"
}
]

View file

@ -0,0 +1,14 @@
{
"is_anonymous": false,
"can_manage_chat": false,
"can_delete_messages": false,
"can_manage_video_chats": false,
"can_restrict_members": false,
"can_promote_members": false,
"can_change_info": false,
"can_invite_users": false,
"can_post_messages": false,
"can_edit_messages": false,
"can_pin_messages": false,
"can_manage_topics": false
}

View file

@ -1,19 +1,26 @@
# Файл сборки Docker контейнера проекта
# Установка образа и рабочей директории
FROM node:lts-buster-slim FROM node:lts-buster-slim
WORKDIR /usr/src/app WORKDIR /usr/src/app
# Установка зависимостей
COPY package.json . COPY package.json .
RUN npm install RUN npm install
COPY bot-telegram_zaboal-employment.ts . # Добавление оставшихся файлов проекта
COPY tsconfig.json .
ADD bot bot
# Требуемые переменные окружения # Объявление переменных окружения
# Токен бота Telegram от бота @BotFather
ARG BOT_TOKEN ARG BOT_TOKEN
# Путь к базе данных внутри контейнера, монтируется из файловой системы хоста
ENV DB_PATH="./dbase.db" # Имена подключаемых баз данных внутри контейнера
ENV BOT_DB_PATH="bot_db.sqlite"
ENV ORG_DB_PATH="org_db.sqlite"
# Запуск контейнера
CMD npm run start CMD npm run start

View file

@ -1,10 +1,10 @@
{ {
"name": "bot-telegram_zaboal-employment", "name": "bot-telegram_zaboal-account",
"version": "alpha", "version": "alpha",
"description": "Бот в Telegram для трудоустройства в ИТ-студию Зажигина.", "description": "Бот в Telegram для управления личным кабинетом в Информационно-технологической стартап-студии имени Богдана Зажигина.",
"main": "bot-telegram_zaboal-employment.ts", "main": "bot/bot.ts",
"scripts": { "scripts": {
"start": "ts-node bot-telegram_zaboal-employment.ts" "start": "ts-node bot/bot.ts"
}, },
"author": "Зажигин Богдан Алексеевич <za.boal@vk.com>", "author": "Зажигин Богдан Алексеевич <za.boal@vk.com>",
"dependencies": { "dependencies": {
@ -13,7 +13,6 @@
}, },
"devDependencies": { "devDependencies": {
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"ts-node-dev": "^2.0.0",
"typescript": "^4.7.4" "typescript": "^4.7.4"
} }
} }

View file

@ -5,7 +5,6 @@
"ES2021" "ES2021"
], ],
"module": "commonjs", "module": "commonjs",
"rootDir": "./",
"esModuleInterop": true, "esModuleInterop": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"strict": true, "strict": true,

View file

@ -1,17 +1,22 @@
# Скрипт запуска проекта
# Процедура запуска проекта подробно описана в docs/start.md.
# Получение необходимых переменных окружения и вывод их в консоль # Получение необходимых переменных окружения и вывод их в консоль
source ./env; source ./env;
echo -e \ echo -e \
"Полученные переменные окружения:\n" \ "Полученные переменные окружения:\n" \
"\t\033[1mтокен Telegram Bot API\033[0m — \033[4m$BOT_TOKEN\033[0m,\n" \ "\tтокен Telegram Bot API — $BOT_TOKEN,\n" \
"\t\033[1mпуть к базе данных SQLite на хосте\033[0m — \033[4m$DB_PATH\033[0m.\n\n"; "\tпуть к базе данных бота — $BOT_DB_PATH,\n" \
"\tпуть к базе данных организации — $ORG_DB_PATH.\n\n";
# Сборка и запуск контейнера Docker # Сборка и запуск контейнера Docker
docker build src \ docker build src \
--tag bot-telegram_zaboal-employment:latest; --tag bot-telegram_zaboal-employment:latest;
docker run \ docker run -it \
--env BOT_TOKEN=$BOT_TOKEN \ --env BOT_TOKEN=$BOT_TOKEN \
--volume $DB_PATH:/usr/src/app/dbase.db \ --volume $BOT_DB_PATH:/usr/src/app/bot_db.sqlite \
--volume $ORG_DB_PATH:/usr/src/app/org_db.sqlite \
bot-telegram_zaboal-employment:latest; bot-telegram_zaboal-employment:latest;