# This is the code behind Helpful Jew. # Helpful Jew is a Telegram bot that parses RSS feeds # and sends notifications when new entry is found # The name "Helpful Jew" was chosed to fight anti-semitism # People should know that Jews are not evil # and that Jews want to help others. # Created by KuchiKuu # 2022-04-16 # Modified: 2020-04-19 import feedparser import telebot import threading # for RSS feed to check from time to time import time # for sleep import json config = {} TOKEN="" OWNER_ID=-1 with open("/root/telegram/helpfuljew/helpfuljew_config") as f: config = json.load(f) TOKEN=config["TOKEN"] OWNER_ID=config["OWNER_ID"] # file structure: # feeds - contains JSON of RSS_FEED: [groupID,groupID] # entries - contains hashed values of posts already sent feeds = {} entries = [] with open("/root/telegram/helpfuljew/helpfuljew_feeds") as f: feeds = json.load(f) with open("/root/telegram/helpfuljew/helpfuljew_entries") as f: entries = json.load(f) if(len(feeds.keys())>0): print(f'{len(feeds.keys())} feeds in database') else: print("feeds are empty") #exit() def json_save_feeds(): with open("/root/telegram/helpfuljew/helpfuljew_feeds","w") as f: json.dump(feeds,f) def json_save_entries(): with open("/root/telegram/helpfuljew/helpfuljew_entries","w") as f: json.dump(entries,f) def check_entry_to_not_shit_itself_and_return_valid_hash(entry): hash="" if "title" in entry.keys(): hash+=entry.title if "published" in entry.keys(): hash+=" "+entry.published if "id" in entry.keys(): hash+=" "+entry.id #print(hash) return hash def fetch_first_time(fetch_first_time_address): entries_number=0 fetch_first_time_feed = feedparser.parse(fetch_first_time_address); for entry in fetch_first_time_feed['entries']: #hash=entry['title']+" "+entry['published']+" "+entry['id'] hash=check_entry_to_not_shit_itself_and_return_valid_hash(entry) if hash not in entries: entries.append(hash) entries_number=entries_number+1 json_save_entries() print("Saved "+str(entries_number)+" from "+fetch_first_time_address) def force_check_feeds(filler=1): if(filler==1): check_feeds_feeds = feeds check_feeds_entries = entries print("Checking feeds") if(len(check_feeds_feeds.keys())>0): for address in check_feeds_feeds.keys(): bot.send_message(OWNER_ID,"Checking "+str(address)) feed=feedparser.parse(address) for entry in feed['entries']: #print(entry['title']+" "+entry['published']+" "+entry['id']); #hash=entry['title']+" "+entry['published']+" "+entry['id'] hash=check_entry_to_not_shit_itself_and_return_valid_hash(entry) if hash not in entries: for group in check_feeds_feeds[address]: text="*"+feed["feed"]["title"]+"*\nNew entry!\n\n"+entry["title"]+"\n" text+=entry["summary"][:100] text+="...\n"+entry['link'] bot.send_message(group,text); entries.append(hash) json_save_entries() bot.send_message(OWNER_ID,"Checking done") def check_feeds(wait_time=3600,forever=1): while(1): check_feeds_feeds = feeds check_feeds_entries = entries print("Checking feeds") if(len(check_feeds_feeds.keys())>0): for address in check_feeds_feeds.keys(): print("Checking "+str(address)) feed=feedparser.parse(address) for entry in feed['entries']: #print(entry['title']+" "+entry['published']+" "+entry['id']); #hash=entry['title']+" "+entry['published']+" "+entry['id'] hash=check_entry_to_not_shit_itself_and_return_valid_hash(entry) if hash not in entries: for group in check_feeds_feeds[address]: text="*"+feed["feed"]["title"]+"*\nNew entry!\n\n"+entry["title"]+"\n"+entry["summary"][:100]+"...\n"+entry['link'] bot.send_message(group,text); entries.append(hash) json_save_entries() print("Checking done. Sleeping...") time.sleep(wait_time); bot = telebot.TeleBot(TOKEN,parse_mode=None) @bot.message_handler(commands=['follow','remove','list','myid','check','reminder']) def database_management_yolo(message): #print(message) command = message.text.split(" ") if(command[0] == "/check"): if(message.from_user.id == OWNER_ID): bot.reply_to(message,"OK") force_check_feeds() if(command[0] == "/reminder"): bot.send_message(message.chat.id,"A friendly reminder:\nIt's all my fault.") if(command[0] == "/myid"): bot.reply_to(message,"Your ID: "+str(message.from_user.id)) if(command[0] == "/follow"): if(len(command[1])>0): feed_address = command[1] check_feed = feedparser.parse(command[1]) if(len(check_feed["entries"])==0): bot.reply_to(message,"Oy vey! This does not look like a valid RSS!") else: if feed_address in feeds.keys(): if message.chat.id not in feeds[feed_address]: feeds[feed_address].append(message.chat.id) bot.reply_to(message,"Following: "+feed_address) fetch_first_time(feed_address) else: bot.reply_to(message,"I already follow this feed for you.") else: feeds[feed_address] = [message.chat.id] bot.reply_to(message,"Following: "+feed_address) fetch_first_time(feed_address) #bot.reply_to(message,str(json.dumps(feeds))) json_save_feeds(); if(command[0] == "/remove"): if(len(command[1])>0): feeds[command[1]].remove(message.chat.id) if(len(feeds[command[1]]) == 0): feeds.pop(command[1]) print("No one else follows "+str(command[1])) bot.reply_to(message,"Removing: "+command[1]) json_save_feeds() if(command[0] == "/list"): list_feeds = [] for i in feeds.keys(): if message.chat.id in feeds[i]: list_feeds.append(i) bot.reply_to(message,"Your feeds:\n"+str(list_feeds)) #@bot.message_handler(func=lambda m: True) #def echo_all(message): # print("Got a message: " + str(message)) # bot.reply_to(message,str(bot.get_me())) #@bot.channel_post_handler(func=lambda m:True) #def reply_to_post(message): # bot.reply_to(message,str(bot.get_Me())) @bot.my_chat_member_handler() def membership(ChatMemberUpdated): if(ChatMemberUpdated.new_chat_member.user.id == bot.get_me().id): if(ChatMemberUpdated.new_chat_member.status == "member"): print("I have joined a chat") bot.send_message(ChatMemberUpdated.chat.id,"Asalamalaykum my brothers.") elif(ChatMemberUpdated.new_chat_member.status == "left"): print("I have been removed from a chat.") x = threading.Thread(target=check_feeds) x.start() bot.infinity_polling()