const DEF_DELAY = 1000; function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms || DEF_DELAY)); } var config = require('./config'); var Bot = require('node-telegram-bot-api'); var bot = new Bot(process.env.TOKEN||config.token, { polling: true }); console.log('Бот был запущен'); const Courier = require('./curier_api'); var users = {}; bot.onText(/^/, function (msg) { var id = msg.chat.id; const args = msg.text.slice("/").trim().split(/ +/g); const command = args.shift().toLowerCase(); var text = args.join(" "); start_answering(id,command,text); }); //Запуск нужной функции async function launchFunctionByName(data){ switch(data.name){ case 'login': var answer = await command_login(data); return answer; break; case 'relogin': var answer = await command_relogin(data); return answer; break; case 'relogin_all': var answer = await command_relogin_all(data); return answer; break; case 'logout': var answer = await command_logout(data); return answer; break; case 'help': var answer = await command_help(data); return answer; break; case 'myslots': var answer = await command_myslots(data); return answer; break; case 'freeslots': var answer = await command_freeslots(data); return answer; break; case 'orders': var answer = await command_orders(data); return answer; break; case 'query': var answer = await command_query(data); return answer; break; case 'reload_bd': var answer = await command_reload_bd(data); return answer; break; case 'search_point': var answer = await command_search_point(data); return answer; break; case 'test': var answer = await command_test(data); return answer; break; case 'newfreeslots': var answer = await command_newfreeslots(data); return answer; break; default: return data.answer; break; } } //Выполнить операцию с таблицей async function command_query(data){ var answer = data.answer; var client = await new Client({ connectionString: process.env.DATABASE_URL, ssl: { rejectUnauthorized: false } }) await client.connect() .catch(e => { console.error(e); }) try { var client_answer = await client.query(data.text); //delete client_answer["builtins"]; delete client_answer["_types"]; delete client_answer["fields"]; delete client_answer["_parsers"]; delete client_answer["RowCtor"]; delete client_answer["rowAsArray"]; delete client_answer["oid"]; answer += JSON.stringify(client_answer).replace(/{/g,'{\n').replace(/}/g,'\n}').replace(/,/g,',\n') await client.end(); } catch(e){ console.error(e); await client.end(); answer += 'Ошибка запроса' }; return answer; } //Получить список всех доступных комманд function command_help(data){ var answer = data.answer; config.commands.forEach(function (values,keys) { if(values.have_description) if((values.need_admin==data.is_Admin)||(!values.need_admin)) if((values.need_auth==data.is_Auth)||(values.show_after_login&&data.is_Auth)) answer += `\n ${keys} - ${values.description}`; }); if(data.is_Admin){ answer += `\n---------------------- Команды администратора:`; config.admin_commands.forEach(function (values,keys) { if(values.have_description) if((values.need_auth==data.is_Auth)||(values.show_after_login&&data.is_Auth)) answer += `\n ${keys} - ${values.description}`; }); } return answer; } //Авторизоваться async function command_login(data){ var answer = data.answer; var dannie = data.text.split("-") if(dannie.length == 2){ var new_user_data = { id: data.id, username: dannie[0].trim(), password: dannie[1].trim() } var new_user = users[data.id]; if(!new_user) new_user = new Courier(new_user_data); else new_user.updateUser(new_user_data); if(await new_user.auth()&&await new_user.getInfo()){ answer = `Вход выполнен успешно Авторизован: ${new_user.info.name} `; var zones = await new_user.getMyZones(); answer += `Зоны работы: `; for(var zone in zones) answer += `${zone}; ` answer += `\n\nДля изменений отслеживаемой зоны работы используйте /setzone`; } else answer = 'Возникла ошибка при авторизации'; users[data.id] = new_user; newUsers.push(new_user.data()); console.log('Авторизован пользователь id=' + data.id) } return answer; } //Список запланнированных слотов async function command_relogin(data){ var answer = data.answer; if(await users[data.id].auth()&&await users[data.id].getInfo()){ answer += `Авторизован: ${users[data.id].info.name}`; } else answer = `Возникла ошибка :( Авторизуйтесь заново с помощью команды /login`; update_users.push(data.id); return answer; } //Обновить для всех авторизацию async function command_relogin_all(data){ var answer = data.answer; for await(var id of Object.keys(users)){ if(!await users[id].getInfo()){ if(await users[id].auth()&&await users[id].getInfo()){ answer += `Авторизован: ${users[id].info.name}`; update_users.push(id); } else answer += `Не авторизован: ${users[id].username}`; answer += `\n` } } if(answer == `Переавторизация\n`) answer = `Все пользователи авторизованы` return answer; } //Список запланнированных слотов async function command_logout(data){ await users[data.id].reset(); await update_users.push(data.id); return data.answer; } //Список запланнированных слотов async function command_myslots(data){ return await users[data.id].getPlanned(); } //Список свободных слотов async function command_freeslots(data){ return await users[data.id].getFreeSlotsWeek(); } //Текущий заказ async function command_orders(data){ return await users[data.id].getOrdersText(); } //Список новых слотов async function command_newfreeslots(data){ users[data.id].is_waiting = false; return await users[data.id].getNewFreeSlotsWeek(); } //Перезапуск бд async function command_reload_bd(data){ await init_database() return data.answer; } const fuzzysearch = require('fuzzysearch'); const levenshtein = require('js-levenshtein'); //Поиск нужной лавки async function command_search_point(data){ var answer; if(data.text.length==0) return `Для использования команды введите название лавки после /setzone Например: /setzone Ветеранов`; var names = []; for(var zone_name in config.points){ if(data.text.toLowerCase().split(' ').join('') == zone_name.toLowerCase().split(' ').join('')) { names = [zone_name]; break; } else if(fuzzysearch(data.text.toLowerCase().split(' ').join(''), zone_name.toLowerCase().split(' ').join(''))){ names.push(zone_name) } } if(names.length == 1) { answer = `Выбрана точка: ${names}(${config.points[names]})` users[data.id].clearZones(); users[data.id].addZone(config.points[names]); await update_users.push(data.id); // console.log(users[data.id]); } else if(names.length == 0){ var minimal = 100; for(var zone_name in config.points){ var a = levenshtein(data.text.toLowerCase().split(' ').join(''), zone_name.toLowerCase().split(' ').join('')); if(a${answer}`; } else if(answer == '') answer = 'Не найдено сопадений' else { answer = `Найденные лавки: `; for(var name of names){ answer+=`${name}\n` } } return answer; } //Тестовая команда async function command_test(data){ var answer = data.answer; //console.log('Выбрана точка работы: ', await users[data.id].getMainZone()); return answer; } //Выбрать канал ответов для сообщения function start_answering(id,command,text){ if(!users[id]) users[id] = new Courier({id:id}); if(!users[id].is_waiting){ var command_info = config.commands.get(command)||config.admin_commands.get(command); if(!command_info) { bot.sendMessage( id, config.defaulttext.unknown_command); } else { if(command_info.need_api) messages_wait_Yandex.push({ id : id, text : text, command_info : command_info }); else messages.push({ id : id, text : text, command_info : command_info }); } } else bot.sendMessage( id, config.defaulttext.need_wait); } setTimeout(() => setInterval(() => start_answering(247608317,'/newfreeslots'), 20000), 5000); //Ответ на сообщения не требующие API яндекса messages = []; answer_for_messages(); async function answer_for_messages(){ var message = messages.shift(); while (message) { var id = message.id; var command_info = message.command_info; var answer = ""; var buttons = []; var user_is_admin = (users[id].mode > 1); if(command_info.need_admin&&!user_is_admin) answer = config.defaulttext.need_admin; else { var user_is_auth = users[id].checkAuth(); if(command_info.need_auth&&!user_is_auth) { answer = config.defaulttext.need_auth; // buttons = getButtonsByNames(config.defaulttext.need_auth.buttons,id); } else { answer = command_info.answer || 'no_answer'; // buttons = getButtonsByNames(command_info.buttons,id); if(command_info.function_name){ var data = { name : command_info.function_name, id : id, is_Auth : user_is_auth, is_Admin : user_is_admin, answer : answer, text : message.text } try { users[id].is_waiting = true; answer = await launchFunctionByName(data); } catch (e) { console.log(e); answer = 'Возникла ошибка'; users[id].is_waiting = false; } } } } message = messages.shift(); users[id].is_waiting = false; if(answer != 'no_answer'){ if (answer.length >= 4000) while(answer.length>0){ await bot.sendMessage( id, answer.substring(0,4000), { parse_mode: 'HTML', reply_markup: { inline_keyboard: buttons } }); answer = answer.substring(4000); } else bot.sendMessage( id, answer, { parse_mode: 'HTML', reply_markup: { inline_keyboard: buttons } }); } } setTimeout(answer_for_messages, 100); } var yandex_api = [1,1,1,1,1,1,1,1]; messages_wait_Yandex = []; messages_with_Yandex = []; add_messages_with_Yandex() answer_for_messages_with_Yandex() async function add_messages_with_Yandex(){ while((messages_wait_Yandex.length > 0) && (yandex_api.length > 0)){ var message = messages_wait_Yandex.shift(); var options = yandex_api.shift(); //console.log(options); await messages_with_Yandex.push(message); } setTimeout(add_messages_with_Yandex, 100); } async function answer_for_messages_with_Yandex(){ var message = messages_with_Yandex.shift(); while (message) { var id = message.id; var command_info = message.command_info; var answer = ""; var buttons = []; var user_is_admin = (users[id].mode > 1); if(command_info.need_admin&&!user_is_admin) answer = config.defaulttext.need_admin; else { var user_is_auth = users[id].checkAuth(); if(command_info.need_auth&&!user_is_auth) { answer = config.defaulttext.need_auth; // buttons = getButtonsByNames(config.defaulttext.need_auth.buttons,id); } else { answer = command_info.answer || 'no_answer'; // buttons = getButtonsByNames(command_info.buttons,id); if(command_info.function_name){ var data = { name : command_info.function_name, id : id, is_Auth : user_is_auth, is_Admin : user_is_admin, answer : answer, text : message.text } try { users[id].is_waiting = true; answer = await launchFunctionByName(data); } catch (e) { console.log(e); answer = 'Возникла ошибка'; users[id].is_waiting = false; } } } } message = messages_with_Yandex.shift(); yandex_api.push(1); users[id].is_waiting = false; if(answer != 'no_answer'){ if (answer.length >= 4000) while(answer.length>0){ await bot.sendMessage( id, answer.substring(0,4000), { parse_mode: 'HTML', reply_markup: { inline_keyboard: buttons } }); answer = answer.substring(4000); } else bot.sendMessage( id, answer, { parse_mode: 'HTML', reply_markup: { inline_keyboard: buttons } }); } } setTimeout(answer_for_messages_with_Yandex, 100); } /******************--- databaseConnect ----**************************/ const { Client } = require('pg'); const client = new Client({ connectionString: process.env.DATABASE_URL, ssl: { rejectUnauthorized: false } }) client.connect() .catch(e => { console.error(e); }) .then(()=>{init_database()}); var bd_loaded = false; function init_database(){ (async () => { var create_table = `CREATE TABLE IF NOT EXISTS USERS( ID INT PRIMARY KEY NOT NULL, TOKEN VARCHAR(1000) NOT NULL DEFAULT 'unauthorized', USERNAME VARCHAR(45) NOT NULL DEFAULT 'no_username', PASSWORD VARCHAR(20) NOT NULL DEFAULT 'no_password', MODE INT NOT NULL DEFAULT 0, ZONES TEXT NOT NULL DEFAULT 'no_zones' );`; await client.query(create_table) var load_users = `SELECT * FROM USERS;`; await client.query(load_users, async (err,res) => { var users_ = res.rows; var auth_needed = 0; for await(var user of users_) { if(user.zones === 'no_zones') user.zones = ''; user.zones = user.zones.split(',') users[user.id] = new Courier(user); if(!(await users[user.id].getInfo())) auth_needed++; }/*var i=0; i { console.error(e); setTimeout(init_database, 5000); }); } /******************--- databaseConnect ----**************************/ var update_users = []; const updateUsersClient = new Client({ connectionString: process.env.DATABASE_URL, ssl: { rejectUnauthorized: false } }); updateUsersClient.connect(); setTimeout(updateUsersOnServer, 5000); async function updateUsersOnServer(){ (async () => { var id = update_users.shift(); while(id){ let update = `UPDATE USERS SET TOKEN = '${users[id].token}', USERNAME = '${users[id].username}', PASSWORD = '${users[id].password}', MODE = ${users[id].mode}, ZONES = '${users[id].zones.join(",")}' WHERE ID = ${id};` await updateUsersClient.query(update) id = update_users.shift(); } setTimeout(updateUsersOnServer, 5000); })() .catch(e => { console.error(e); setTimeout(updateUsersOnServer, 5000); }); } var newUsers = []; function saveNewUsers(){ (async () => { var user = newUsers.shift(); while (user){ var add_user = `INSERT INTO USERS(ID, TOKEN, USERNAME, PASSWORD, MODE, ZONES) VALUES(${user.id}, '${user.token}', '${user.username}', '${user.password}', ${user.mode}, '${user.zones.join(",")}') ON CONFLICT (ID) DO UPDATE SET TOKEN = EXCLUDED.TOKEN, USERNAME = EXCLUDED.USERNAME, PASSWORD = EXCLUDED.PASSWORD;`; //console.log('save ',user) await client.query(add_user); user = newUsers.shift(); } setTimeout(saveNewUsers, 5000); })() .catch(e => { console.error(e); }); }