class TestDatabaseHandler(unittest.TestCase): def setUp(self): self.db = DatabaseHandler("resources/test.db") def test_add_user(self): self.db.add_user(telegram_id=25525, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) result = self.db.get_user(telegram_id=25525) self.assertEqual(result[0], 25525) self.assertEqual(result[1], "TestDummy") self.assertEqual(result[2], "John") self.assertEqual(result[3], "Snow") self.assertEqual(result[4], "DE") self.assertFalse(result[5]) self.assertTrue(result[6]) def test_remove_user(self): self.db.add_user(telegram_id=25525, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) self.db.remove_user(telegram_id=25525) result = self.db.get_user(telegram_id=25525) self.assertIsNone(result) def test_update_user(self): self.db.add_user(telegram_id=25525, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) self.db.update_user(telegram_id=25525, firstname="Jonathan", is_bot=True) result = self.db.get_user(telegram_id=25525) self.assertEqual(result[0], 25525) self.assertEqual(result[1], "TestDummy") self.assertEqual(result[2], "Jonathan") self.assertEqual(result[3], "Snow") self.assertEqual(result[4], "DE") self.assertTrue(result[5]) def test_get_user(self): self.db.add_user(telegram_id=25525, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) result = self.db.get_user(telegram_id=25525) self.assertEqual(result[0], 25525) self.assertEqual(result[1], "TestDummy") self.assertEqual(result[2], "John") self.assertEqual(result[3], "Snow") self.assertEqual(result[4], "DE") self.assertFalse(result[5]) def test_add_url(self): self.db.add_url(url="https://lorem-rss.herokuapp.com/feed") result = self.db.get_url(url="https://lorem-rss.herokuapp.com/feed") self.assertEqual(result[0], "https://lorem-rss.herokuapp.com/feed") def test_remove_url(self): self.db.add_url(url="https://lorem-rss.herokuapp.com/feed") self.db.remove_url(url="https://lorem-rss.herokuapp.com/feed") result = self.db.get_url(url="https://lorem-rss.herokuapp.com/feed") self.assertIsNone(result) def test_remove_url_has_references(self): self.db.add_url(url="https://lorem-rss.herokuapp.com/feed") self.db.add_user(telegram_id=25525, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) self.db.add_user(telegram_id=25526, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) self.db.add_user_bookmark( telegram_id=25525, url="https://lorem-rss.herokuapp.com/feed", alias="Test") self.db.add_user_bookmark( telegram_id=25525, url="https://lorem-rss.herokuapp.com/feed", alias="TestEntry") self.db.remove_url(url="https://lorem-rss.herokuapp.com/feed") result = self.db.get_users_for_url( url="https://lorem-rss.herokuapp.com/feed") self.assertEqual(len(result), 0) result = self.db.get_url(url="https://lorem-rss.herokuapp.com/feed") self.assertIsNone(result) def test_update_url(self): self.db.add_url(url="https://lorem-rss.herokuapp.com/feed") entry = self.db.get_url(url="https://lorem-rss.herokuapp.com/feed") timestamp = str(dh.get_datetime_now()) self.db.update_url( url="https://lorem-rss.herokuapp.com/feed", last_updated=timestamp) result = self.db.get_url(url="https://lorem-rss.herokuapp.com/feed") self.assertEqual(result[1], timestamp) def test_get_url(self): self.db.add_url(url="https://lorem-rss.herokuapp.com/feed") result = self.db.get_url(url="https://lorem-rss.herokuapp.com/feed") self.assertEqual(result[0], "https://lorem-rss.herokuapp.com/feed") def test_add_user_bookmark(self): self.db.add_user(telegram_id=25525, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) self.db.add_user_bookmark( telegram_id=25525, url="https://lorem-rss.herokuapp.com/feed01", alias="feed01") self.db.add_user_bookmark( telegram_id=25525, url="https://lorem-rss.herokuapp.com/feed02", alias="feed02") self.db.add_user_bookmark( telegram_id=25525, url="https://lorem-rss.herokuapp.com/feed03", alias="feed03") result = self.db.get_urls_for_user(telegram_id=25525) self.assertEqual(len(result), 3) self.assertEqual( result[0][0], "https://lorem-rss.herokuapp.com/feed01") self.assertEqual( result[1][0], "https://lorem-rss.herokuapp.com/feed02") self.assertEqual( result[2][0], "https://lorem-rss.herokuapp.com/feed03") def test_remove_bookmark(self): self.db.add_user(telegram_id=25525, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) self.db.add_user_bookmark( telegram_id=25525, url="https://lorem-rss.herokuapp.com/feed01", alias="feed") self.db.remove_user_bookmark( telegram_id=25525, url="https://lorem-rss.herokuapp.com/feed01") result = self.db.get_urls_for_user(telegram_id=25525) self.assertEqual(len(result), 0) def test_update_bookmark(self): pass def test_get_urls_for_user(self): self.db.add_user(telegram_id=25525, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) self.db.add_user_bookmark( telegram_id=25525, url="https://lorem-rss.herokuapp.com/feed01", alias="feed01") self.db.add_user_bookmark( telegram_id=25525, url="https://lorem-rss.herokuapp.com/feed02", alias="feed02") self.db.add_user_bookmark( telegram_id=25525, url="https://lorem-rss.herokuapp.com/feed03", alias="feed03") result = self.db.get_urls_for_user(telegram_id=25525) self.assertEqual(len(result), 3) self.assertEqual( result[0][0], "https://lorem-rss.herokuapp.com/feed01") self.assertEqual( result[1][0], "https://lorem-rss.herokuapp.com/feed02") self.assertEqual( result[2][0], "https://lorem-rss.herokuapp.com/feed03") def test_get_users_for_url(self): self.db.add_user(telegram_id=25526, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) self.db.add_user(telegram_id=25527, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) self.db.add_user(telegram_id=25528, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) self.db.add_user_bookmark( telegram_id=25526, url="http://cbrgm.de", alias="cbrgm") self.db.add_user_bookmark( telegram_id=25527, url="http://cbrgm.de", alias="niceblog") self.db.add_user_bookmark( telegram_id=25528, url="http://cbrgm.de", alias="awesome") result = self.db.get_users_for_url("http://cbrgm.de") self.assertEqual(len(result), 3) self.assertEqual(result[0][1], "TestDummy01") self.assertEqual(result[1][1], "TestDummy02") self.assertEqual(result[2][1], "TestDummy03") def test_get_user_bookmark(self): self.db.add_user(telegram_id=25525, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) self.db.add_user_bookmark( url="https://lorem-rss.herokuapp.com/feed", telegram_id=25525, alias="Test") bookmark = self.db.get_user_bookmark(telegram_id=25525, alias="Test") self.assertEqual(bookmark[0], "https://lorem-rss.herokuapp.com/feed") self.assertEqual(bookmark[1], "Test") def test_remove_if_not_referenced(self): self.db.add_url(url="https://lorem-rss.herokuapp.com/feed") self.db.add_user(telegram_id=25525, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) self.db.add_user_bookmark( url="https://lorem-rss.herokuapp.com/feed", telegram_id=25525, alias="Test") self.db.remove_user_bookmark( telegram_id=25525, url="https://lorem-rss.herokuapp.com/feed") web = self.db.get_url("https://lorem-rss.herokuapp.com/feed") self.assertIsNone(web) def test_dont_remove_if_referenced(self): self.db.add_url(url="https://lorem-rss.herokuapp.com/feed") self.db.add_user(telegram_id=25525, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) self.db.add_user(telegram_id=25526, username="******", firstname="John", lastname="Snow", language_code="DE", is_bot=False, is_active=True) self.db.add_user_bookmark( url="https://lorem-rss.herokuapp.com/feed", telegram_id=25525, alias="Test") self.db.add_user_bookmark( url="https://lorem-rss.herokuapp.com/feed", telegram_id=25526, alias="MyTest") self.db.remove_user_bookmark( telegram_id=25525, url="https://lorem-rss.herokuapp.com/feed") web = self.db.get_url("https://lorem-rss.herokuapp.com/feed") self.assertEqual(web[0], "https://lorem-rss.herokuapp.com/feed") def tearDown(self): base_path = os.path.abspath(os.path.dirname(__file__)) filepath = os.path.join(base_path, '..', "resources/test.db") os.remove(filepath)
class RobotRss(object): def __init__(self, telegram_token, update_interval): # Initialize bot internals self.db = DatabaseHandler("resources/userdata/datastore.db") self.fh = FileHandler("..") self.inventory = InventoryHandler() # Register webhook to telegram bot self.updater = Updater(telegram_token) self.dispatcher = self.updater.dispatcher # Add Commands to bot self._addCommand(CommandHandler("start", self.start)) self._addCommand(CommandHandler("stop", self.stop)) self._addCommand(CommandHandler("help", self.help)) self._addCommand(CommandHandler("list", self.list)) self._addCommand(CommandHandler("about", self.about)) self._addCommand(CommandHandler("add", self.add, pass_args=True)) self._addCommand(CommandHandler("get", self.get, pass_args=True)) self._addCommand(CommandHandler("remove", self.remove, pass_args=True)) self._addCommand( CommandHandler("addgroup", self.add_group, pass_args=True)) self._addCommand( CommandHandler("search", self.inventory_search, pass_args=True)) self._addCommand(MessageHandler(Filters.text, self.vechten)) self._addCommand(MessageHandler(Filters.command, self.unknown)) self._addCommand(InlineQueryHandler(self.inlinequery)) # Start the Bot self.processing = BatchProcess(database=self.db, update_interval=update_interval, bot=self.dispatcher.bot) self.processing.start() self.updater.start_polling() self.updater.idle() def _addCommand(self, command): """ Registers a new command to the bot """ self.updater.dispatcher.add_handler(command) def inlinequery(self, bot, update): query = update.inline_query.query print(query) searchresults = self.inventory.search_many(query) print(searchresults) queryresults = [] for result in searchresults: queryresult = InlineQueryResultPhoto( id=uuid4(), title=result[0], description=result[1], caption= "<b>Voorwerp</b>: {}\n<b>Omschrijving:</b> {}\n<b>Locatie:</b> {}" .format(result[0], result[1], result[2]), parse_mode="HTML", photo_url=result[3], thumb_url=result[3]) queryresults.append(queryresult) update.inline_query.answer(queryresults) def start(self, bot, update): """ Send a message when the command /start is issued. """ telegram_user = update.message.from_user # Add new User if not exists if not self.db.get_user(telegram_id=telegram_user.id): message = "Hee, jou ken ik nog niet.. Ik stop je ff in mijn database, momentje." update.message.reply_text(message) self.db.add_user(telegram_id=telegram_user.id, username=telegram_user.username, firstname=telegram_user.first_name, lastname=telegram_user.last_name, language_code=telegram_user.language_code, is_bot=telegram_user.is_bot, is_active=1) self.db.update_user(telegram_id=telegram_user.id, is_active=1) message = "Je krijgt nu persoonlijk nieuws. Tik /help voor de commando's" update.message.reply_text(message) def add(self, bot, update, args): """ Adds a rss subscription to user """ telegram_user = update.message.from_user if len(args) != 2: message = "Ja, daar snap dus ik dus niks van. Probeer dit eens:\n" \ " /add <url> <naampje>" update.message.reply_text(message) return arg_url = FeedHandler.format_url_string(string=args[0]) arg_entry = args[1] # Check if argument matches url format if not FeedHandler.is_parsable(url=arg_url): message = "Die url lijkt niet helemaal lekker!" update.message.reply_text(message) return # Check if entry does not exists entries = self.db.get_urls_for_user(telegram_id=telegram_user.id) if any(arg_url.lower() in entry for entry in entries): message = "Deze url heb je al toegevoegd!" update.message.reply_text(message) return if any(arg_entry in entry for entry in entries): message = "Je hebt hetzelfde naampje gebruikt als een andere url, da ga nie" update.message.reply_text(message) return self.db.add_user_bookmark(telegram_id=telegram_user.id, url=arg_url.lower(), alias=arg_entry) message = "Hij staat erbij! Gebruik /list als je me niet gelooft" update.message.reply_text(message) def get(self, bot, update, args): """ Manually parses an rss feed """ telegram_user = update.message.from_user if len(args) > 2: message = "To get the last news of your subscription please use /get <entryname> [optional: <count 1-10>]. Make sure you first add a feed using the /add command." update.message.reply_text(message) return if len(args) == 2: args_entry = args[0] args_count = int(args[1]) else: args_entry = args[0] args_count = 4 url = self.db.get_user_bookmark(telegram_id=telegram_user.id, alias=args_entry) if url is None: message = "I can not find an entry with label " + \ args_entry + " in your subscriptions! Please check your subscriptions using /list and use the delete command again!" update.message.reply_text(message) return entries = FeedHandler.parse_feed(url[0], args_count) for entry in entries: message = "[" + url[1] + "] <a href='" + \ entry.link + "'>" + entry.title + "</a>" print(message) try: update.message.reply_text(message, parse_mode=ParseMode.HTML) except Unauthorized: self.db.update_user(telegram_id=telegram_user.id, is_active=0) except TelegramError as e: # handle all other telegram related errors print("Telegram error: {0}".format(e.message)) pass def remove(self, bot, update, args): """ Removes an rss subscription from user """ telegram_user = update.message.from_user if len(args) != 1: message = "To remove a subscriptions from your list please use /remove <entryname>. " \ "To see all your subscriptions along with their entry names use /list !" update.message.reply_text(message) return entry = self.db.get_user_bookmark(telegram_id=telegram_user.id, alias=args[0]) if entry: self.db.remove_user_bookmark(telegram_id=telegram_user.id, url=entry[0]) message = "I removed " + args[0] + " from your subscriptions!" update.message.reply_text(message) else: message = "I can not find an entry with label " + \ args[ 0] + " in your subscriptions! Please check your subscriptions using /list and use the delete command again!" update.message.reply_text(message) def list(self, bot, update): """ Displays a list of all user subscriptions """ telegram_user = update.message.from_user message = "Hier is het lijstje met url's en groepen/users:" update.message.reply_text(message) # Group URL's entries = self.db.get_channels() for entry in entries: message = "[" + entry[0] + "]\n " + entry[1] update.message.reply_text(message) # User URL's entries = self.db.get_urls_for_user(telegram_id=telegram_user.id) for entry in entries: message = "[" + entry[1] + "]\n " + entry[0] update.message.reply_text(message) def help(self, bot, update): """ Send a message when the command /help is issued. """ message = "Ik snap de volgende commando's:\n" \ "/help: Deze helptekst\n" \ "/about: Info over deze bot\n" \ "/start: Zet het sturen van nieuwsupdates aan\n" \ "/stop: Stop met sturen van nieuwsupdates\n" \ "/list: Geef een lijst van feeds\n" \ "/add <url> <naam>: Voeg een nieuwe feed toe\n" \ "/addgroup <url> <@grouphandle>\n" \ "/search <keyword>: Zoek in de DJO inventaris" update.message.reply_text(message) def stop(self, bot, update): """ Stops the bot from working """ telegram_user = update.message.from_user self.db.update_user(telegram_id=telegram_user.id, is_active=0) message = "Jahaaa, ik stop al." update.message.reply_text(message) def about(self, bot, update): """ Shows about information """ message = "Dit is de officiele DJO Amersfoort Telegram Bot. Hier staat mijn source: " \ " <a href='https://github.com/djoamersfoort/djo-telegram-bot'>Github</a>." update.message.reply_text(message, parse_mode=ParseMode.HTML) def add_group(self, bot, update, args): if len(args) != 2: message = "Ja, daar snap ik dus helemaal niks van. Probeer dit eens:\n" \ "/addgroup <url> <groupame>" update.message.reply_text(message) return arg_url = FeedHandler.format_url_string(string=args[0]) arg_channel = args[1] # Check if argument matches url format if not FeedHandler.is_parsable(url=arg_url): message = "Die url lijkt niet helemaal lekker!" update.message.reply_text(message) return if not arg_channel.startswith('@'): message = "Een groepnaam moet met @ starten" update.message.reply_text(message) return channels = self.db.get_channels() if any(channel[0] == arg_channel and channel[1] == arg_url for channel in channels): update.message.reply_text( "Deze url is al aanwezig voor deze groep!") return # Add the channel + url self.db.add_url(arg_url) self.db.add_channel(arg_channel, arg_url) message = "Channel en url zijn toegevoegd!" update.message.reply_text(message) def inventory_search(self, bot, update, args): if not len(args) >= 1: update.message.reply_text('Waar wil je naar zoeken?') return keyword = ' '.join(args[0:]) (text, image) = self.inventory.search(keyword) if image is not None: update.message.reply_photo(image, quote=False, caption=text, parse_mode=ParseMode.HTML) else: update.message.reply_text(text, quote=False, parse_mode=ParseMode.HTML) def vechten(self, bot, update): if "kom vechten" in update.message.text.lower(): print("Iemand wil vechten") update.message.reply_document( 'https://i.kym-cdn.com/photos/images/original/001/356/324/914.gif' ) def unknown(self, bot, update): message = "Computer says no" update.message.reply_text(message)
class RobotRss(object): def __init__(self, telegram_token, update_interval): # Initialize bot internals self.db = DatabaseHandler("resources/datastore.db") self.fh = FileHandler("..") # Register webhook to telegram bot self.updater = Updater(telegram_token) self.dispatcher = self.updater.dispatcher # Add Commands to bot self._addCommand(CommandHandler("start", self.start)) self._addCommand(CommandHandler("stop", self.stop)) self._addCommand(CommandHandler("help", self.help)) self._addCommand(CommandHandler("list", self.list)) self._addCommand(CommandHandler("about", self.about)) self._addCommand(CommandHandler("add", self.add, pass_args=True)) self._addCommand(CommandHandler("get", self.get, pass_args=True)) self._addCommand(CommandHandler("remove", self.remove, pass_args=True)) # Start the Bot self.processing = BatchProcess( database=self.db, update_interval=update_interval, bot=self.dispatcher.bot) self.processing.start() self.updater.start_polling() self.updater.idle() def _addCommand(self, command): """ Registers a new command to the bot """ self.updater.dispatcher.add_handler(command) def start(self, bot, update): """ Send a message when the command /start is issued. """ telegram_user = update.message.from_user # Add new User if not exists if not self.db.get_user(telegram_id=telegram_user.id): message = "Hello! I don't think we've met before! I am an RSS News Bot and would like to help you to receive your favourite news in the future! Let me first set up a few things before we start..." update.message.reply_text(message) self.db.add_user(telegram_id=telegram_user.id, username=telegram_user.username, firstname=telegram_user.first_name, lastname=telegram_user.last_name, language_code=telegram_user.language_code, is_bot=telegram_user.is_bot, is_active=1) self.db.update_user(telegram_id=telegram_user.id, is_active=1) message = "You will now receive news! Use /help if you need some tips how to tell me what to do!" update.message.reply_text(message) def add(self, bot, update, args): """ Adds a rss subscription to user """ telegram_user = update.message.from_user if len(args) != 2: message = "Sorry! I could not add the entry! Please use the the command passing the following arguments:\n\n /add <url> <entryname> \n\n Here is a short example: \n\n /add http://www.feedforall.com/sample.xml ExampleEntry" update.message.reply_text(message) return arg_url = args[0] arg_entry = args[1] # Check if argument matches url format feed=FeedHandler.is_parsable(url=arg_url) if not feed: message = f"Sorry! It seems like {arg_url}" + \ "' doesn't provide an RSS news feed... Have you tried another URL from that provider?" update.message.reply_text(message) return # Check if entry does not exists entries = self.db.get_urls_for_user(telegram_id=telegram_user.id) if any(arg_url.lower() in entry.lower() for entry,_ in entries): message = f"Sorry, {telegram_user.first_name}" + \ "! I already have that url stored in your subscriptions." update.message.reply_text(message) return if any(arg_entry in entry for entry in entries): message = f"Sorry! I already have an entry with name {arg_entry}" + \ " stored in your subscriptions.. Please choose another entry name or delete the entry using '/remove {arg_entry}'" update.message.reply_text(message) return urls = self.db.get_all_urls() if not (arg_url in urls): items = {} for item in feed: for key in ['summary', 'title', 'link']: if not(key in item.keys()): item[key]='' hash=CityHash64(item['summary']+item['title']+item['link']) items[hash] = {'active': True, 'last_date': DateHandler.get_datetime_now()} self.db.add_url(url=arg_url, items=items) self.db.add_user_bookmark(telegram_id=telegram_user.id, url=arg_url, alias=arg_entry) message = f"I successfully added {arg_entry} to your subscriptions!" update.message.reply_text(message) def get(self, bot, update, args): """ Manually parses an rss feed """ telegram_user = update.message.from_user if len(args) > 2: message = "To get the last news of your subscription please use /get <entryname> [optional: <count 1-10>]. Make sure you first add a feed using the /add command." update.message.reply_text(message) return if len(args) == 2: args_entry = args[0] args_count = int(args[1]) else: args_entry = args[0] args_count = 4 if not(1 <= args_count <= 10): message = "Count parameter (if used) must be between 1 and 10.\n" + \ "Usage: /get <entryname> [optional: <count 1-10>]" update.message.reply_text(message) return url = self.db.get_user_bookmark(telegram_id=telegram_user.id, alias=args_entry) if url is None: message = "I can not find an entry with label " + \ args_entry + " in your subscriptions! Please check your subscriptions using /list and use the delete command again!" update.message.reply_text(message) return entries = FeedHandler.parse_feed(url[0], args_count) for entry in entries: message = f"[{url[1]}] <a href='{entry.link}'>{entry.title}</a>" print(message) try: update.message.reply_text(message, parse_mode=ParseMode.HTML) except Unauthorized: self.db.update_user(telegram_id=telegram_user.id, is_active=0) except TelegramError: # handle all other telegram related errors pass def remove(self, bot, update, args): """ Removes an rss subscription from user """ telegram_user = update.message.from_user if len(args) != 1: message = "To remove a subscriptions from your list please use /remove <entryname>. To see all your subscriptions along with their entry names use /list !" update.message.reply_text(message) return entry = self.db.get_user_bookmark( telegram_id=telegram_user.id, alias=args[0]) if entry: self.db.remove_user_bookmark( telegram_id=telegram_user.id, url=entry[0]) message = "I removed " + args[0] + " from your subscriptions!" update.message.reply_text(message) else: message = "I can not find an entry with label " + \ args[0] + " in your subscriptions! Please check your subscriptions using /list and use the delete command again!" update.message.reply_text(message) def list(self, bot, update): """ Displays a list of all user subscriptions """ telegram_user = update.message.from_user message = "Here is a list of all subscriptions I stored for you!" update.message.reply_text(message) entries = self.db.get_urls_for_user(telegram_id=telegram_user.id) for entry in entries: message = f"[{entry[1]}]\n {entry[0]}" update.message.reply_text(message) def help(self, bot, update): """ Send a message when the command /help is issued. """ message = "If you need help with handling the commands, please have a look at my <a href='https://github.com/cbrgm/telegram-robot-rss'>Github</a> page. There I have summarized everything necessary for you!" update.message.reply_text(message, parse_mode=ParseMode.HTML) def stop(self, bot, update): """ Stops the bot from working """ telegram_user = update.message.from_user self.db.update_user(telegram_id=telegram_user.id, is_active=0) message = "Oh.. Okay, I will not send you any more news updates! If you change your mind and you want to receive messages from me again use /start command again!" update.message.reply_text(message) def about(self, bot, update): """ Shows about information """ message = "Thank you for using <b>RobotRSS</b>! \n\n If you like the bot, please recommend it to others! \n\nDo you have problems, ideas or suggestions about what the bot should be able to do? Then contact my developer <a href='http://cbrgm.de'>@cbrgm</a> or create an issue on <a href='https://github.com/cbrgm/telegram-robot-rss'>Github</a>. There you will also find my source code, if you are interested in how I work!" update.message.reply_text(message, parse_mode=ParseMode.HTML)