process.env["NTBA_FIX_319"] = 1; // Modules extérieurs var TelegramBot = require('node-telegram-bot-api'); var schedule = require('node-schedule'); // Modules propres var { query, getChanByChatId, createChan, deleteChanByChatId, modifyChan, addGroup, getGroups } = require('./connection-db'); var { getBirthdays, searchGroups, getGroupById, getNewToken } = require('./requests'); // Configurations const config = require('./config'); // Création de variables var bot = new TelegramBot(config.telegram.token, { polling: true }); var schedules = {}; // En cas de redémarrage de l'appli query(`SELECT chatId, schedule FROM channel WHERE schedule <> ""`).then(rep => { rep.forEach(chan => { }) }) // A la connexion, création d'un document Channel dans MongoDB bot.onText(/\/start/, msg => { const chatId = msg.chat.id; return getChanByChatId(chatId).then(chan => { // /start déjà fait... if (chan) return bot.sendMessage(chatId, 'Vous avez déjà fait lancé le bot sur cette conversation. Pour tout réinitialiser, faites /reset.') return createChan({ chatId: chatId, username: '', state: '', token: '', refresh: '', expiration: '', schedule: '' }).then(_ => { const resp = 'Holà, je suis le Happy Botday, je suis là pour vous souhaiter vous rapeller les anniversaires de vos potes !\nPour commencer, il faut que quelqu\'un s\'identifie : /connect'; bot.sendMessage(chatId, resp); }) }) }); // Suppression de l'objet créé lors du /start bot.onText(/\/reset/, msg => { const chatId = msg.chat.id; // Suppression de l'objet if (schedule[chatId]) { schedule[chatId].cancel(); delete (schedule[chatId]); } return deleteChanByChatId(chatId).then(_ => { const resp = 'Toutes vos paramètres ont été supprimés. Pour recommencer à m\'utiliser, faites /start.'; bot.sendMessage(chatId, resp); }) }) // Si rien n'a été fait avant, propose un lien de connexion à l'OAuth2 de VR bot.onText(/\/connect/, (msg, _) => { const chatId = msg.chat.id; getChanByChatId(chatId).then(chan => { // start pas encore fait if (!chan) return bot.sendMessage(chatId, 'Avant de vous authentifier, faites /start.'); // /connect déjà fait, renvoie vers le lien précédent if (chan.state.length !== 0) return bot.sendMessage(chatId, `@${chan.username} a déjà fait une demande. Vous pouvez annuler la demande via /cancel ou @${chan.username} peut se connecter depuis ce lien :\n${config.website.protocol}://${config.website.hostname}/?state=${chan.state}.`) // authentification déjà faite if (chan.token.length !== 0) return bot.sendMessage(chatId, `Une connexion a déjà été faite par @${chan.username}. Pour la réinitialiser, faites /disconnect`); // dans le reste des cas, création d'un lien pour l'authentification et enregistrement dans l'objet pour être sur chan.state = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); chan.username = msg.from.username; modifyChan(chan).then(chan => { const resp = `Pour vous identifier, connectez-vous via l\'OAuth2 de ViaRézo depuis ce lien :\n${config.website.protocol}://${config.website.hostname}/?state=${chan.state}`; return bot.sendMessage(chatId, resp); }) }) }); // Annulation de la demande de connexion bot.onText(/\/cancel/, msg => { const chatId = msg.chat.id; getChanByChatId(chatId).then(chan => { // ne peut pas annuler une demande déjà acceptée if (chan.token.length !== 0) return bot.sendMessage(chatId, 'La demande d\'athentification a déjà été acceptée, elle ne peut pas être annulée. Pour se déconnecter, faites /disconnect.') chan.username = ''; chan.state = ''; modifyChan(chan).then(_ => bot.sendMessage(chatId, 'La demande d\'authentification a été annulée. Vous pouvez vous reconnecter avec /connect.')) }) }) // Permet de déconnecter l'utilisateur qui s'est authentifié sur l'OAuth2 bot.onText(/\/disconnect/, msg => { const chatId = msg.chat.id; getChanByChatId(chatId).then(chan => { // s'il n'y a pas de token, personne ne s'est connecté if (chan.token.length === 0) return bot.sendMessage(chatId, 'Personne ne s\'est connecté...'); // suppression de tous les paramètres de connexion et save() username = chan.username; chan.token = ''; chan.expiration = Date.now(0); chan.username = ''; modifyChan(chan).then(_ => bot.sendMessage(chatId, `@${username} n'est plus connecté à l'OAuth2.`)); }) }); // Affiche tous les anniversaires de LinkCS bot.onText(/\/allbirthdays/, msg => { const chatId = msg.chat.id; // recherche du token du chan actuel getChanByChatId(chatId).then(chan => { return getBirthdays(chan.token) }).then(users => { var msg = '**Joyeux anniversaire** à :\n' users.forEach(user => { msg += `${user.name}\n` }); bot.sendMessage(chatId, msg, { parse_mode: 'Markdown' }); }) }); // Affiche les anniversaires demandés bot.onText(/\/birthdays/, msg => { const chatId = msg.chat.id; // recherche du token du chan actuel getChanByChatId(chatId).then(chan => { return Promise.all([ getBirthdays(chan.token), getGroups(chatId), ]) }).then(([users, groups]) => { // récupère que les personnes du jour qui font partie des groupes ciblés const newUsers = users.filter(user => user.asso.some(asso => groups.indexOf(asso) !== -1)); if (newUsers.length === 0) return bot.sendMessage(chatId, 'Pas d\'anniversaire à souhaiter aujourd\'hui.') var msg = '**Joyeux anniversaire** à :\n' newUsers.forEach(user => { msg += `${user.name}\n` }); return bot.sendMessage(chatId, msg, { parse_mode: 'Markdown' }); }) }); // recherche des groupes et renvoie le résultat avec leurs ID pour les rajouter bot.onText(/\/search (.+)/, (msg, match) => { const chatId = msg.chat.id; const research = match[1]; getChanByChatId(chatId).then(chan => { return searchGroups(chan.token, research) }).then(groups => { if (groups.length == 0) return bot.sendMessage(chatId, 'Pas de groupe à ce nom...'); var resp = 'Voici les différentes associations. Faites /add XXXX pour ajouter les anniversaires de ses membres. '; // LinkCS limite à 20 résultats if (groups.length == 20) resp += 'La recherche est limitée à 20 choix.' resp += '\n\n' groups.forEach(group => { resp += `${group.name} : \`/add ${group.id}\`\nhttps://linkcs.fr/association/${group.code} \n\n` }) bot.sendMessage(chatId, resp, { parse_mode: 'Markdown' }); }); }) // Ajout d'un groupe dans la liste des groupes bot.onText(/\/add (.+)/, (msg, match) => { const chatId = msg.chat.id; getChanByChatId(chatId).then(chan => { const id = parseInt(match[1].split(' ')[0]); return Promise.all([ getGroupById(chan.token, id), getGroups(chatId), id ]); }).then(([group, groups, id]) => { // si pas de groupe trouvé if (!group) return bot.sendMessage(chatId, 'Pas de groupe trouvé ayant cette ID'); // si le groupe y est déjà if (groups.indexOf(id) !== -1) return bot.sendMessage(chatId, 'Ce groupe est déjà est dans votre liste d\'anniversaire.'); // sinon on le rajoute return addGroup(chatId, id).then(_ => { bot.sendMessage(chatId, `Ajout du groupe \`${group}\` à la liste des anniversaires.`, { parse_mode: 'Markdown' }); }) }) }) // Ajout du temps de schedule bot.onText(/\/schedule (.+)/, (msg, match) => { const chatId = msg.chat.id; const time = match[1]; if (!RegExp('^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$').test(time)) return bot.sendMessage(chatId, 'Le temps entré n\'est pas au format hh:mm'); const hour = parseInt(time.split(':')[0]); const minute = parseInt(time.split(':')[1]); getChanByChatId(chatId).then(chan => { if (!chan) return bot.sendMessage(chatId, 'Pas de compte enregistré, faites /start pour commencer'); chan.schedule = time; return Promise.all([ modifyChan(chan), getGroups(chatId) ]) }).then(([chan, groups]) => { schedules[chan.chatId] = schedule.scheduleJob({ hour: hour, minute: minute }, function () { return getNewToken(chan).then(chan => { return getBirthdays(chan.token) }).then(users => { // récupère que les personnes du jour qui font partie des groupes ciblés const newUsers = users.filter(user => user.asso.some(asso => groups.indexOf(asso) !== -1)); if (newUsers.length === 0) return var msg = '**Joyeux anniversaire** à :\n' newUsers.forEach(user => { msg += `${user.name}\n` }); return bot.sendMessage(chan.chatId, msg, { parse_mode: 'Markdown' }); }) }); bot.sendMessage(chatId, `Votre rappel est configuré pour tous les jours à ${time}`); }) }) // J'étais bien obligé (en vrai c'est pour tester) bot.onText(/\/nikmarine/, msg => { const chatId = msg.chat.id; bot.sendMessage(chatId, 'Nik bien Marine'); console.log(schedules); }) module.exports = bot;