initial
This commit is contained in:
commit
dc03da0a3e
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.idea
|
||||
node_modules
|
66
Database.js
Normal file
66
Database.js
Normal 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
99
index.js
Normal 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
20
package.json
Normal 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
55
scenes/start.js
Normal 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;
|
Reference in New Issue
Block a user