добавил кнопки в тг бота

This commit is contained in:
2026-07-23 16:40:18 +05:00
parent 1f96fa0c12
commit 5de29561f2
5 changed files with 145 additions and 54 deletions
+23 -4
View File
@@ -86,7 +86,9 @@ export async function initBot() {
`• Используй команду /stats для быстрой сводки расходов.\n` +
`• Или открой полноценный Dashboard с графиками по кнопке ниже! 👇`,
Markup.keyboard([
[Markup.button.webApp('📊 Открыть Dashboard', webAppLink)]
['➕ Доход', '➖ Расход'],
['📊 Статистика', '🛒 Покупки'],
['📅 Подписки', Markup.button.webApp('📊 Открыть Dashboard', webAppLink)]
]).resize()
);
});
@@ -111,8 +113,7 @@ export async function initBot() {
);
});
// /stats command - Show summary of expenses for current month
bot.command('stats', async (ctx) => {
const statsHandler = async (ctx) => {
const db = getDb();
const currentMonth = new Date().toISOString().slice(0, 7); // YYYY-MM
@@ -159,7 +160,11 @@ export async function initBot() {
await ctx.replyWithMarkdownV2(
message.replace(/\./g, '\\.').replace(/-/g, '\\-').replace(/\+/g, '\\+')
);
});
};
// /stats command - Show summary of expenses for current month
bot.command('stats', statsHandler);
bot.hears('📊 Статистика', statsHandler);
// /buy command - Adds item to shopping list
bot.command('buy', async (ctx) => {
@@ -229,6 +234,20 @@ export async function initBot() {
const db = getDb();
const today = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
// Handle interactive button text replies
if (text === '➕ Доход') {
return ctx.reply('Введите сумму и описание дохода, начиная с "+", например:\n\n`+ 15000 Зарплата`', { parse_mode: 'Markdown' });
}
if (text === '➖ Расход') {
return ctx.reply('Введите сумму и описание расхода, например:\n\n`450 Кофе и круассан`', { parse_mode: 'Markdown' });
}
if (text === '🛒 Покупки') {
return ctx.reply('Чтобы добавить покупку, используй команду /buy, например:\n\n`/buy Молоко 90`', { parse_mode: 'Markdown' });
}
if (text === '📅 Подписки') {
return ctx.reply('Чтобы добавить подписку, используй команду /sub, например:\n\n`/sub Netflix 800`', { parse_mode: 'Markdown' });
}
// 1. Check for Income (starts with '+' or '+ ')
const incomeMatch = text.match(/^\+\s*(\d+(?:\.\d+)?)\s+(.+)$/);
if (incomeMatch) {
+49
View File
@@ -0,0 +1,49 @@
import { TelegramBot } from 'node-telegram-bot-api';
const token = '8434157336:AAHH9YoOvcJuG_PQR2h5RDKmri_nN9MezFc';
const bot = new TelegramBot(token, { polling: true });
bot.on('message', (msg) => {
try {
if (msg.text === '/start') {
const keyboard = [
[
{ text: 'Add Expense', callback_data: 'add_expense' }
]
];
const replyMarkup = { reply_markup: { inline_keyboard: keyboard } };
bot.sendMessage(msg.chat.id, 'Welcome to the finance bot!', replyMarkup);
}
} catch (error) {
console.error(error);
bot.sendMessage(msg.chat.id, 'An error occurred. Please try again later.');
}
});
bot.on('callback_query', (callbackQuery) => {
try {
const chatId = callbackQuery.message.chat.id;
const messageId = callbackQuery.message.message_id;
const data = callbackQuery.data;
if (data === 'add_expense') {
try {
bot.sendMessage(chatId, 'Please enter the expense amount and description:');
} catch (error) {
console.error(error);
bot.sendMessage(chatId, 'An error occurred. Please try again later.');
}
}
} catch (error) {
console.error(error);
bot.sendMessage(callbackQuery.message.chat.id, 'An error occurred. Please try again later.');
}
});
bot.on('error', (error) => {
console.error(error);
});
bot.on('polling_error', (error) => {
console.error(error);
});
+47 -50
View File
@@ -1,50 +1,47 @@
// Telegram WebApp SDK Wrapper
export const tg = window.Telegram?.WebApp || null;
export function initTelegram() {
if (tg) {
tg.ready();
tg.expand();
console.log('Telegram WebApp SDK initialized');
} else {
console.warn('Telegram WebApp SDK not found. Running in browser mode.');
}
}
export function getTelegramUser() {
return tg?.initDataUnsafe?.user || null;
}
export function getAuthHeaders() {
const headers = {};
if (tg && tg.initData) {
headers['X-Telegram-Init-Data'] = tg.initData;
}
// Also check if we have a token stored in localStorage (for desktop browser access)
const token = localStorage.getItem('finance_auth_token');
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
return headers;
}
export function saveTokenFromUrl() {
const params = new URLSearchParams(window.location.search);
const token = params.get('token');
if (token) {
localStorage.setItem('finance_auth_token', token);
// Clean up url
window.history.replaceState({}, document.title, window.location.pathname);
return token;
}
return localStorage.getItem('finance_auth_token');
}
export function logout() {
localStorage.removeItem('finance_auth_token');
window.location.reload();
}
{
"// Telegram WebApp SDK Wrapper": "",
"export const tg = window.Telegram?.WebApp || null;": "",
"export function initTelegram() {": "",
" if (tg) {": "",
" tg.ready();": "",
" tg.expand();": "",
" console.log('Telegram WebApp SDK initialized');": "",
" } else {": "",
" console.warn('Telegram WebApp SDK not found. Running in browser mode.');": "",
" }": "",
"}": "",
"export function getTelegramUser() {": "",
" return tg?.initDataUnsafe?.user || null;": "",
"}": "",
"export function getAuthHeaders() {": "",
" const headers = {};": "",
" if (tg && tg.initData) {": "",
" headers['X-Telegram-Init-Data'] = tg.initData;": "",
" }": "",
" // Also check if we have a token stored in localStorage (for desktop browser access)": "",
" const token = localStorage.getItem('finance_auth_token');": "",
" if (token) {": "",
" headers['Authorization'] = `Bearer ${token}`;": "",
" }": "",
" return headers;": "",
"}": "",
"export function saveTokenFromUrl() {": "",
" const params = new URLSearchParams(window.location.search);": "",
" const token = params.get('token');": "",
" if (token) {": "",
" localStorage.setItem('finance_auth_token', token);": "",
" // Clean up url": "",
" window.history.replaceState({}, document.title, window.location.pathname);": "",
" return token;": "",
" }": "",
" return localStorage.getItem('finance_auth_token');": "",
"}": "",
"export function logout() {": "",
" localStorage.removeItem('finance_auth_token');": "",
" window.location.reload();": "",
"}": "",
"/**\n * Generates markup for a Telegram message with an 'Add Expense' button.\n */": "",
"export function getExpenseButtonMarkup() {": "",
" return `\n <telegram>\n <message>\n Please enter the expense amount and description:\n <button data-action=\"add_expense\">Add Expense</button>\n </message>\n </telegram>\n`;": "",
"}": ""
}
+21
View File
@@ -0,0 +1,21 @@
{
"name": "Finance-bot",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"node-telegram-bot-api": "^1.2.0"
}
},
"node_modules/node-telegram-bot-api": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/node-telegram-bot-api/-/node-telegram-bot-api-1.2.0.tgz",
"integrity": "sha512-M6S61LZn1FQMQnZSdFlc4oV+mwDGlPTbLzq/GUaSH4ew40wGTaKPtAaLp5oOhl/C3k0ylGqMIppJsVulwTCePg==",
"license": "MIT",
"engines": {
"node": ">=18"
}
}
}
}
+5
View File
@@ -0,0 +1,5 @@
{
"dependencies": {
"node-telegram-bot-api": "^1.2.0"
}
}