init commit
This commit is contained in:
302
src/handlers/commandHandlers.ts
Normal file
302
src/handlers/commandHandlers.ts
Normal file
@@ -0,0 +1,302 @@
|
||||
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: '⚙️ Настройки', 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: '🔍 Найти еще', 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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user