alpha-test
This commit is contained in:
644
src/handlers/notificationHandlers.ts
Normal file
644
src/handlers/notificationHandlers.ts
Normal file
@@ -0,0 +1,644 @@
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user