17 Commits 427ea76845 ... 34bfd57e8c

Autore SHA1 Messaggio Data
  edmilson-dk 34bfd57e8c feat: added method for reset column active configs chat 3 anni fa
  edmilson-dk 8cf03925d7 feat: added method for reset column active configs chat 3 anni fa
  edmilson-dk 3a11c8de2d feat: added method for reset column active configs chat 3 anni fa
  edmilson-dk 1ce4be0edd feat: created news methods in chat repository 3 anni fa
  edmilson-dk 8dfba4bcdc feat: added new column in chats table 3 anni fa
  edmilson-dk 6daa9913d3 refactor: removed comments 3 anni fa
  edmilson-dk 35a1799126 refactor: removed console.log 3 anni fa
  edmilson-dk e4e082f01e feat: finished view chat commands 3 anni fa
  edmilson-dk a27d64061a refactor: renamed variables 3 anni fa
  edmilson-dk 5fa24817ff refactor: renamed variables 3 anni fa
  edmilson-dk a4e55cec32 feat: added drop all posts method 3 anni fa
  edmilson-dk ff152436c5 feat: added get mid night utc method 3 anni fa
  edmilson-dk 52c04371ab feat: added about and help actions 3 anni fa
  edmilson-dk f99a5d91bf feat: added about and helper messages 3 anni fa
  edmilson-dk a4a3151335 refactor: removed unused messages 3 anni fa
  edmilson-dk 863d3cbaed refactor: removed comments 3 anni fa
  edmilson-dk f48a5080a3 refactor: added other tag in send message 3 anni fa

+ 28 - 4
src/actions/setup_feed_actions.js

@@ -1,11 +1,11 @@
 const { home } = require('../messages/commands')
-const { start_bot_keyboard, go_back_btn, clicked_chat } = require('../messages/inline_keyboard')
+const { start_bot_keyboard, go_back_btn } = require('../messages/inline_keyboard')
 const { getChatId, getUserId } = require('../helpers/bot_helpers')
 const { homeMarkup } = require('../markups');
 const ChatRepository = require('../infra/repositories/chat_repository');
 const { listChats } = require('../helpers/features_helpers');
 
-const { manager_feeds, add_super_chat } = start_bot_keyboard;
+const { manager_feeds, add_super_chat, about, help } = start_bot_keyboard;
 
 const chatRepository = new ChatRepository();
 
@@ -16,12 +16,36 @@ module.exports = ({ bot }) => {
     ctx.telegram.sendMessage(getChatId(ctx), home.text, homeMarkup);
   }) 
 
+  function aboutAndHelpMessage(ctx, message) {
+    ctx.answerCbQuery();
+    ctx.deleteMessage();
+    ctx.telegram.sendMessage(getChatId(ctx), message, {
+      reply_markup: {
+        inline_keyboard: [
+          [{ text: 'Acessar meu grupo', url: process.env.BOT_CHAT }],
+          [{ text: go_back_btn.text, callback_data: 'start_bot' }]
+        ]
+      },
+      parse_mode: 'HTML'
+    })
+  }
+
+  bot.action('about', ctx => {
+    aboutAndHelpMessage(ctx, about.message);
+  })
+
+  bot.action('help', ctx => {
+    aboutAndHelpMessage(ctx, help.message);
+  })
+
   bot.action('manager_feeds', async ctx => {
     ctx.answerCbQuery();
     ctx.deleteMessage();
    
-    const userID = getUserId(ctx, 'action');
-    const chatsList = await listChats(chatRepository, userID);
+    const userId = getUserId(ctx, 'action');
+    await chatRepository.setNotActiveConfigChats(String(userId));
+    
+    const chatsList = await listChats(chatRepository, userId);
     
     const defaultMarkup = [
       [{ text: manager_feeds.action_update_list, callback_data: 'manager_feeds'},

+ 77 - 57
src/commands/index.js

@@ -1,5 +1,5 @@
 const { start_service, home, cmd_error, not_member_admin, view_chat, add_feed, remove_feed, active_feed } = require('../messages/commands');
-const { homeMarkup, timezonesMarkup, isNotMemberOrAdminMarkup, goBackManagerFeedsMarkup } = require('../markups');
+const { homeMarkup, isNotMemberOrAdminMarkup, goBackManagerFeedsMarkup } = require('../markups');
 const { getChatId, isBotAdmin, isAdmin, isStillMemberAndAdmin, removeCommand } = require('../helpers/bot_helpers');
 const { asyncFilter, isHashtagsValid, removeSpacesInArray, removeNotHashtagsInArray, listFeeds } = require('../helpers/features_helpers');
 
@@ -24,26 +24,36 @@ module.exports = bot => {
 
   bot.start(async ctx => {
     const { type } = await ctx.getChat();
-    const userID = ctx.from.id;
+    const userId = ctx.from.id;
     const username = ctx.from.username;
 
     if (type === 'private') {
-      await userRepository.add({ user_id: userID, username });
+      await chatRepository.setNotActiveConfigChats(String(userId));
+      
+      const user = new User(userId, username);
+      await userRepository.add(user.getValue());
 
       ctx.telegram.sendMessage(getChatId(ctx), home.text, homeMarkup);
+      return;
     } else {
       ctx.telegram.sendMessage(getChatId(ctx), 'Olá!'); 
+      return;
     }
-    return;
   })
 
- bot.command('start_service', async ctx => {
-    const { type, id: chatID, title } = await ctx.getChat();
-    const userID = ctx.from.id;
-    const isUserAdmin = await isAdmin(userID, ctx);
-    const isUserValid = await userRepository.existsUser(String(userID));
-    const chat = new Chat(chatID, title, userID);
-    
+  bot.command('start_service', async ctxStartServiceCmd => startServiceCommand(ctxStartServiceCmd));
+  bot.command('view_chat', async ctxViewChatCmd => viewChatCommand(ctxViewChatCmd));
+  bot.command('add', async ctxAddCmd => await addFeedCommand(ctxAddCmd, finishedViewChatCmd));
+  bot.command('remove', async ctxRemoveCmd => await removeFeedCommand(ctxRemoveCmd, finishedViewChatCmd));
+  bot.command('active', async ctxActiveCmd => await activeChatCommand(ctxActiveCmd, finishedViewChatCmd));
+
+  async function startServiceCommand(ctx) {
+    const { type, id: chatId, title } = await ctx.getChat();
+    const userId = ctx.from.id;
+    const isUserAdmin = await isAdmin(userId, ctx);
+    const isUserValid = await userRepository.existsUser(String(userId));
+    const chat = new Chat(chatId, title, userId);
+      
     if (type !== 'private') {
       if (!isUserValid) {
         ctx.reply(start_service.invalid_user);
@@ -57,19 +67,19 @@ module.exports = bot => {
         ctx.reply(start_service.not_admin);
         return;
       }
-      if ((await chatRepository.existsChat(chatID))) {
+      if ((await chatRepository.existsChat(chatId))) {
         ctx.reply(start_service.chat_alredy_exists);
         return;
       } 
-
+  
       await chatRepository.addChat(chat.getValues());
       ctx.reply(start_service.success);  
-
+  
       return;
     }
-
+  
     return;
-  })
+  }
 
   bot.on('channel_post', async ctx => {
     const text = ctx.update.channel_post.text;
@@ -81,14 +91,14 @@ module.exports = bot => {
       return exists;
     });
 
-    const userID = userActiveSessionId.length > 0 
+    const userId = userActiveSessionId.length > 0 
       ? userActiveSessionId[0].user.id
       : undefined;
       
-    const { id: chatID, title } = await ctx.getChat();
+    const { id: chatId, title } = await ctx.getChat();
     let chat = null;
     
-    if (userID) chat = new Chat(chatID, title, userID);
+    if (userId) chat = new Chat(chatId, title, userId);
 
     if (text === '/start_service') {
       if ((await isBotAdmin(ctx)) && chat) {
@@ -97,7 +107,7 @@ module.exports = bot => {
 
         return;
       }
-      if ((await chatRepository.existsChat(chatID))) {
+      if ((await chatRepository.existsChat(chatId))) {
         ctx.reply(start_service.chat_alredy_exists);
         return;
       } 
@@ -106,45 +116,44 @@ module.exports = bot => {
     return;
   })
 
-  bot.command('view_chat', async ctx => {
-    const chatTitle = ctx.message.text.replace('/view_chat', '').trim();
+  async function finishedViewChatCmd(ctx, chatId, reset = false) {
+    const feedsList = await listFeeds(feedRepository, chatId);
+    const userId = String(ctx.message.from.id);
+
+    return [
+      getChatId(ctx), 
+      `${view_chat.text}\n\n${feedsList}`, 
+      goBackManagerFeedsMarkup
+    ];
+  }
+
+  async function viewChatCommand(ctx) {
+    const chatTitle = removeCommand(ctx.message.text,'/view_chat');
    
     if (!chatTitle) {
       ctx.reply(cmd_error.text);
       return;
     }
 
-    const userID = ctx.message.from.id;
-    const { id: chatID } = await chatRepository.getOneChatByTitle(String(userID), chatTitle);
-    
-    const getMessage = async () => {
-      const feedsList = await listFeeds(feedRepository, chatID);
-      
-      return [
-        getChatId(ctx), 
-        `${view_chat.text}\n\n${feedsList}`, 
-        goBackManagerFeedsMarkup
-      ];
-    }
+    const userId = String(ctx.message.from.id);
+    const { id: chatId } = await chatRepository.getOneChatByTitle(String(userId), chatTitle);
 
-    if ((await isStillMemberAndAdmin(chatID, userID, { bot }))) {   
-      
-      const message = await getMessage();
-      ctx.telegram.sendMessage(...message);
+    if ((await isStillMemberAndAdmin(chatId, userId, { bot }))) {   
+      await chatRepository.setActiveConfigChat(chatId, userId, true);
 
-      bot.command('add', async ctx => await addFeedCommand(ctx, chatID, getMessage));
-      bot.command('remove', async ctx => await removeFeedCommand(ctx, chatID, getMessage));
-      bot.command('active', async ctx => await activeChatCommand(ctx, chatID, getMessage));
+      const message = await finishedViewChatCmd(ctx, chatId);
+      ctx.telegram.sendMessage(...message);
+      return;
 
     } else {
-      ctx.telegram.sendMessage(chatID, not_member_admin.text, isNotMemberOrAdminMarkup);
-      await chatRepository.dropChat(userID, chatID);
+      ctx.telegram.sendMessage(chatId, not_member_admin.text, isNotMemberOrAdminMarkup);
+      await chatRepository.dropChat(userId, chatId);
 
       return;
     }
-  })
+  }
 
-  async function addFeedCommand(ctx, chat_id, getMessage) {
+  async function addFeedCommand(ctx, finishedViewChatCmd) {
     let data = removeCommand(ctx.message.text, '/add').split(' ');
     data = removeSpacesInArray(data);
 
@@ -162,19 +171,22 @@ module.exports = bot => {
     } 
     
     if ((await rssParser.rssIsValid(rssURL))) {
+      const userId = String(ctx.message.from.id);
+
       const title = await rssParser.getFeedTitle(rssURL);
       const hashtags_formatted = hashtags.join(' ');
-      
-      if ((await feedRepository.existsFeedByTitle(title, chat_id))) {
+      const chatId = await chatRepository.getIsActiveConfigChat(userId);
+     
+      if ((await feedRepository.existsFeedByTitle(title, chatId))) {
         ctx.reply(add_feed.alredy_exists);
         return;
       }
 
-      const feed = new Feed(rssURL, hashtags_formatted, title, chat_id);
+      const feed = new Feed(rssURL, hashtags_formatted, title, chatId);
       await feedRepository.addFeed(feed.getValue());
 
       ctx.reply(add_feed.success);
-      const message = await getMessage();
+      const message = await finishedViewChatCmd(ctx, chatId);
       ctx.telegram.sendMessage(...message);
 
       return;
@@ -184,38 +196,46 @@ module.exports = bot => {
     }
   }
 
-  async function removeFeedCommand(ctx, chat_id, getMessage) {
+  async function removeFeedCommand(ctx, finishedViewChatCmd) {
     const feedTitle = removeCommand(ctx.message.text, '/remove');
 
     if (!feedTitle) {
       ctx.telegram.sendMessage(getChatId(ctx), remove_feed.cmd_error, { parse_mode: 'HTML'});
       return;
     }
-    if (!(await feedRepository.existsFeedByTitle(feedTitle, chat_id))) {
+    if (!(await feedRepository.existsFeedByTitle(feedTitle, chatId))) {
       ctx.telegram.sendMessage(getChatId(ctx), remove_feed.invalid_title, { parse_mode: 'HTML'});
       return;
     }
 
-    await feedRepository.dropFeed(feedTitle, chat_id);
+    const userId = String(ctx.message.from.id);
+    const chatId = await chatRepository.getIsActiveConfigChat(userId);
+    await feedRepository.dropFeed(feedTitle, chatId);
 
     ctx.reply(remove_feed.success);
-    const message = await getMessage();
+    const message = await finishedViewChatCmd(ctx, chatId);
     ctx.telegram.sendMessage(...message);
 
     return;
   }
 
-  async function activeChatCommand(ctx, chat_id, getMessage) {
-    if (!(await feedRepository.containChat(chat_id))) {
+  async function activeChatCommand(ctx, finishedViewChatCmd) {
+    const userId = String(ctx.message.from.id);
+    const chatId = await chatRepository.getIsActiveConfigChat(userId);
+
+    if (!(await feedRepository.containChat(chatId))) {
       ctx.reply(active_feed.error);
       return;
     }
 
-    await chatRepository.updateActiveChat(true, chat_id);
+    await chatRepository.updateActiveChat(true, chatId);
+    await chatRepository.setActiveConfigChat(chatId, userId, false);
 
     ctx.reply(active_feed.success);
-    const message = await getMessage();
+    const message = await finishedViewChatCmd(ctx, chatId);
     ctx.telegram.sendMessage(...message);
+
+    return;
   }
 
   setupFeedActions({ bot });

+ 16 - 7
src/core/index.js

@@ -9,11 +9,10 @@ const feedRepository = new FeedRepository();
 const postRepository = new PostRepository();
 
 const rssParser = new RssParser();
+const time = new Date;
 
-async function getChatsData(oneChatId) {
-  const chatsIds = oneChatId 
-    ? oneChatId
-    : await chatRepository.getAllChatsIdActive();
+async function getChatsData() {
+  const chatsIds = await chatRepository.getAllChatsIdActive();
 
   if (chatsIds.length === 0) return chatsIds;
 
@@ -53,28 +52,38 @@ function sendMessages({ feed, data, bot }) {
         bot.telegram.sendMessage(feed.chat_id, 
           `<strong>Novo post ✅</strong><code>\n\n${item.title}</code>\n\n<a href='${item.link}'>Ler post completo ➡️</a>\n\nDe: <i>${feed.title}</i>\n\n${feed.hashtags}`, 
           { parse_mode: 'HTML'})
-      }, index * 6000);
+      }, index * 60000);
     }
   });
 }
 
+function isUTCMidNight() {
+  const utcHours = time.getUTCHours() === 00;
+  const utcMinutes = time.getUTCMinutes() === 00;
+  const utcSeconds = time.getUTCSeconds() <= 58;
+
+  return (utcHours && utcMinutes && utcSeconds) ? true : false;
+}
+
 async function start(bot) {
   const data = await getChatsData();
 
+  if (isUTCMidNight()) await postRepository.dropAllPosts();
   if (data.length === 0) return data;
   
   data.forEach(async feed => {
     const { count } = await postRepository.getPostsCount({ chat_id: feed.chat_id});
 
     feed.data.splice(0, count);
-    const items = feed.data.slice(0, 1);
+    const items = feed.data.slice(0, 10);
+
     sendMessages({ feed, data: items, bot });
   });
 }
 
 async function main(bot) {
   await start(bot);
-  setInterval(async () => await start(bot), 8000);
+  setInterval(async () => await start(bot), 600000);
 }
 
 module.exports = main;

+ 1 - 3
src/drivers/rss-parser/index.js

@@ -9,8 +9,7 @@ class RssParser {
 
   async getFeeds(rssURL) {
     try {
-      const feeds = await parser.parseURL(rssURL);
-      
+      const feeds = await parser.parseURL(rssURL);   
       return feeds.items;
     } catch (err) {
       return [];
@@ -22,7 +21,6 @@ class RssParser {
       await parser.parseURL(rssURL);
       return true;
     } catch (err) {
-      console.log(err)
       return false;
     }
   }

+ 2 - 2
src/helpers/features_helpers.js

@@ -34,7 +34,7 @@ async function listFeeds(feedRepository, chatID) {
   let feedsList = '<strong>Feeds 📌</strong>\n';
   if (feeds && feeds.length > 0) {
     feeds.forEach(feed => {
-      feedsList += `\n🔹 <i>${feed.title}</i>\n`
+      feedsList += `\n🔹 <code>${feed.title}</code>\n`
     })
   }
 
@@ -47,7 +47,7 @@ async function listChats(chatRepository, userID) {
   let chatsList = '<strong>Chats 📌</strong>\n';
   if (chats && chats.length > 0) {
     chats.forEach(chat => {
-      chatsList += `\n🔸 <i>${chat.title}</i>\n`;
+      chatsList += `\n🔸 <code>${chat.title}</code>\n`;
     })
   }
 

+ 2 - 1
src/index.js

@@ -1,9 +1,10 @@
 require('dotenv').config();
 
 const { Telegraf } = require('telegraf');
-const init = require('./core');
+
 const bot = new Telegraf(process.env.BOT_TOKEN);
 
+const init = require('./core');
 const commands = require('./commands');
 
 commands(bot);

+ 2 - 1
src/infra/database/query-builder/postgres/knex/migrations/20210227120048_chat_table.js

@@ -4,7 +4,8 @@ exports.up = function(knex) {
       return knex.schema.createTable('chats', table => {
         table.string('id', 60).notNullable().unique();
         table.string('title', 100).notNullable();
-        table.boolean('active').defaultTo(false);
+        table.boolean('is_active').defaultTo(false);
+        table.boolean('is_active_configuration').defaultTo(false);
 
         // relation to user table
         table.string('user_id')

+ 25 - 3
src/infra/repositories/chat_repository.js

@@ -71,16 +71,38 @@ class ChatRepository {
   async getAllChatsIdActive() {
     const rows = await knex('chats')
       .select('id')
-      .where({ active: true })
+      .where({ is_active: true })
 
     return rows;
   }
 
-  async updateActiveChat(active, chat_id) {
+  async updateActiveChat(is_active, chat_id) {
     await knex('chats')
       .where({ id: chat_id })
-      .update({ active })
+      .update({ is_active })
   }
+
+  async getIsActiveConfigChat(user_id) {
+    const row = await knex('chats')
+      .where({ is_active_configuration: true, user_id })
+      .select('id')
+
+    return row[0].id;
+  }
+
+  async setNotActiveConfigChats(user_id) {
+    await knex('chats')
+      .where({ user_id, is_active_configuration: true })
+      .update({ is_active_configuration: false })
+  }
+
+  async setActiveConfigChat(chat_id, user_id, state) {
+    await knex('chats')
+      .where({ id: chat_id, user_id })
+      .update({ is_active_configuration: state })
+  }
+
+  
 }
 
 module.exports = ChatRepository;

+ 6 - 0
src/infra/repositories/post_repository.js

@@ -20,6 +20,12 @@ class PostRepository {
 
     return count[0];
   }
+
+
+  async dropAllPosts() {
+    await knex('posts')
+      .del();
+  }
 }
 
 module.exports = PostRepository;

+ 0 - 0
src/messages/commands.json


Some files were not shown because too many files changed in this diff