44 次代码提交 28107a7a1e ... 427ea76845

作者 SHA1 备注 提交日期
  edmilson-dk 427ea76845 feat: finished core methods 3 年之前
  edmilson-dk c4b3925d8c feat: created post repositorys 3 年之前
  edmilson-dk b2bd4410a8 feat: created new database column 3 年之前
  edmilson-dk 22f40c6a12 refactor: removed unused messages 3 年之前
  edmilson-dk 5d6b335394 refactor: removed unused chat repository methods 3 年之前
  edmilson-dk 408804d928 feat: added core method init 3 年之前
  edmilson-dk 050d2a49ca refactor: removed unused chat repository methods 3 年之前
  edmilson-dk 2d197925ca refactor: removd unused columns 3 年之前
  edmilson-dk 7cfd9d0cc0 refactor: removd unused columns 3 年之前
  edmilson-dk 07371bbe3e refactor: removed unused functions 3 年之前
  edmilson-dk 1a96574775 feat: finished function for get rss feeds 3 年之前
  edmilson-dk 256dc524b7 feat: removed unused fields 3 年之前
  edmilson-dk ba65a9e00f feat: removed unused fields 3 年之前
  edmilson-dk 072c907f2f feat: removed unnecessary commands 3 年之前
  edmilson-dk 376da709a8 feat: added news messages 3 年之前
  edmilson-dk 08452d9ab5 feat: created method for validate if table feeds contain one chat id or more 3 年之前
  edmilson-dk 4d3d984652 feat: created new method for update chats with active state 3 年之前
  edmilson-dk ad18974294 feat: added new column in chats table 3 年之前
  edmilson-dk 072e490006 feat: removed console 3 年之前
  edmilson-dk c81da9ca72 feat: finished method for get feeds 3 年之前
  edmilson-dk 7fc2aee57f feat: added initial implementation of set active command 3 年之前
  edmilson-dk 77b2ef3d25 refactor: removed console.log 3 年之前
  edmilson-dk e79e3783e3 feat: created set times messages 3 年之前
  edmilson-dk 9ef2d48fc2 feat: added set times messages for error return and success 3 年之前
  edmilson-dk 3d6280c7a3 refactor: removed unused messages to commands 3 年之前
  edmilson-dk 081de17e4d refactor: renamed tables 3 年之前
  edmilson-dk 684dbcea35 refactor: renamed the feeds table name to feeds 3 年之前
  edmilson-dk a90c3634e9 refactor: renamed the chat table name to chats 3 年之前
  edmilson-dk 87cae31d97 refactor: renamed the user table name to users 3 年之前
  edmilson-dk 2a8a9cd8db refactor: removed unused help function 3 年之前
  edmilson-dk 68bb279876 feat: removed unnecessary entity fields 3 年之前
  edmilson-dk d6eabe5ef1 feat: created set time command 3 年之前
  edmilson-dk 73f36d653c feat: writed news messages 4 年之前
  edmilson-dk 3c6f5c1165 feat: created method for validate hours and interval 4 年之前
  edmilson-dk faa3e19781 feat: created format time helper 4 年之前
  edmilson-dk 3e5054eb1f feat: created remover command in message helper 4 年之前
  edmilson-dk b1eb424901 feat: created format time helper 4 年之前
  edmilson-dk d55f89ff20 feat: created new message 4 年之前
  edmilson-dk e0022fdd45 feat: created new command 4 年之前
  edmilson-dk 9bd5283cf8 feat: added new module 4 年之前
  edmilson-dk c19258a6bb fix: fix message 4 年之前
  edmilson-dk b26c3c35ee feat: created method for get ids of all users 4 年之前
  edmilson-dk 0f5a0dad9d feat: added method for get ids of all chats 4 年之前
  edmilson-dk a331ed61a2 feat: created new method in rss parser, for get feeds of one chat 4 年之前

+ 1 - 0
package.json

@@ -10,6 +10,7 @@
     "start": "node src/index.js"
   },
   "dependencies": {
+    "cron": "^1.8.2",
     "dotenv": "^8.2.0",
     "knex": "^0.21.18",
     "pg": "^8.5.1",

+ 1 - 1
src/actions/setup_feed_actions.js

@@ -21,7 +21,7 @@ module.exports = ({ bot }) => {
     ctx.deleteMessage();
    
     const userID = getUserId(ctx, 'action');
-    chatsList = await listChats(chatRepository, userID);
+    const chatsList = await listChats(chatRepository, userID);
     
     const defaultMarkup = [
       [{ text: manager_feeds.action_update_list, callback_data: 'manager_feeds'},

+ 32 - 39
src/commands/index.js

@@ -1,12 +1,6 @@
-const { 
-  start_bot, start_service, 
-  home, cmd_error, not_member_admin, 
-  view_chat, add_feed, remove_feed
-} = require('../messages/commands');
-const  { go_back_btn } = require('../messages/inline_keyboard');
-
+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 { getChatId, isBotAdmin, isAdmin, isStillMemberAndAdmin } = require('../helpers/bot_helpers');
+const { getChatId, isBotAdmin, isAdmin, isStillMemberAndAdmin, removeCommand } = require('../helpers/bot_helpers');
 const { asyncFilter, isHashtagsValid, removeSpacesInArray, removeNotHashtagsInArray, listFeeds } = require('../helpers/features_helpers');
 
 const User = require('../domain/User');
@@ -30,32 +24,16 @@ module.exports = bot => {
 
   bot.start(async ctx => {
     const { type } = await ctx.getChat();
-    const userID = String(ctx.from.id);
+    const userID = ctx.from.id;
+    const username = ctx.from.username;
 
     if (type === 'private') {
-      !(await userRepository.existsUser(userID))
-        ? ctx.telegram.sendMessage(getChatId(ctx), start_bot.text, timezonesMarkup)
-        : ctx.telegram.sendMessage(getChatId(ctx), home.text, homeMarkup);
+      await userRepository.add({ user_id: userID, username });
+
+      ctx.telegram.sendMessage(getChatId(ctx), home.text, homeMarkup);
     } else {
       ctx.telegram.sendMessage(getChatId(ctx), 'Olá!'); 
     }
-
-    return;
-  })
-
-  bot.command('register', async ctx => {
-    const [, timezone] = ctx.message.text.split(' ');
-
-    if (!timezone) {
-      ctx.reply(cmd_error.text);
-      return;
-    }
-
-    const user = new User(ctx.from.id, ctx.from.username, timezone);
-    await userRepository.add(user.getValue());
-    
-    ctx.telegram.sendMessage(getChatId(ctx), home.text, homeMarkup);
-
     return;
   })
 
@@ -137,7 +115,7 @@ module.exports = bot => {
     }
 
     const userID = ctx.message.from.id;
-    const { id: chatID, title } = await chatRepository.getOneChatByTitle(String(userID), chatTitle);
+    const { id: chatID } = await chatRepository.getOneChatByTitle(String(userID), chatTitle);
     
     const getMessage = async () => {
       const feedsList = await listFeeds(feedRepository, chatID);
@@ -156,6 +134,7 @@ module.exports = bot => {
 
       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));
 
     } else {
       ctx.telegram.sendMessage(chatID, not_member_admin.text, isNotMemberOrAdminMarkup);
@@ -166,12 +145,17 @@ module.exports = bot => {
   })
 
   async function addFeedCommand(ctx, chat_id, getMessage) {
-    let data = ctx.message.text.replace('/add', '').trim().split(' ');
+    let data = removeCommand(ctx.message.text, '/add').split(' ');
     data = removeSpacesInArray(data);
 
     const rssURL = data.slice(0, 1).toString();
     const hashtags = removeNotHashtagsInArray(data);
 
+    if (hashtags.length > 3) {
+      ctx.telegram.sendMessage(getChatId(ctx), add_feed.max_hashtags);
+      return;
+    }
+
     if (!isHashtagsValid(hashtags)) {
       ctx.telegram.sendMessage(getChatId(ctx), add_feed.cmd_error, { parse_mode: 'HTML'});
       return;
@@ -186,12 +170,8 @@ module.exports = bot => {
         return;
       }
 
-      await feedRepository.addFeed({ 
-        rss_url: rssURL,
-        hashtag: hashtags_formatted,
-        title,
-        chat_id
-      });
+      const feed = new Feed(rssURL, hashtags_formatted, title, chat_id);
+      await feedRepository.addFeed(feed.getValue());
 
       ctx.reply(add_feed.success);
       const message = await getMessage();
@@ -205,7 +185,7 @@ module.exports = bot => {
   }
 
   async function removeFeedCommand(ctx, chat_id, getMessage) {
-    const feedTitle = ctx.message.text.replace('/remove', '').trim();
+    const feedTitle = removeCommand(ctx.message.text, '/remove');
 
     if (!feedTitle) {
       ctx.telegram.sendMessage(getChatId(ctx), remove_feed.cmd_error, { parse_mode: 'HTML'});
@@ -225,5 +205,18 @@ module.exports = bot => {
     return;
   }
 
-  setupFeedActions({bot});
+  async function activeChatCommand(ctx, chat_id, getMessage) {
+    if (!(await feedRepository.containChat(chat_id))) {
+      ctx.reply(active_feed.error);
+      return;
+    }
+
+    await chatRepository.updateActiveChat(true, chat_id);
+
+    ctx.reply(active_feed.success);
+    const message = await getMessage();
+    ctx.telegram.sendMessage(...message);
+  }
+
+  setupFeedActions({ bot });
 }

+ 80 - 0
src/core/index.js

@@ -0,0 +1,80 @@
+const RssParser = require('../drivers/rss-parser');
+
+const ChatRepository = require('../infra/repositories/chat_repository');
+const FeedRepository = require('../infra/repositories/feed_repository');
+const PostRepository = require('../infra/repositories/post_repository');
+
+const chatRepository = new ChatRepository();
+const feedRepository = new FeedRepository();
+const postRepository = new PostRepository();
+
+const rssParser = new RssParser();
+
+async function getChatsData(oneChatId) {
+  const chatsIds = oneChatId 
+    ? oneChatId
+    : await chatRepository.getAllChatsIdActive();
+
+  if (chatsIds.length === 0) return chatsIds;
+
+  const data = [];
+
+  await Promise.all(chatsIds.map(async chat => {
+    const items = await feedRepository.getFeeds(chat.id);
+    data.push(...items);
+
+    return items;
+  }))
+
+  async function fetchData(feed) {
+    const items = await rssParser.getFeeds(feed.rss_url);
+    return { data: items, chat_id: feed.chat_id, title: feed.title, hashtags: feed.hashtag };
+  }
+  
+  const items = data.map(feed => {
+    return new Promise((resolve) => {
+      setTimeout(async () => {
+        return resolve(await fetchData(feed));
+      }, 5000)});
+    })
+  
+  const feeds = await Promise.all(items);
+  return feeds;
+}
+
+function sendMessages({ feed, data, bot }) {
+  data.forEach(async (item, index) => {
+    const defaultObject = { title: item.title, chat_id: feed.chat_id };
+    
+    if (!(await postRepository.existsPost(defaultObject))) {
+      await postRepository.addPost(defaultObject);
+      
+      setTimeout(() => {
+        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);
+    }
+  });
+}
+
+async function start(bot) {
+  const data = await getChatsData();
+
+  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);
+    sendMessages({ feed, data: items, bot });
+  });
+}
+
+async function main(bot) {
+  await start(bot);
+  setInterval(async () => await start(bot), 8000);
+}
+
+module.exports = main;

+ 1 - 13
src/domain/Chat.js

@@ -3,18 +3,10 @@ class Chat {
     id, 
     title, 
     user_id,
-    interval_post = "1", 
-    start_posts = "8:00", 
-    end_posts = "00:00", 
-    next_posts_time = "9:00", 
     ) {
     this.id = String(id);
     this.title = title;
     this.user_id = String(user_id);
-    this.interval_post = interval_post;
-    this.start_posts = start_posts;
-    this.end_posts = end_posts;
-    this.next_posts_time = next_posts_time;
 
     Object.freeze(this);
   }
@@ -23,11 +15,7 @@ class Chat {
     return {
       id: this.id,
       title: this.title,
-      user_id: this.user_id,
-      interval_post: this.interval_post,
-      start_posts: this.start_posts,
-      end_posts: this.end_posts,
-      next_posts_time: this.next_posts_time
+      user_id: this.user_id
     }
   }
 }

+ 1 - 3
src/domain/User.js

@@ -1,8 +1,7 @@
 class User {
-  constructor(user_id, username, timezone) {
+  constructor(user_id, username) {
     this.user_id = String(user_id);
     this.username = username;
-    this.timezone = timezone;
 
     Object.freeze(this);
   }
@@ -11,7 +10,6 @@ class User {
     return {
       user_id: this.user_id,
       username: this.username,
-      timezone: this.timezone,
     }
   }
 }

+ 14 - 4
src/drivers/rss-parser/index.js

@@ -2,14 +2,24 @@ const Parser = require('rss-parser');
 const parser = new Parser();
 
 class RssParser {
-  async getFeedTitle(rss_url) {
-    const feed = await parser.parseURL(rss_url);
+  async getFeedTitle(rssURL) {
+    const feed = await parser.parseURL(rssURL);
     return feed.title;
   }
 
-  async rssIsValid(rss_url) {
+  async getFeeds(rssURL) {
+    try {
+      const feeds = await parser.parseURL(rssURL);
+      
+      return feeds.items;
+    } catch (err) {
+      return [];
+    }
+  }
+
+  async rssIsValid(rssURL) {
     try { 
-      await parser.parseURL(rss_url);
+      await parser.parseURL(rssURL);
       return true;
     } catch (err) {
       console.log(err)

+ 6 - 0
src/helpers/bot_helpers.js

@@ -34,10 +34,16 @@ function getUserId(ctx, type) {
   }
 }
 
+function removeCommand(message, command) {
+  const newMessage = message.replace(command, '').trim();
+  return newMessage;
+}
+
 module.exports = {
   isAdmin,
   isBotAdmin,
   getChatId,
   getUserId,
   isStillMemberAndAdmin,
+  removeCommand
 };

+ 2 - 2
src/helpers/features_helpers.js

@@ -43,7 +43,7 @@ async function listFeeds(feedRepository, chatID) {
 
 async function listChats(chatRepository, userID) {
   const chats = await chatRepository.getAllChatOfUser(String(userID));
-
+  
   let chatsList = '<strong>Chats 📌</strong>\n';
   if (chats && chats.length > 0) {
     chats.forEach(chat => {
@@ -60,5 +60,5 @@ module.exports = {
   removeSpacesInArray,
   removeNotHashtagsInArray,
   listFeeds,
-  listChats
+  listChats,
 }

+ 0 - 0
src/index.js


部分文件因为文件数量过多而无法显示