Files
tg_tinder_bot/src/handlers/commandHandlers.ts

307 lines
13 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import TelegramBot, { Message, InlineKeyboardMarkup } from 'node-telegram-bot-api';
import { ProfileService } from '../services/profileService';
import { MatchingService } from '../services/matchingService';
import { Profile } from '../models/Profile';
export class CommandHandlers {
private bot: TelegramBot;
private profileService: ProfileService;
private matchingService: MatchingService;
constructor(bot: TelegramBot) {
this.bot = bot;
this.profileService = new ProfileService();
this.matchingService = new MatchingService();
}
register(): void {
this.bot.onText(/\/start/, (msg: Message) => this.handleStart(msg));
this.bot.onText(/\/help/, (msg: Message) => this.handleHelp(msg));
this.bot.onText(/\/profile/, (msg: Message) => this.handleProfile(msg));
this.bot.onText(/\/browse/, (msg: Message) => this.handleBrowse(msg));
this.bot.onText(/\/matches/, (msg: Message) => this.handleMatches(msg));
this.bot.onText(/\/settings/, (msg: Message) => this.handleSettings(msg));
this.bot.onText(/\/create_profile/, (msg: Message) => this.handleCreateProfile(msg));
}
async handleStart(msg: Message): Promise<void> {
const userId = msg.from?.id.toString();
if (!userId) return;
// Проверяем есть ли у пользователя профиль
const existingProfile = await this.profileService.getProfileByTelegramId(userId);
if (existingProfile) {
const keyboard: InlineKeyboardMarkup = {
inline_keyboard: [
[
{ text: '👤 Мой профиль', callback_data: 'view_my_profile' },
{ text: '🔍 Просмотр анкет', callback_data: 'start_browsing' }
],
[
{ text: '💕 Мои матчи', callback_data: 'view_matches' },
{ text: '⭐ VIP поиск', callback_data: 'vip_search' }
],
[
{ text: '⚙️ Настройки', callback_data: 'settings' }
]
]
};
await this.bot.sendMessage(
msg.chat.id,
`🎉 С возвращением, ${existingProfile.name}!\n\n` +
`💖 Telegram Tinder Bot готов к работе!\n\n` +
`Что хотите сделать?`,
{ reply_markup: keyboard }
);
} else {
const keyboard: InlineKeyboardMarkup = {
inline_keyboard: [
[{ text: '<27> Создать профиль', callback_data: 'create_profile' }],
[{ text: ' Как это работает?', callback_data: 'how_it_works' }]
]
};
await this.bot.sendMessage(
msg.chat.id,
`🎉 Добро пожаловать в Telegram Tinder Bot!\n\n` +
`💕 Здесь вы можете найти свою вторую половинку!\n\n` +
`Для начала создайте свой профиль:`,
{ reply_markup: keyboard }
);
}
}
async handleHelp(msg: Message): Promise<void> {
const helpText = `
🤖 Telegram Tinder Bot - Справка
📋 Доступные команды:
/start - Главное меню
/profile - Управление профилем
/browse - Просмотр анкет
/matches - Ваши матчи
/settings - Настройки
/help - Эта справка
<EFBFBD> Как использовать:
1. Создайте профиль с фото и описанием
2. Просматривайте анкеты других пользователей
3. Ставьте лайки понравившимся
4. Общайтесь с взаимными матчами!
❤️ Удачи в поиске любви!
`;
await this.bot.sendMessage(msg.chat.id, helpText.trim());
}
async handleProfile(msg: Message): Promise<void> {
const userId = msg.from?.id.toString();
if (!userId) return;
const profile = await this.profileService.getProfileByTelegramId(userId);
if (!profile) {
const keyboard: InlineKeyboardMarkup = {
inline_keyboard: [
[{ text: '🚀 Создать профиль', callback_data: 'create_profile' }]
]
};
await this.bot.sendMessage(
msg.chat.id,
'❌ У вас пока нет профиля.\nСоздайте его для начала использования бота!',
{ reply_markup: keyboard }
);
return;
}
// Показываем профиль пользователя
await this.showUserProfile(msg.chat.id, profile, true);
}
async handleBrowse(msg: Message): Promise<void> {
const userId = msg.from?.id.toString();
if (!userId) return;
const profile = await this.profileService.getProfileByTelegramId(userId);
if (!profile) {
await this.bot.sendMessage(
msg.chat.id,
'❌ Сначала создайте профиль!\nИспользуйте команду /start'
);
return;
}
await this.showNextCandidate(msg.chat.id, userId);
}
async handleMatches(msg: Message): Promise<void> {
const userId = msg.from?.id.toString();
if (!userId) return;
// Получаем матчи пользователя
const matches = await this.matchingService.getUserMatches(userId);
if (matches.length === 0) {
await this.bot.sendMessage(
msg.chat.id,
'<27> У вас пока нет матчей.\n\n' +
'🔍 Попробуйте просмотреть больше анкет!\n' +
'Используйте /browse для поиска.'
);
return;
}
let matchText = `💕 Ваши матчи (${matches.length}):\n\n`;
for (const match of matches) {
const otherUserId = match.userId1 === userId ? match.userId2 : match.userId1;
const otherProfile = await this.profileService.getProfileByUserId(otherUserId);
if (otherProfile) {
matchText += `💖 ${otherProfile.name}, ${otherProfile.age}\n`;
matchText += `📍 ${otherProfile.city || 'Не указан'}\n`;
matchText += `💌 Матч: ${new Date(match.createdAt).toLocaleDateString()}\n\n`;
}
}
const keyboard: InlineKeyboardMarkup = {
inline_keyboard: [
[{ text: '💬 Открыть чаты', callback_data: 'open_chats' }],
[{ text: '<27> Нативные чаты', callback_data: 'native_chats' }],
[{ text: '<27>🔍 Найти еще', callback_data: 'start_browsing' }]
]
};
await this.bot.sendMessage(msg.chat.id, matchText, { reply_markup: keyboard });
}
async handleSettings(msg: Message): Promise<void> {
const keyboard: InlineKeyboardMarkup = {
inline_keyboard: [
[
{ text: '🔍 Настройки поиска', callback_data: 'search_settings' },
{ text: '🔔 Уведомления', callback_data: 'notification_settings' }
],
[
{ text: '🚫 Скрыть профиль', callback_data: 'hide_profile' },
{ text: '🗑 Удалить профиль', callback_data: 'delete_profile' }
]
]
};
await this.bot.sendMessage(
msg.chat.id,
'⚙️ Настройки профиля\n\nВыберите что хотите изменить:',
{ reply_markup: keyboard }
);
}
async handleCreateProfile(msg: Message): Promise<void> {
const userId = msg.from?.id.toString();
if (!userId) return;
await this.bot.sendMessage(
msg.chat.id,
'👋 Давайте создадим ваш профиль!\n\n' +
'📝 Сначала напишите ваше имя:'
);
// Устанавливаем состояние ожидания имени
// Это будет обрабатываться в messageHandlers
}
// Вспомогательные методы
async showUserProfile(chatId: number, profile: Profile, isOwner: boolean = false): Promise<void> {
const mainPhotoFileId = profile.photos[0]; // Первое фото - главное
let profileText = `👤 ${profile.name}, ${profile.age}\n`;
profileText += `📍 ${profile.city || 'Не указан'}\n`;
if (profile.job) profileText += `💼 ${profile.job}\n`;
if (profile.education) profileText += `🎓 ${profile.education}\n`;
if (profile.height) profileText += `📏 ${profile.height} см\n`;
profileText += `\n📝 ${profile.bio || 'Описание не указано'}\n`;
if (profile.interests.length > 0) {
profileText += `\n🎯 Интересы: ${profile.interests.join(', ')}`;
}
const keyboard: InlineKeyboardMarkup = isOwner ? {
inline_keyboard: [
[
{ text: '✏️ Редактировать', callback_data: 'edit_profile' },
{ text: '📸 Фото', callback_data: 'manage_photos' }
],
[{ text: '🔍 Начать поиск', callback_data: 'start_browsing' }]
]
} : {
inline_keyboard: [
[{ text: '👈 Назад', callback_data: 'back_to_browsing' }]
]
};
if (mainPhotoFileId) {
await this.bot.sendPhoto(chatId, mainPhotoFileId, {
caption: profileText,
reply_markup: keyboard
});
} else {
await this.bot.sendMessage(chatId, profileText, { reply_markup: keyboard });
}
}
async showNextCandidate(chatId: number, userId: string): Promise<void> {
const candidate = await this.matchingService.getNextCandidate(userId);
if (!candidate) {
await this.bot.sendMessage(
chatId,
'🎉 Вы просмотрели всех доступных кандидатов!\n\n' +
'⏰ Попробуйте позже - возможно появятся новые анкеты!'
);
return;
}
const candidatePhotoFileId = candidate.photos[0]; // Первое фото - главное
let candidateText = `${candidate.name}, ${candidate.age}\n`;
candidateText += `📍 ${candidate.city || 'Не указан'}\n`;
if (candidate.job) candidateText += `💼 ${candidate.job}\n`;
if (candidate.education) candidateText += `🎓 ${candidate.education}\n`;
if (candidate.height) candidateText += `📏 ${candidate.height} см\n`;
candidateText += `\n📝 ${candidate.bio || 'Описание отсутствует'}\n`;
if (candidate.interests.length > 0) {
candidateText += `\n🎯 Интересы: ${candidate.interests.join(', ')}`;
}
const keyboard: InlineKeyboardMarkup = {
inline_keyboard: [
[
{ text: '👎 Не нравится', callback_data: `dislike_${candidate.userId}` },
{ text: '💖 Супер лайк', callback_data: `superlike_${candidate.userId}` },
{ text: '👍 Нравится', callback_data: `like_${candidate.userId}` }
],
[
{ text: '👤 Профиль', callback_data: `view_profile_${candidate.userId}` },
{ text: '📸 Еще фото', callback_data: `more_photos_${candidate.userId}` }
],
[{ text: '⏭ Следующий', callback_data: 'next_candidate' }]
]
};
if (candidatePhotoFileId) {
await this.bot.sendPhoto(chatId, candidatePhotoFileId, {
caption: candidateText,
reply_markup: keyboard
});
} else {
await this.bot.sendMessage(chatId, candidateText, { reply_markup: keyboard });
}
}
}