645 lines
31 KiB
TypeScript
645 lines
31 KiB
TypeScript
import TelegramBot from 'node-telegram-bot-api';
|
||
import { v4 as uuidv4 } from 'uuid';
|
||
import { query } from '../database/connection';
|
||
import { NotificationService } from '../services/notificationService';
|
||
|
||
interface NotificationSettings {
|
||
newMatches: boolean;
|
||
newMessages: boolean;
|
||
newLikes: boolean;
|
||
reminders: boolean;
|
||
dailySummary: boolean;
|
||
timePreference: 'morning' | 'afternoon' | 'evening' | 'night';
|
||
doNotDisturb: boolean;
|
||
doNotDisturbStart?: string;
|
||
doNotDisturbEnd?: string;
|
||
}
|
||
|
||
export class NotificationHandlers {
|
||
private bot: TelegramBot;
|
||
private notificationService: NotificationService;
|
||
|
||
constructor(bot: TelegramBot) {
|
||
this.bot = bot;
|
||
this.notificationService = new NotificationService(bot);
|
||
}
|
||
|
||
// Метод для получения экземпляра сервиса уведомлений
|
||
getNotificationService(): NotificationService {
|
||
return this.notificationService;
|
||
}
|
||
|
||
// Обработка команды /notifications
|
||
async handleNotificationsCommand(msg: TelegramBot.Message): Promise<void> {
|
||
const telegramId = msg.from?.id.toString();
|
||
if (!telegramId) return;
|
||
|
||
try {
|
||
const userId = await this.getUserIdByTelegramId(telegramId);
|
||
if (!userId) {
|
||
await this.bot.sendMessage(msg.chat.id, '❌ Вы не зарегистрированы. Используйте команду /start для регистрации.');
|
||
return;
|
||
}
|
||
|
||
const settings = await this.notificationService.getNotificationSettings(userId);
|
||
await this.sendNotificationSettings(msg.chat.id, settings as NotificationSettings);
|
||
} catch (error) {
|
||
console.error('Error handling notifications command:', error);
|
||
await this.bot.sendMessage(msg.chat.id, '❌ Произошла ошибка при загрузке настроек уведомлений.');
|
||
}
|
||
}
|
||
|
||
// Отправка меню настроек уведомлений
|
||
async sendNotificationSettings(chatId: number, settings: NotificationSettings): Promise<void> {
|
||
const message = `
|
||
🔔 *Настройки уведомлений*
|
||
|
||
Выберите, какие уведомления вы хотите получать:
|
||
|
||
${settings.newMatches ? '✅' : '❌'} Новые матчи
|
||
${settings.newMessages ? '✅' : '❌'} Новые сообщения
|
||
${settings.newLikes ? '✅' : '❌'} Новые лайки
|
||
${settings.reminders ? '✅' : '❌'} Напоминания
|
||
${settings.dailySummary ? '✅' : '❌'} Ежедневные сводки
|
||
|
||
⏰ Предпочтительное время: ${this.getTimePreferenceText(settings.timePreference)}
|
||
|
||
${settings.doNotDisturb ? '🔕' : '🔔'} Режим "Не беспокоить": ${settings.doNotDisturb ? 'Включен' : 'Выключен'}
|
||
${settings.doNotDisturb && settings.doNotDisturbStart && settings.doNotDisturbEnd ?
|
||
`с ${settings.doNotDisturbStart} до ${settings.doNotDisturbEnd}` : ''}
|
||
|
||
Нажмите на кнопку, чтобы изменить настройку:
|
||
`;
|
||
|
||
await this.bot.sendMessage(chatId, message, {
|
||
parse_mode: 'Markdown',
|
||
reply_markup: {
|
||
inline_keyboard: [
|
||
[
|
||
{ text: `${settings.newMatches ? '✅' : '❌'} Новые матчи`, callback_data: 'notif_toggle:newMatches' },
|
||
{ text: `${settings.newMessages ? '✅' : '❌'} Новые сообщения`, callback_data: 'notif_toggle:newMessages' }
|
||
],
|
||
[
|
||
{ text: `${settings.newLikes ? '✅' : '❌'} Новые лайки`, callback_data: 'notif_toggle:newLikes' },
|
||
{ text: `${settings.reminders ? '✅' : '❌'} Напоминания`, callback_data: 'notif_toggle:reminders' }
|
||
],
|
||
[
|
||
{ text: `${settings.dailySummary ? '✅' : '❌'} Ежедневные сводки`, callback_data: 'notif_toggle:dailySummary' }
|
||
],
|
||
[
|
||
{ text: `⏰ Время: ${this.getTimePreferenceText(settings.timePreference)}`, callback_data: 'notif_time' }
|
||
],
|
||
[
|
||
{ text: `${settings.doNotDisturb ? '🔕' : '🔔'} Режим "Не беспокоить"`, callback_data: 'notif_dnd' }
|
||
],
|
||
[
|
||
{ text: '↩️ Назад', callback_data: 'settings' }
|
||
]
|
||
]
|
||
}
|
||
});
|
||
}
|
||
|
||
// Обработка переключения настройки уведомления
|
||
async handleNotificationToggle(callbackQuery: TelegramBot.CallbackQuery): Promise<void> {
|
||
const telegramId = callbackQuery.from?.id.toString();
|
||
if (!telegramId || !callbackQuery.message) return;
|
||
|
||
try {
|
||
const userId = await this.getUserIdByTelegramId(telegramId);
|
||
if (!userId) {
|
||
await this.bot.answerCallbackQuery(callbackQuery.id, { text: '❌ Вы не зарегистрированы.' });
|
||
return;
|
||
}
|
||
|
||
// notif_toggle:settingName
|
||
const settingName = callbackQuery.data?.split(':')[1];
|
||
if (!settingName) return;
|
||
|
||
const settings = await this.notificationService.getNotificationSettings(userId);
|
||
let updatedSettings: Partial<NotificationSettings> = { ...settings };
|
||
|
||
// Инвертируем значение настройки
|
||
if (settingName in updatedSettings) {
|
||
switch(settingName) {
|
||
case 'newMatches':
|
||
updatedSettings.newMatches = !updatedSettings.newMatches;
|
||
break;
|
||
case 'newMessages':
|
||
updatedSettings.newMessages = !updatedSettings.newMessages;
|
||
break;
|
||
case 'newLikes':
|
||
updatedSettings.newLikes = !updatedSettings.newLikes;
|
||
break;
|
||
case 'reminders':
|
||
updatedSettings.reminders = !updatedSettings.reminders;
|
||
break;
|
||
case 'dailySummary':
|
||
updatedSettings.dailySummary = !updatedSettings.dailySummary;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Обновляем настройки
|
||
await this.notificationService.updateNotificationSettings(userId, updatedSettings);
|
||
|
||
// Отправляем обновленные настройки
|
||
await this.bot.answerCallbackQuery(callbackQuery.id, {
|
||
text: `✅ Настройка "${this.getSettingName(settingName)}" ${updatedSettings[settingName as keyof NotificationSettings] ? 'включена' : 'отключена'}`
|
||
});
|
||
|
||
await this.sendNotificationSettings(callbackQuery.message.chat.id, updatedSettings as NotificationSettings);
|
||
} catch (error) {
|
||
console.error('Error handling notification toggle:', error);
|
||
await this.bot.answerCallbackQuery(callbackQuery.id, { text: '❌ Произошла ошибка при обновлении настроек.' });
|
||
}
|
||
}
|
||
|
||
// Обработка выбора времени для уведомлений
|
||
async handleTimePreference(callbackQuery: TelegramBot.CallbackQuery): Promise<void> {
|
||
if (!callbackQuery.message) return;
|
||
|
||
await this.bot.editMessageText('⏰ *Выберите предпочтительное время для уведомлений:*', {
|
||
chat_id: callbackQuery.message.chat.id,
|
||
message_id: callbackQuery.message.message_id,
|
||
parse_mode: 'Markdown',
|
||
reply_markup: {
|
||
inline_keyboard: [
|
||
[
|
||
{ text: '🌅 Утро (9:00)', callback_data: 'notif_time_set:morning' },
|
||
{ text: '☀️ День (13:00)', callback_data: 'notif_time_set:afternoon' }
|
||
],
|
||
[
|
||
{ text: '🌆 Вечер (19:00)', callback_data: 'notif_time_set:evening' },
|
||
{ text: '🌙 Ночь (22:00)', callback_data: 'notif_time_set:night' }
|
||
],
|
||
[
|
||
{ text: '↩️ Назад', callback_data: 'notifications' }
|
||
]
|
||
]
|
||
}
|
||
});
|
||
|
||
await this.bot.answerCallbackQuery(callbackQuery.id);
|
||
}
|
||
|
||
// Обработка установки времени для уведомлений
|
||
async handleTimePreferenceSet(callbackQuery: TelegramBot.CallbackQuery): Promise<void> {
|
||
const telegramId = callbackQuery.from?.id.toString();
|
||
if (!telegramId || !callbackQuery.message) return;
|
||
|
||
try {
|
||
const userId = await this.getUserIdByTelegramId(telegramId);
|
||
if (!userId) {
|
||
await this.bot.answerCallbackQuery(callbackQuery.id, { text: '❌ Вы не зарегистрированы.' });
|
||
return;
|
||
}
|
||
|
||
// notif_time_set:timePreference
|
||
const timePreference = callbackQuery.data?.split(':')[1] as 'morning' | 'afternoon' | 'evening' | 'night';
|
||
if (!timePreference) return;
|
||
|
||
const settings = await this.notificationService.getNotificationSettings(userId);
|
||
// Копируем существующие настройки и обновляем нужные поля
|
||
const existingSettings = settings as NotificationSettings;
|
||
const updatedSettings: NotificationSettings = {
|
||
...existingSettings,
|
||
timePreference
|
||
};
|
||
|
||
// Обновляем настройки
|
||
await this.notificationService.updateNotificationSettings(userId, updatedSettings);
|
||
|
||
// Отправляем обновленные настройки
|
||
await this.bot.answerCallbackQuery(callbackQuery.id, {
|
||
text: `✅ Время уведомлений установлено на ${this.getTimePreferenceText(timePreference)}`
|
||
});
|
||
|
||
await this.sendNotificationSettings(callbackQuery.message.chat.id, updatedSettings);
|
||
} catch (error) {
|
||
console.error('Error handling time preference set:', error);
|
||
await this.bot.answerCallbackQuery(callbackQuery.id, { text: '❌ Произошла ошибка при обновлении времени уведомлений.' });
|
||
}
|
||
}
|
||
|
||
// Обработка режима "Не беспокоить"
|
||
async handleDndMode(callbackQuery: TelegramBot.CallbackQuery): Promise<void> {
|
||
if (!callbackQuery.message) return;
|
||
|
||
await this.bot.editMessageText('🔕 *Режим "Не беспокоить"*\n\nВыберите действие:', {
|
||
chat_id: callbackQuery.message.chat.id,
|
||
message_id: callbackQuery.message.message_id,
|
||
parse_mode: 'Markdown',
|
||
reply_markup: {
|
||
inline_keyboard: [
|
||
[
|
||
{ text: '✅ Включить', callback_data: 'notif_dnd_set:on' },
|
||
{ text: '❌ Выключить', callback_data: 'notif_dnd_set:off' }
|
||
],
|
||
[
|
||
{ text: '⏰ Настроить время', callback_data: 'notif_dnd_time' }
|
||
],
|
||
[
|
||
{ text: '↩️ Назад', callback_data: 'notifications' }
|
||
]
|
||
]
|
||
}
|
||
});
|
||
|
||
await this.bot.answerCallbackQuery(callbackQuery.id);
|
||
}
|
||
|
||
// Обработка установки режима "Не беспокоить"
|
||
async handleDndModeSet(callbackQuery: TelegramBot.CallbackQuery): Promise<void> {
|
||
const telegramId = callbackQuery.from?.id.toString();
|
||
if (!telegramId || !callbackQuery.message) return;
|
||
|
||
try {
|
||
const userId = await this.getUserIdByTelegramId(telegramId);
|
||
if (!userId) {
|
||
await this.bot.answerCallbackQuery(callbackQuery.id, { text: '❌ Вы не зарегистрированы.' });
|
||
return;
|
||
}
|
||
|
||
// notif_dnd_set:on/off
|
||
const mode = callbackQuery.data?.split(':')[1];
|
||
if (!mode) return;
|
||
|
||
const settings = await this.notificationService.getNotificationSettings(userId);
|
||
// Копируем существующие настройки и обновляем нужное поле
|
||
const existingSettings = settings as NotificationSettings;
|
||
let updatedSettings: NotificationSettings = {
|
||
...existingSettings,
|
||
doNotDisturb: mode === 'on'
|
||
};
|
||
|
||
// Если включаем режим "Не беспокоить", но не задано время, ставим дефолтные значения
|
||
if (mode === 'on' && (!updatedSettings.doNotDisturbStart || !updatedSettings.doNotDisturbEnd)) {
|
||
updatedSettings.doNotDisturbStart = '23:00';
|
||
updatedSettings.doNotDisturbEnd = '08:00';
|
||
}
|
||
|
||
// Обновляем настройки
|
||
await this.notificationService.updateNotificationSettings(userId, updatedSettings);
|
||
|
||
// Отправляем обновленные настройки
|
||
await this.bot.answerCallbackQuery(callbackQuery.id, {
|
||
text: `✅ Режим "Не беспокоить" ${mode === 'on' ? 'включен' : 'выключен'}`
|
||
});
|
||
|
||
await this.sendNotificationSettings(callbackQuery.message.chat.id, updatedSettings);
|
||
} catch (error) {
|
||
console.error('Error handling DND mode set:', error);
|
||
await this.bot.answerCallbackQuery(callbackQuery.id, { text: '❌ Произошла ошибка при обновлении режима "Не беспокоить".' });
|
||
}
|
||
}
|
||
|
||
// Настройка времени для режима "Не беспокоить"
|
||
async handleDndTimeSetup(callbackQuery: TelegramBot.CallbackQuery): Promise<void> {
|
||
if (!callbackQuery.message) return;
|
||
|
||
await this.bot.editMessageText('⏰ *Настройка времени для режима "Не беспокоить"*\n\nВыберите один из предустановленных вариантов или введите свой:', {
|
||
chat_id: callbackQuery.message.chat.id,
|
||
message_id: callbackQuery.message.message_id,
|
||
parse_mode: 'Markdown',
|
||
reply_markup: {
|
||
inline_keyboard: [
|
||
[
|
||
{ text: '🌙 23:00 - 08:00', callback_data: 'notif_dnd_time_set:23:00:08:00' }
|
||
],
|
||
[
|
||
{ text: '🌙 22:00 - 07:00', callback_data: 'notif_dnd_time_set:22:00:07:00' }
|
||
],
|
||
[
|
||
{ text: '🌙 00:00 - 09:00', callback_data: 'notif_dnd_time_set:00:00:09:00' }
|
||
],
|
||
[
|
||
{ text: '✏️ Ввести свой вариант', callback_data: 'notif_dnd_time_custom' }
|
||
],
|
||
[
|
||
{ text: '↩️ Назад', callback_data: 'notif_dnd' }
|
||
]
|
||
]
|
||
}
|
||
});
|
||
|
||
await this.bot.answerCallbackQuery(callbackQuery.id);
|
||
}
|
||
|
||
// Установка предустановленного времени для режима "Не беспокоить"
|
||
async handleDndTimeSet(callbackQuery: TelegramBot.CallbackQuery): Promise<void> {
|
||
const telegramId = callbackQuery.from?.id.toString();
|
||
if (!telegramId || !callbackQuery.message) return;
|
||
|
||
try {
|
||
const userId = await this.getUserIdByTelegramId(telegramId);
|
||
if (!userId) {
|
||
await this.bot.answerCallbackQuery(callbackQuery.id, { text: '❌ Вы не зарегистрированы.' });
|
||
return;
|
||
}
|
||
|
||
// notif_dnd_time_set:startTime:endTime
|
||
const parts = callbackQuery.data?.split(':');
|
||
if (parts && parts.length >= 4) {
|
||
const startTime = `${parts[2]}:${parts[3]}`;
|
||
const endTime = `${parts[4]}:${parts[5]}`;
|
||
|
||
const settings = await this.notificationService.getNotificationSettings(userId);
|
||
// Копируем существующие настройки и обновляем нужные поля
|
||
const existingSettings = settings as NotificationSettings;
|
||
const updatedSettings: NotificationSettings = {
|
||
...existingSettings,
|
||
doNotDisturb: true,
|
||
doNotDisturbStart: startTime,
|
||
doNotDisturbEnd: endTime
|
||
};
|
||
|
||
// Обновляем настройки
|
||
await this.notificationService.updateNotificationSettings(userId, updatedSettings);
|
||
|
||
// Отправляем обновленные настройки
|
||
await this.bot.answerCallbackQuery(callbackQuery.id, {
|
||
text: `✅ Время "Не беспокоить" установлено с ${startTime} до ${endTime}`
|
||
});
|
||
|
||
await this.sendNotificationSettings(callbackQuery.message.chat.id, updatedSettings);
|
||
}
|
||
} catch (error) {
|
||
console.error('Error handling DND time set:', error);
|
||
await this.bot.answerCallbackQuery(callbackQuery.id, { text: '❌ Произошла ошибка при настройке времени "Не беспокоить".' });
|
||
}
|
||
}
|
||
|
||
// Запрос пользовательского времени для режима "Не беспокоить"
|
||
async handleDndTimeCustom(callbackQuery: TelegramBot.CallbackQuery): Promise<void> {
|
||
if (!callbackQuery.message) return;
|
||
|
||
// Устанавливаем ожидание пользовательского ввода
|
||
const userId = callbackQuery.from?.id.toString();
|
||
if (userId) {
|
||
await this.setUserState(userId, 'waiting_dnd_time');
|
||
}
|
||
|
||
await this.bot.editMessageText('⏰ *Введите время для режима "Не беспокоить"*\n\nУкажите время в формате:\n`с [ЧЧ:ММ] до [ЧЧ:ММ]`\n\nНапример: `с 23:30 до 07:00`', {
|
||
chat_id: callbackQuery.message.chat.id,
|
||
message_id: callbackQuery.message.message_id,
|
||
parse_mode: 'Markdown',
|
||
reply_markup: {
|
||
inline_keyboard: [
|
||
[
|
||
{ text: '↩️ Отмена', callback_data: 'notif_dnd_time' }
|
||
]
|
||
]
|
||
}
|
||
});
|
||
|
||
await this.bot.answerCallbackQuery(callbackQuery.id);
|
||
}
|
||
|
||
// Обработка пользовательского ввода времени для режима "Не беспокоить"
|
||
async handleDndTimeInput(msg: TelegramBot.Message): Promise<void> {
|
||
const telegramId = msg.from?.id.toString();
|
||
if (!telegramId) return;
|
||
|
||
try {
|
||
const userId = await this.getUserIdByTelegramId(telegramId);
|
||
if (!userId) {
|
||
await this.bot.sendMessage(msg.chat.id, '❌ Вы не зарегистрированы. Используйте команду /start для регистрации.');
|
||
return;
|
||
}
|
||
|
||
// Очищаем состояние ожидания
|
||
await this.clearUserState(telegramId);
|
||
|
||
// Парсим введенное время
|
||
const timeRegex = /с\s+(\d{1,2}[:\.]\d{2})\s+до\s+(\d{1,2}[:\.]\d{2})/i;
|
||
const match = msg.text?.match(timeRegex);
|
||
|
||
if (match && match.length >= 3) {
|
||
let startTime = match[1].replace('.', ':');
|
||
let endTime = match[2].replace('.', ':');
|
||
|
||
// Проверяем и форматируем время
|
||
if (this.isValidTime(startTime) && this.isValidTime(endTime)) {
|
||
startTime = this.formatTime(startTime);
|
||
endTime = this.formatTime(endTime);
|
||
|
||
const settings = await this.notificationService.getNotificationSettings(userId);
|
||
// Копируем существующие настройки и обновляем нужные поля
|
||
const existingSettings = settings as NotificationSettings;
|
||
const updatedSettings: NotificationSettings = {
|
||
...existingSettings,
|
||
doNotDisturb: true,
|
||
doNotDisturbStart: startTime,
|
||
doNotDisturbEnd: endTime
|
||
};
|
||
|
||
// Обновляем настройки
|
||
await this.notificationService.updateNotificationSettings(userId, updatedSettings);
|
||
|
||
await this.bot.sendMessage(msg.chat.id, `✅ Время "Не беспокоить" установлено с ${startTime} до ${endTime}`);
|
||
await this.sendNotificationSettings(msg.chat.id, updatedSettings);
|
||
} else {
|
||
await this.bot.sendMessage(msg.chat.id, '❌ Неверный формат времени. Пожалуйста, используйте формат ЧЧ:ММ (например, 23:30).');
|
||
}
|
||
} else {
|
||
await this.bot.sendMessage(msg.chat.id, '❌ Неверный формат ввода. Пожалуйста, введите время в формате "с [ЧЧ:ММ] до [ЧЧ:ММ]" (например, "с 23:30 до 07:00").');
|
||
}
|
||
} catch (error) {
|
||
console.error('Error handling DND time input:', error);
|
||
await this.bot.sendMessage(msg.chat.id, '❌ Произошла ошибка при настройке времени "Не беспокоить".');
|
||
}
|
||
}
|
||
|
||
// Проверка валидности времени
|
||
private isValidTime(time: string): boolean {
|
||
const regex = /^(\d{1,2}):(\d{2})$/;
|
||
const match = time.match(regex);
|
||
|
||
if (match) {
|
||
const hours = parseInt(match[1]);
|
||
const minutes = parseInt(match[2]);
|
||
return hours >= 0 && hours <= 23 && minutes >= 0 && minutes <= 59;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
// Форматирование времени в формат ЧЧ:ММ
|
||
private formatTime(time: string): string {
|
||
const [hours, minutes] = time.split(':').map(Number);
|
||
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
|
||
}
|
||
|
||
// Получение текстового представления времени
|
||
private getTimePreferenceText(preference: string): string {
|
||
switch (preference) {
|
||
case 'morning': return 'Утро (9:00)';
|
||
case 'afternoon': return 'День (13:00)';
|
||
case 'evening': return 'Вечер (19:00)';
|
||
case 'night': return 'Ночь (22:00)';
|
||
default: return 'Вечер (19:00)';
|
||
}
|
||
}
|
||
|
||
// Получение названия настройки
|
||
private getSettingName(setting: string): string {
|
||
switch (setting) {
|
||
case 'newMatches': return 'Новые матчи';
|
||
case 'newMessages': return 'Новые сообщения';
|
||
case 'newLikes': return 'Новые лайки';
|
||
case 'reminders': return 'Напоминания';
|
||
case 'dailySummary': return 'Ежедневные сводки';
|
||
default: return setting;
|
||
}
|
||
}
|
||
|
||
// Получение ID пользователя по Telegram ID
|
||
private async getUserIdByTelegramId(telegramId: string): Promise<string | null> {
|
||
try {
|
||
const result = await query(
|
||
'SELECT id FROM users WHERE telegram_id = $1',
|
||
[parseInt(telegramId)]
|
||
);
|
||
return result.rows.length > 0 ? result.rows[0].id : null;
|
||
} catch (error) {
|
||
console.error('Error getting user by telegram ID:', error);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// Установка состояния ожидания пользователя
|
||
private async setUserState(telegramId: string, state: string): Promise<void> {
|
||
try {
|
||
const userId = await this.getUserIdByTelegramId(telegramId);
|
||
if (!userId) return;
|
||
|
||
// Сначала проверяем, существуют ли столбцы state и state_data
|
||
const checkColumnResult = await query(`
|
||
SELECT column_name
|
||
FROM information_schema.columns
|
||
WHERE table_name = 'users' AND column_name = 'state'
|
||
`);
|
||
|
||
if (checkColumnResult.rows.length === 0) {
|
||
console.log('Adding state and state_data columns to users table...');
|
||
// Добавляем столбцы, если их нет
|
||
await query(`
|
||
ALTER TABLE users ADD COLUMN IF NOT EXISTS state VARCHAR(255) NULL;
|
||
ALTER TABLE users ADD COLUMN IF NOT EXISTS state_data JSONB DEFAULT '{}'::jsonb;
|
||
`);
|
||
}
|
||
|
||
// Теперь устанавливаем состояние
|
||
await query(
|
||
`UPDATE users
|
||
SET state = $1,
|
||
state_data = jsonb_set(COALESCE(state_data, '{}'::jsonb), '{timestamp}', to_jsonb(NOW()))
|
||
WHERE telegram_id = $2`,
|
||
[state, parseInt(telegramId)]
|
||
);
|
||
} catch (error) {
|
||
console.error('Error setting user state:', error);
|
||
}
|
||
}
|
||
|
||
// Очистка состояния ожидания пользователя
|
||
private async clearUserState(telegramId: string): Promise<void> {
|
||
try {
|
||
await query(
|
||
'UPDATE users SET state = NULL WHERE telegram_id = $1',
|
||
[parseInt(telegramId)]
|
||
);
|
||
} catch (error) {
|
||
console.error('Error clearing user state:', error);
|
||
}
|
||
}
|
||
|
||
// Регистрация обработчиков уведомлений
|
||
register(): void {
|
||
// Команда настройки уведомлений
|
||
this.bot.onText(/\/notifications/, this.handleNotificationsCommand.bind(this));
|
||
|
||
// Обработчик для кнопки настроек уведомлений в меню настроек
|
||
this.bot.on('callback_query', async (callbackQuery) => {
|
||
if (callbackQuery.data === 'notifications') {
|
||
const telegramId = callbackQuery.from?.id.toString();
|
||
if (!telegramId || !callbackQuery.message) return;
|
||
|
||
try {
|
||
const userId = await this.getUserIdByTelegramId(telegramId);
|
||
if (!userId) {
|
||
await this.bot.answerCallbackQuery(callbackQuery.id, { text: '❌ Вы не зарегистрированы.' });
|
||
return;
|
||
}
|
||
|
||
const settings = await this.notificationService.getNotificationSettings(userId);
|
||
await this.sendNotificationSettings(callbackQuery.message.chat.id, settings as NotificationSettings);
|
||
await this.bot.answerCallbackQuery(callbackQuery.id);
|
||
} catch (error) {
|
||
console.error('Error handling notifications callback:', error);
|
||
await this.bot.answerCallbackQuery(callbackQuery.id, { text: '❌ Произошла ошибка при загрузке настроек уведомлений.' });
|
||
}
|
||
}
|
||
else if (callbackQuery.data?.startsWith('notif_toggle:')) {
|
||
await this.handleNotificationToggle(callbackQuery);
|
||
}
|
||
else if (callbackQuery.data === 'notif_time') {
|
||
await this.handleTimePreference(callbackQuery);
|
||
}
|
||
else if (callbackQuery.data?.startsWith('notif_time_set:')) {
|
||
await this.handleTimePreferenceSet(callbackQuery);
|
||
}
|
||
else if (callbackQuery.data === 'notif_dnd') {
|
||
await this.handleDndMode(callbackQuery);
|
||
}
|
||
else if (callbackQuery.data?.startsWith('notif_dnd_set:')) {
|
||
await this.handleDndModeSet(callbackQuery);
|
||
}
|
||
else if (callbackQuery.data === 'notif_dnd_time') {
|
||
await this.handleDndTimeSetup(callbackQuery);
|
||
}
|
||
else if (callbackQuery.data?.startsWith('notif_dnd_time_set:')) {
|
||
await this.handleDndTimeSet(callbackQuery);
|
||
}
|
||
else if (callbackQuery.data === 'notif_dnd_time_custom') {
|
||
await this.handleDndTimeCustom(callbackQuery);
|
||
}
|
||
});
|
||
|
||
// Обработчик пользовательского ввода для времени "Не беспокоить"
|
||
this.bot.on('message', async (msg) => {
|
||
if (!msg.text) return;
|
||
|
||
const telegramId = msg.from?.id.toString();
|
||
if (!telegramId) return;
|
||
|
||
try {
|
||
// Сначала проверяем, существует ли столбец state
|
||
const checkColumnResult = await query(`
|
||
SELECT column_name
|
||
FROM information_schema.columns
|
||
WHERE table_name = 'users' AND column_name = 'state'
|
||
`);
|
||
|
||
if (checkColumnResult.rows.length === 0) {
|
||
console.log('State column does not exist in users table. Skipping state check.');
|
||
return;
|
||
}
|
||
|
||
// Теперь проверяем состояние пользователя
|
||
const result = await query(
|
||
'SELECT state FROM users WHERE telegram_id = $1',
|
||
[parseInt(telegramId)]
|
||
);
|
||
|
||
if (result.rows.length > 0 && result.rows[0].state === 'waiting_dnd_time') {
|
||
await this.handleDndTimeInput(msg);
|
||
}
|
||
} catch (error) {
|
||
console.error('Error checking user state:', error);
|
||
}
|
||
});
|
||
}
|
||
}
|