команда регистрации красиво работает
This commit is contained in:
parent
15b40dfc3b
commit
60e5a7e163
12 changed files with 226 additions and 64 deletions
|
@ -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
24
docs/settings.md
Normal 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) — предлагаемый набор прав администратора бота при добавлении в группу.
|
||||||
|
|
||||||
|
Эти настройки формируются согласно изменениям кода самого бота. Изменять их рекомендуются только разработчикам, внёсшим изменения.
|
|
@ -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
14
env
|
@ -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=""
|
|
@ -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
137
src/bot/bot.ts
Normal 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);
|
||||||
|
});
|
10
src/bot/settings/commands.json
Normal file
10
src/bot/settings/commands.json
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"command": "register",
|
||||||
|
"description": "регистрация в организации"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "employ",
|
||||||
|
"description": "собеседование по вакансии"
|
||||||
|
}
|
||||||
|
]
|
14
src/bot/settings/default_administrator_rights.json
Normal file
14
src/bot/settings/default_administrator_rights.json
Normal 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
|
||||||
|
}
|
|
@ -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
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,6 @@
|
||||||
"ES2021"
|
"ES2021"
|
||||||
],
|
],
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"rootDir": "./",
|
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
|
17
start.sh
17
start.sh
|
@ -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;
|
Loading…
Add table
Reference in a new issue