This commit is contained in:
Ilya 2022-12-16 00:42:34 +03:00
commit dc03da0a3e
6 changed files with 243 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.idea
node_modules

1
.npmrc Normal file
View File

@ -0,0 +1 @@
registry=https://repo.redguy.ru/repository/npm-public/

66
Database.js Normal file
View File

@ -0,0 +1,66 @@
const pg = require('pg');
class Database {
static instance;
constructor(connectionStr) {
this.pool = new pg.Pool({connectionString: connectionStr});
Database.instance = this;
}
async prepareUser(id) {
let client = await this.pool.connect();
let user = null;
try {
await client.query('BEGIN');
let res = await client.query('SELECT * FROM santa_users WHERE id = $1', [id]);
if (res.rowCount === 0) {
await client.query('INSERT INTO santa_users (id) VALUES ($1)', [id]);
res = await client.query('SELECT * FROM santa_users WHERE id = $1', [id]);
}
await client.query('COMMIT');
user = res.rows[0];
} finally {
client.release();
}
return user;
}
async setGameState(id, state) {
let client = await this.pool.connect();
try {
await client.query('BEGIN');
await client.query('UPDATE santa_users SET ingame = $1 WHERE id = $2', [state, id]);
await client.query('COMMIT');
} finally {
client.release();
}
}
async enterGame(id, first_name, last_name, group, problems) {
let client = await this.pool.connect();
try {
await client.query('BEGIN');
await client.query('UPDATE santa_users SET first_name = $1, last_name = $2, group_name = $3, problems = $4, ingame = true WHERE id = $5', [first_name, last_name, group, problems, id]);
await client.query('COMMIT');
} finally {
client.release();
}
}
async getUsersCount() {
let client = await this.pool.connect();
let count = null;
try {
await client.query('BEGIN');
let res = await client.query('SELECT COUNT(*) as count FROM santa_users WHERE ingame = true');
await client.query('COMMIT');
count = res.rows[0].count;
} finally {
client.release();
}
return count;
}
}
module.exports = Database;

99
index.js Normal file
View File

@ -0,0 +1,99 @@
const Telegraf = require('telegraf');
const session = require('telegraf/session');
const Database = require('./Database');
const axios = require("axios");
const Stage = require("telegraf/stage");
let bot = new Telegraf.Telegraf(process.env.TOKEN);
bot.use(session());
let database = new Database(process.env.DATABASE_URL);
bot.use(async (ctx, next) => {
let start = new Date();
ctx.userdata = await database.prepareUser(ctx.from.id);
await next();
let ms = new Date() - start;
try {
if (ctx.message && ctx.message.text.startsWith("/")) {
let res = await axios.put("https://api.redguy.ru/v1/logs/", {
service: 3,
content: "Command " + ctx.message.text.split(" ")[0].substring(1) + " processed in " + ms + "ms",
level: "info",
category: "Santa"
}, {
headers: {
authorization: "Bearer " + process.env.LOGS_TOKEN
}
});
console.log(res.data)
}
if (ctx.callbackQuery && ctx.callbackQuery.data) {
await axios.put("https://api.redguy.ru/v1/logs/", {
service: 3,
content: "Callback " + ctx.callbackQuery.data + " processed in " + ms + "ms",
level: "info",
category: "Santa"
}, {
headers: {
authorization: "Bearer " + process.env.LOGS_TOKEN
}
});
}
} catch (e) {
console.log(e)
}
});
let stage = new Stage();
stage.register(require("./scenes/start"));
bot.use(stage.middleware());
bot.start(async (ctx) => {
let keyboard = [];
if(ctx.userdata.ingame) {
keyboard.push([{
text: "Выйти из игры",
callback_data: "exit"
}]);
} else {
keyboard.push([{
text: "Войти в игру",
callback_data: "start"
}]);
}
await ctx.reply(`Добро пожаловать в тайного санту студенческого совета ОП5!\n\nТвой статус: ${ctx.userdata.ingame? "В игре" : "Не в игре"}`, Telegraf.Extra.markup((m) => m.inlineKeyboard(keyboard)));
});
bot.action("menu", async (ctx) => {
let keyboard = [];
if(ctx.userdata.ingame) {
keyboard.push([{
text: "Выйти из игры",
callback_data: "exit"
}]);
} else {
keyboard.push([{
text: "Войти в игру",
callback_data: "start"
}]);
}
await ctx.editMessageText(`Добро пожаловать в тайного санту студенческого совета ОП5!\n\nТвой статус: ${ctx.userdata.ingame? "В игре" : "Не в игре"}`, Telegraf.Extra.markup((m) => m.inlineKeyboard(keyboard)));
});
bot.action("start", async (ctx) => {
await ctx.scene.enter("start");
});
bot.action("exit", async (ctx) => {
await database.setGameState(ctx.from.id, false);
await ctx.answerCbQuery("Вы вышли из игры");
await ctx.editMessageText(`Добро пожаловать в тайного санту студенческого совета ОП5!\n\nТвой статус: Не в игре`, Telegraf.Extra.markup((m) => m.inlineKeyboard([{text: "Войти в игру", callback_data: "start"}])));
});
bot.command("stats", async (ctx) => {
await ctx.reply("Всего игроков: " + (await database.getUsersCount()));
});
bot.catch((err, ctx) => console.log(err, ctx)) // Print error and error context to console, no crash
bot.startPolling();

20
package.json Normal file
View File

@ -0,0 +1,20 @@
{
"name": "ks54santa",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^1.2.1",
"pg": "^8.8.0",
"telegraf": "3.39"
},
"devDependencies": {
"@types/pg": "^8.6.5"
}
}

55
scenes/start.js Normal file
View File

@ -0,0 +1,55 @@
const Scene = require('telegraf').BaseScene;
const Telegraf = require('telegraf');
const Database = require('../Database');
let scene = new Scene('start');
scene.enter(async (ctx) => {
ctx.session.state = "first_name";
ctx.session.message_id = ctx.callbackQuery.message.message_id;
ctx.session.chat_id = ctx.callbackQuery.message.chat.id;
await ctx.editMessageText("Введи своё имя",
Telegraf.Extra.markup((m) => m.inlineKeyboard([{text: "Отмена", callback_data: "leave"}])));
await ctx.answerCbQuery();
});
scene.on('text', async (ctx) => {
switch (ctx.session.state) {
case "first_name": {
ctx.session.first_name = ctx.message.text;
ctx.session.state = "last_name";
await ctx.telegram.editMessageText(ctx.session.chat_id,ctx.session.message_id, null,"Введи свою фамилию",
Telegraf.Extra.markup((m) => m.inlineKeyboard([{text: "Отмена", callback_data: "leave"}])));
break;
}
case "last_name": {
ctx.session.last_name = ctx.message.text;
ctx.session.state = "group";
await ctx.telegram.editMessageText(ctx.session.chat_id,ctx.session.message_id,null,"Введи свою группу",
Telegraf.Extra.markup((m) => m.inlineKeyboard([{text: "Отмена", callback_data: "leave"}])));
break;
}
case "group": {
ctx.session.group = ctx.message.text;
ctx.session.state = "problems";
await ctx.telegram.editMessageText(ctx.session.chat_id,ctx.session.message_id,null,"Введи то что тебе нельзя дарить (алергии, запреты родителей и т.д.)",
Telegraf.Extra.markup((m) => m.inlineKeyboard([{text: "Отмена", callback_data: "leave"}])));
break;
}
case "problems": {
ctx.session.problems = ctx.message.text;
Database.instance.enterGame(ctx.from.id, ctx.session.first_name, ctx.session.last_name, ctx.session.group, ctx.session.problems);
await ctx.telegram.editMessageText(ctx.session.chat_id,ctx.session.message_id,null,"Готово!",
Telegraf.Extra.markup((m) => m.inlineKeyboard([{text: "Меню", callback_data: "menu"}])));
await ctx.scene.leave();
}
}
await ctx.deleteMessage();
});
scene.action('leave', async (ctx) => {
await ctx.telegram.editMessageText(ctx.session.chat_id,ctx.session.message_id,null,"Отменено",
Telegraf.Extra.markup((m) => m.inlineKeyboard([{text: "Меню", callback_data: "menu"}])));
await ctx.scene.leave();
});
module.exports = scene;