index.js
· 5.1 KiB · JavaScript
Originalformat
const { Bot, InlineKeyboard } = require("grammy");
const fs = require("fs");
const path = require("path");
const bot = new Bot("");
const DB_PATH = path.join(__dirname, "db.json");
function getDb() {
if (!fs.existsSync(DB_PATH)) {
return { chats: {} };
}
try {
const data = JSON.parse(fs.readFileSync(DB_PATH, "utf-8"));
if (!data.chats) data.chats = {};
return data;
} catch (e) {
return { chats: {} };
}
}
function saveDb(data) {
fs.writeFileSync(DB_PATH, JSON.stringify(data, null, 2));
}
function getChatUser(db, chatInstance, userId, firstName) {
if (!db.chats[chatInstance]) {
db.chats[chatInstance] = {};
}
if (!db.chats[chatInstance][userId]) {
db.chats[chatInstance][userId] = {
name: firstName,
size: 0,
last_grown: 0
};
}
if (firstName) db.chats[chatInstance][userId].name = firstName;
return db.chats[chatInstance][userId];
}
function getTopUsers(db, chatInstance) {
if (!db.chats[chatInstance]) return [];
return Object.values(db.chats[chatInstance])
.sort((a, b) => b.size - a.size)
.slice(0, 10);
}
bot.on("inline_query", async (ctx) => {
const user = ctx.from;
await ctx.answerInlineQuery([
{
type: "article",
id: "grow-pp",
title: "Вырастить писю 🍆",
description: "Испытать удачу (+1-30 см)",
input_message_content: {
message_text: `🍆 *${user.first_name}* готовится вырастить свою писю...`,
parse_mode: "Markdown"
},
reply_markup: new InlineKeyboard().text("🍆 Вырастить", "grow_action")
},
{
type: "article",
id: "top-pp",
title: "Топ писи 🏆",
description: "Показать лидеров чата",
input_message_content: {
message_text: "🏆 *Топ писюнов чата*",
parse_mode: "Markdown"
},
reply_markup: new InlineKeyboard().text("🔄 Загрузить топ", "top_action")
}
], { cache_time: 0 });
});
bot.callbackQuery("grow_action", async (ctx) => {
// console.log(ctx.update);
const chatInstance = ctx.update.callback_query.chat_instance;
const userId = ctx.from.id;
const firstName = ctx.from.first_name;
if (!chatInstance) {
return ctx.answerCallbackQuery({ text: "Error: No chat instance found." });
}
const db = getDb();
const user = getChatUser(db, chatInstance, userId, firstName);
const now = Date.now();
const cooldown = 24 * 60 * 60 * 1000;
if (user.last_grown && (now - user.last_grown < cooldown)) {
const remaining = cooldown - (now - user.last_grown);
const hours = Math.floor(remaining / (1000 * 60 * 60));
const minutes = Math.floor((remaining % (1000 * 60 * 60)) / (1000 * 60));
return ctx.answerCallbackQuery({
text: `⏳ Ты уже растил сегодня! Приходи через ${hours} ч ${minutes} мин.`,
show_alert: true
});
}
const growth = Math.floor(Math.random() * 30) + 1;
user.size += growth;
user.last_grown = now;
saveDb(db);
try {
await ctx.editMessageText(
`🍆 *${user.name}* вырастил писю!\n` +
`➕ Прирост: *${growth} см*\n` +
`📏 Общий размер: *${user.size} см*`,
{
parse_mode: "Markdown",
reply_markup: new InlineKeyboard().text("🍆 Вырастить ещё", "grow_action")
}
);
} catch (e) { }
await ctx.answerCallbackQuery({ text: `Выросла на ${growth} см!` });
});
bot.callbackQuery("top_action", async (ctx) => {
const chatInstance = ctx.update.callback_query.chat_instance;
if (!chatInstance) {
return ctx.answerCallbackQuery({ text: "Error: No chat instance found." });
}
const db = getDb();
const sortedUsers = getTopUsers(db, chatInstance);
let topText = "🏆 *Топ писи чата:*\n\n";
if (sortedUsers.length === 0) {
topText += "В этом чате еще никто не мерялся...";
} else {
sortedUsers.forEach((u, index) => {
let prefix = `${index + 1}.`;
if (index === 0) prefix = "🥇";
if (index === 1) prefix = "🥈";
if (index === 2) prefix = "🥉";
topText += `${prefix} ${u.name} — *${u.size} см*\n`;
});
}
try {
await ctx.editMessageText(
topText,
{
parse_mode: "Markdown",
reply_markup: new InlineKeyboard().text("🔄 Обновить", "top_action")
}
);
} catch (e) { }
await ctx.answerCallbackQuery();
});
bot.command("start", (ctx) => ctx.reply("Напиши @BotName в чате, чтобы играть!"));
bot.catch((err) => {
console.error("Bot Error:", err);
});
bot.start();
| 1 | const { Bot, InlineKeyboard } = require("grammy"); |
| 2 | const fs = require("fs"); |
| 3 | const path = require("path"); |
| 4 | |
| 5 | const bot = new Bot(""); |
| 6 | |
| 7 | const DB_PATH = path.join(__dirname, "db.json"); |
| 8 | |
| 9 | function getDb() { |
| 10 | if (!fs.existsSync(DB_PATH)) { |
| 11 | return { chats: {} }; |
| 12 | } |
| 13 | try { |
| 14 | const data = JSON.parse(fs.readFileSync(DB_PATH, "utf-8")); |
| 15 | if (!data.chats) data.chats = {}; |
| 16 | return data; |
| 17 | } catch (e) { |
| 18 | return { chats: {} }; |
| 19 | } |
| 20 | } |
| 21 | |
| 22 | function saveDb(data) { |
| 23 | fs.writeFileSync(DB_PATH, JSON.stringify(data, null, 2)); |
| 24 | } |
| 25 | |
| 26 | function getChatUser(db, chatInstance, userId, firstName) { |
| 27 | if (!db.chats[chatInstance]) { |
| 28 | db.chats[chatInstance] = {}; |
| 29 | } |
| 30 | if (!db.chats[chatInstance][userId]) { |
| 31 | db.chats[chatInstance][userId] = { |
| 32 | name: firstName, |
| 33 | size: 0, |
| 34 | last_grown: 0 |
| 35 | }; |
| 36 | } |
| 37 | |
| 38 | if (firstName) db.chats[chatInstance][userId].name = firstName; |
| 39 | |
| 40 | return db.chats[chatInstance][userId]; |
| 41 | } |
| 42 | |
| 43 | function getTopUsers(db, chatInstance) { |
| 44 | if (!db.chats[chatInstance]) return []; |
| 45 | return Object.values(db.chats[chatInstance]) |
| 46 | .sort((a, b) => b.size - a.size) |
| 47 | .slice(0, 10); |
| 48 | } |
| 49 | |
| 50 | |
| 51 | bot.on("inline_query", async (ctx) => { |
| 52 | const user = ctx.from; |
| 53 | |
| 54 | await ctx.answerInlineQuery([ |
| 55 | { |
| 56 | type: "article", |
| 57 | id: "grow-pp", |
| 58 | title: "Вырастить писю 🍆", |
| 59 | description: "Испытать удачу (+1-30 см)", |
| 60 | input_message_content: { |
| 61 | message_text: `🍆 *${user.first_name}* готовится вырастить свою писю...`, |
| 62 | parse_mode: "Markdown" |
| 63 | }, |
| 64 | reply_markup: new InlineKeyboard().text("🍆 Вырастить", "grow_action") |
| 65 | }, |
| 66 | { |
| 67 | type: "article", |
| 68 | id: "top-pp", |
| 69 | title: "Топ писи 🏆", |
| 70 | description: "Показать лидеров чата", |
| 71 | input_message_content: { |
| 72 | message_text: "🏆 *Топ писюнов чата*", |
| 73 | parse_mode: "Markdown" |
| 74 | }, |
| 75 | reply_markup: new InlineKeyboard().text("🔄 Загрузить топ", "top_action") |
| 76 | } |
| 77 | ], { cache_time: 0 }); |
| 78 | }); |
| 79 | |
| 80 | |
| 81 | bot.callbackQuery("grow_action", async (ctx) => { |
| 82 | // console.log(ctx.update); |
| 83 | const chatInstance = ctx.update.callback_query.chat_instance; |
| 84 | const userId = ctx.from.id; |
| 85 | const firstName = ctx.from.first_name; |
| 86 | |
| 87 | if (!chatInstance) { |
| 88 | return ctx.answerCallbackQuery({ text: "Error: No chat instance found." }); |
| 89 | } |
| 90 | |
| 91 | const db = getDb(); |
| 92 | const user = getChatUser(db, chatInstance, userId, firstName); |
| 93 | |
| 94 | |
| 95 | const now = Date.now(); |
| 96 | const cooldown = 24 * 60 * 60 * 1000; |
| 97 | |
| 98 | if (user.last_grown && (now - user.last_grown < cooldown)) { |
| 99 | const remaining = cooldown - (now - user.last_grown); |
| 100 | const hours = Math.floor(remaining / (1000 * 60 * 60)); |
| 101 | const minutes = Math.floor((remaining % (1000 * 60 * 60)) / (1000 * 60)); |
| 102 | |
| 103 | return ctx.answerCallbackQuery({ |
| 104 | text: `⏳ Ты уже растил сегодня! Приходи через ${hours} ч ${minutes} мин.`, |
| 105 | show_alert: true |
| 106 | }); |
| 107 | } |
| 108 | |
| 109 | |
| 110 | const growth = Math.floor(Math.random() * 30) + 1; |
| 111 | user.size += growth; |
| 112 | user.last_grown = now; |
| 113 | |
| 114 | saveDb(db); |
| 115 | |
| 116 | try { |
| 117 | await ctx.editMessageText( |
| 118 | `🍆 *${user.name}* вырастил писю!\n` + |
| 119 | `➕ Прирост: *${growth} см*\n` + |
| 120 | `📏 Общий размер: *${user.size} см*`, |
| 121 | { |
| 122 | parse_mode: "Markdown", |
| 123 | reply_markup: new InlineKeyboard().text("🍆 Вырастить ещё", "grow_action") |
| 124 | } |
| 125 | ); |
| 126 | } catch (e) { } |
| 127 | |
| 128 | await ctx.answerCallbackQuery({ text: `Выросла на ${growth} см!` }); |
| 129 | }); |
| 130 | |
| 131 | bot.callbackQuery("top_action", async (ctx) => { |
| 132 | const chatInstance = ctx.update.callback_query.chat_instance; |
| 133 | |
| 134 | if (!chatInstance) { |
| 135 | return ctx.answerCallbackQuery({ text: "Error: No chat instance found." }); |
| 136 | } |
| 137 | |
| 138 | const db = getDb(); |
| 139 | const sortedUsers = getTopUsers(db, chatInstance); |
| 140 | |
| 141 | let topText = "🏆 *Топ писи чата:*\n\n"; |
| 142 | if (sortedUsers.length === 0) { |
| 143 | topText += "В этом чате еще никто не мерялся..."; |
| 144 | } else { |
| 145 | sortedUsers.forEach((u, index) => { |
| 146 | let prefix = `${index + 1}.`; |
| 147 | if (index === 0) prefix = "🥇"; |
| 148 | if (index === 1) prefix = "🥈"; |
| 149 | if (index === 2) prefix = "🥉"; |
| 150 | |
| 151 | topText += `${prefix} ${u.name} — *${u.size} см*\n`; |
| 152 | }); |
| 153 | } |
| 154 | |
| 155 | try { |
| 156 | await ctx.editMessageText( |
| 157 | topText, |
| 158 | { |
| 159 | parse_mode: "Markdown", |
| 160 | reply_markup: new InlineKeyboard().text("🔄 Обновить", "top_action") |
| 161 | } |
| 162 | ); |
| 163 | } catch (e) { } |
| 164 | |
| 165 | await ctx.answerCallbackQuery(); |
| 166 | }); |
| 167 | |
| 168 | bot.command("start", (ctx) => ctx.reply("Напиши @BotName в чате, чтобы играть!")); |
| 169 | |
| 170 | bot.catch((err) => { |
| 171 | console.error("Bot Error:", err); |
| 172 | }); |
| 173 | |
| 174 | bot.start(); |