def main(): setup_logging() updater = Updater(TOKEN, workers=int(os.environ.get('PTB_WORKERS', 2))) dp = updater.dispatcher dp.addTelegramCommandHandler('start', start) addTelegramCommandHandler(dp, 'help', help, 'display help message') mensa_help = '\[<date>] get what offerings are waiting for you at the specified date ' \ 'formatted like \'YYYY-MM-DD\'.' addTelegramCommandHandler(dp, 'mensa', mensa_plan_all, mensa_help) # alias for autocorrected command dp.addTelegramCommandHandler('Mensa', mensa_plan_all) addTelegramCommandHandler(dp, 'm', m_plan_keyboard, 'show quick-access menu') # shortcuts to direct offers for cmd, f, h in SHORTCUTS: addTelegramCommandHandler(dp, cmd, f, h) dp.addTelegramCommandHandler(cmd.capitalize(), f) dp.addTelegramCommandHandler('week', week_plan) dp.addErrorHandler(error) dp.addUnknownTelegramCommandHandler(unknown) if USE_POLLING: logging.info('Bot running with polling enabled.') update_queue = updater.start_polling(poll_interval=1, timeout=5) updater.idle() else: logging.info('Bot running with webhook.') # You can also set the webhook yourself (via cURL) or delete it sending an empty url. # Note that for self-signed certificates, you also have to send the .pem certificate file # to the Telegram API. updater.bot.setWebhook(webhook_url=os.environ.get('PTB_WEBHOOK_URL')) update_queue = updater.start_webhook(os.environ.get('PTB_WEBHOOK_LISTEN_IP'), os.environ.get('PTB_WEBHOOK_LISTEN_PORT'))
class UpdaterTest(BaseTest, unittest.TestCase): """ This object represents Tests for Updater, Dispatcher, WebhookServer and WebhookHandler """ def setUp(self): self.updater = Updater('', workers=2) self.received_message = None self.message_count = 0 self.lock = Lock() def tearDown(self): self.updater.stop() def reset(self): self.message_count = 0 self.received_message = None def telegramHandlerTest(self, bot, update): self.received_message = update.message.text self.message_count += 1 @run_async def asyncHandlerTest(self, bot, update): sleep(1) with self.lock: self.received_message = update.message.text self.message_count += 1 def stringHandlerTest(self, bot, update): self.received_message = update self.message_count += 1 def additionalArgsTest(self, bot, update, update_queue, args): self.received_message = update self.message_count += 1 if args[0] == 'resend': update_queue.put('/test5 noresend') elif args[0] == 'noresend': pass def errorRaisingHandlerTest(self, bot, update): raise TelegramError(update) def errorHandlerTest(self, bot, update, error): self.received_message = error.message self.message_count += 1 def test_addRemoveTelegramMessageHandler(self): print('Testing add/removeTelegramMessageHandler') bot = MockBot('Test') self.updater.bot = bot d = self.updater.dispatcher d.addTelegramMessageHandler( self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, 'Test') # Remove handler d.removeTelegramMessageHandler(self.telegramHandlerTest) self.reset() bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addTelegramMessageHandlerMultipleMessages(self): print('Testing addTelegramMessageHandler and send 100 messages...') self.updater.bot = MockBot('Multiple', 100) self.updater.dispatcher.addTelegramMessageHandler( self.telegramHandlerTest) self.updater.start_polling(0.0) sleep(.5) self.assertEqual(self.received_message, 'Multiple') self.assertEqual(self.message_count, 100) def test_addRemoveTelegramRegexHandler(self): print('Testing add/removeStringRegexHandler') bot = MockBot('Test2') self.updater.bot = bot d = self.updater.dispatcher regobj = re.compile('Te.*') self.updater.dispatcher.addTelegramRegexHandler(regobj, self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, 'Test2') # Remove handler d.removeTelegramRegexHandler(regobj, self.telegramHandlerTest) self.reset() bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveTelegramCommandHandler(self): print('Testing add/removeTelegramCommandHandler') bot = MockBot('/test') self.updater.bot = bot d = self.updater.dispatcher self.updater.dispatcher.addTelegramCommandHandler( 'test', self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, '/test') # Remove handler d.removeTelegramCommandHandler('test', self.telegramHandlerTest) self.reset() bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveUnknownTelegramCommandHandler(self): print('Testing add/removeUnknownTelegramCommandHandler') bot = MockBot('/test2') self.updater.bot = bot d = self.updater.dispatcher self.updater.dispatcher.addUnknownTelegramCommandHandler( self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, '/test2') # Remove handler d.removeUnknownTelegramCommandHandler(self.telegramHandlerTest) self.reset() bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveStringRegexHandler(self): print('Testing add/removeStringRegexHandler') bot = MockBot('', messages=0) self.updater.bot = bot d = self.updater.dispatcher d.addStringRegexHandler('Te.*', self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('Test3') sleep(.1) self.assertEqual(self.received_message, 'Test3') # Remove handler d.removeStringRegexHandler('Te.*', self.stringHandlerTest) self.reset() queue.put('Test3') sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveStringCommandHandler(self): print('Testing add/removeStringCommandHandler') bot = MockBot('', messages=0) self.updater.bot = bot d = self.updater.dispatcher d.addStringCommandHandler( 'test3', self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('/test3') sleep(.1) self.assertEqual(self.received_message, '/test3') # Remove handler d.removeStringCommandHandler('test3', self.stringHandlerTest) self.reset() queue.put('/test3') sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveUnknownStringCommandHandler(self): print('Testing add/removeUnknownStringCommandHandler') bot = MockBot('/test') self.updater.bot = bot d = self.updater.dispatcher d.addUnknownStringCommandHandler( self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('/test4') sleep(.1) self.assertEqual(self.received_message, '/test4') # Remove handler d.removeUnknownStringCommandHandler(self.stringHandlerTest) self.reset() bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveErrorHandler(self): print('Testing add/removeErrorHandler') bot = MockBot('', messages=0) self.updater.bot = bot d = self.updater.dispatcher d.addErrorHandler(self.errorHandlerTest) queue = self.updater.start_polling(0.01) error = TelegramError("Unauthorized.") queue.put(error) sleep(.1) self.assertEqual(self.received_message, "Unauthorized.") # Remove handler d.removeErrorHandler(self.errorHandlerTest) self.reset() queue.put(error) sleep(.1) self.assertTrue(None is self.received_message) def test_errorInHandler(self): print('Testing error in Handler') bot = MockBot('', messages=0) self.updater.bot = bot d = self.updater.dispatcher d.addStringRegexHandler('.*', self.errorRaisingHandlerTest) self.updater.dispatcher.addErrorHandler(self.errorHandlerTest) queue = self.updater.start_polling(0.01) queue.put('Test Error 1') sleep(.1) self.assertEqual(self.received_message, 'Test Error 1') def test_errorOnGetUpdates(self): print('Testing error on getUpdates') bot = MockBot('', raise_error=True) self.updater.bot = bot d = self.updater.dispatcher d.addErrorHandler(self.errorHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, "Test Error 2") def test_addRemoveTypeHandler(self): print('Testing add/removeTypeHandler') bot = MockBot('', messages=0) self.updater.bot = bot d = self.updater.dispatcher d.addTypeHandler(dict, self.stringHandlerTest) queue = self.updater.start_polling(0.01) payload = {"Test": 42} queue.put(payload) sleep(.1) self.assertEqual(self.received_message, payload) # Remove handler d.removeTypeHandler(dict, self.stringHandlerTest) self.reset() queue.put(payload) sleep(.1) self.assertTrue(None is self.received_message) def test_runAsync(self): print('Testing @run_async') bot = MockBot('Test5', messages=2) self.updater.bot = bot d = self.updater.dispatcher d.addTelegramMessageHandler( self.asyncHandlerTest) self.updater.start_polling(0.01) sleep(1.2) self.assertEqual(self.received_message, 'Test5') self.assertEqual(self.message_count, 2) def test_additionalArgs(self): print('Testing additional arguments for handlers') self.updater.bot = MockBot('', messages=0) self.updater.dispatcher.addStringCommandHandler( 'test5', self.additionalArgsTest) queue = self.updater.start_polling(0.01) queue.put('/test5 resend') sleep(.1) self.assertEqual(self.received_message, '/test5 noresend') self.assertEqual(self.message_count, 2) def test_webhook(self): print('Testing Webhook') bot = MockBot('', messages=0) self.updater.bot = bot d = self.updater.dispatcher d.addTelegramMessageHandler( self.telegramHandlerTest) # Select random port for travis port = randrange(1024, 49152) self.updater.start_webhook('127.0.0.1', port, './tests/test_updater.py', './tests/test_updater.py', listen='127.0.0.1') sleep(0.5) # SSL-Wrapping will fail, so we start the server without SSL Thread(target=self.updater.httpd.serve_forever).start() # Now, we send an update to the server via urlopen message = Message(1, User(1, "Tester"), datetime.now(), GroupChat(1, "Test Group")) message.text = "Webhook Test" update = Update(1) update.message = message try: payload = bytes(update.to_json(), encoding='utf-8') except TypeError: payload = bytes(update.to_json()) header = { 'content-type': 'application/json', 'content-length': str(len(payload)) } r = Request('http://127.0.0.1:%d/TOKEN' % port, data=payload, headers=header) urlopen(r) sleep(1) self.assertEqual(self.received_message, 'Webhook Test') print("Test other webhook server functionalites...") request = Request('http://localhost:%d/webookhandler.py' % port) response = urlopen(request) self.assertEqual(b'', response.read()) self.assertEqual(200, response.code) request.get_method = lambda: 'HEAD' response = urlopen(request) self.assertEqual(b'', response.read()) self.assertEqual(200, response.code) # Test multiple shutdown() calls self.updater.httpd.shutdown() self.updater.httpd.shutdown() self.assertTrue(True) def signalsender(self): sleep(0.5) os.kill(os.getpid(), signal.SIGTERM) def test_idle(self): print('Testing idle') self.updater.bot = MockBot('Test6', messages=0) self.updater.start_polling(poll_interval=0.01) Thread(target=self.signalsender).start() self.updater.idle() # If we get this far, idle() ran through sleep(1) self.updater.running = False
class UpdaterTest(BaseTest, unittest.TestCase): """ This object represents Tests for Updater, Dispatcher, WebhookServer and WebhookHandler """ def setUp(self): self.updater = None self.received_message = None self.message_count = 0 self.lock = Lock() def _setup_updater(self, *args, **kwargs): bot = MockBot(*args, **kwargs) self.updater = Updater(workers=2, bot=bot) def tearDown(self): if self.updater is not None: self.updater.stop() def reset(self): self.message_count = 0 self.received_message = None def telegramHandlerTest(self, bot, update): self.received_message = update.message.text self.message_count += 1 def telegramInlineHandlerTest(self, bot, update): self.received_message = (update.inline_query, update.chosen_inline_result) self.message_count += 1 @run_async def asyncHandlerTest(self, bot, update, **kwargs): sleep(1) with self.lock: self.received_message = update.message.text self.message_count += 1 def stringHandlerTest(self, bot, update): self.received_message = update self.message_count += 1 def regexGroupHandlerTest(self, bot, update, groups=None, groupdict=None): self.received_message = (groups, groupdict) self.message_count += 1 def additionalArgsTest(self, bot, update, update_queue, args): self.received_message = update self.message_count += 1 if args[0] == 'resend': update_queue.put('/test5 noresend') elif args[0] == 'noresend': pass def contextTest(self, bot, update, context): self.received_message = update self.message_count += 1 self.context = context @run_async def asyncAdditionalHandlerTest(self, bot, update, update_queue=None, **kwargs): sleep(1) with self.lock: if update_queue is not None: self.received_message = update.message.text self.message_count += 1 def errorRaisingHandlerTest(self, bot, update): raise TelegramError(update) def errorHandlerTest(self, bot, update, error): self.received_message = error.message self.message_count += 1 def test_addRemoveTelegramMessageHandler(self): self._setup_updater('Test') d = self.updater.dispatcher d.addTelegramMessageHandler(self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, 'Test') # Remove handler d.removeTelegramMessageHandler(self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addTelegramMessageHandlerMultipleMessages(self): self._setup_updater('Multiple', 100) self.updater.dispatcher.addTelegramMessageHandler( self.telegramHandlerTest) self.updater.start_polling(0.0) sleep(2) self.assertEqual(self.received_message, 'Multiple') self.assertEqual(self.message_count, 100) def test_addRemoveTelegramRegexHandler(self): self._setup_updater('Test2') d = self.updater.dispatcher regobj = re.compile('Te.*') self.updater.dispatcher.addTelegramRegexHandler( regobj, self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, 'Test2') # Remove handler d.removeTelegramRegexHandler(regobj, self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveTelegramCommandHandler(self): self._setup_updater('/test') d = self.updater.dispatcher self.updater.dispatcher.addTelegramCommandHandler( 'test', self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, '/test') # Remove handler d.removeTelegramCommandHandler('test', self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveUnknownTelegramCommandHandler(self): self._setup_updater('/test2') d = self.updater.dispatcher self.updater.dispatcher.addUnknownTelegramCommandHandler( self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, '/test2') # Remove handler d.removeUnknownTelegramCommandHandler(self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveStringRegexHandler(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringRegexHandler('Te.*', self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('Test3') sleep(.1) self.assertEqual(self.received_message, 'Test3') # Remove handler d.removeStringRegexHandler('Te.*', self.stringHandlerTest) self.reset() queue.put('Test3') sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveStringCommandHandler(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringCommandHandler('test3', self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('/test3') sleep(.1) self.assertEqual(self.received_message, '/test3') # Remove handler d.removeStringCommandHandler('test3', self.stringHandlerTest) self.reset() queue.put('/test3') sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveUnknownStringCommandHandler(self): self._setup_updater('/test') d = self.updater.dispatcher d.addUnknownStringCommandHandler(self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('/test4') sleep(.1) self.assertEqual(self.received_message, '/test4') # Remove handler d.removeUnknownStringCommandHandler(self.stringHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveErrorHandler(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addErrorHandler(self.errorHandlerTest) queue = self.updater.start_polling(0.01) error = TelegramError("Unauthorized.") queue.put(error) sleep(.1) self.assertEqual(self.received_message, "Unauthorized.") # Remove handler d.removeErrorHandler(self.errorHandlerTest) self.reset() queue.put(error) sleep(.1) self.assertTrue(None is self.received_message) def test_errorInHandler(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringRegexHandler('.*', self.errorRaisingHandlerTest) self.updater.dispatcher.addErrorHandler(self.errorHandlerTest) queue = self.updater.start_polling(0.01) queue.put('Test Error 1') sleep(.1) self.assertEqual(self.received_message, 'Test Error 1') def test_cleanBeforeStart(self): self._setup_updater('') d = self.updater.dispatcher d.addTelegramMessageHandler(self.telegramHandlerTest) self.updater.start_polling(0.01, clean=True) sleep(.1) self.assertEqual(self.message_count, 0) self.assertIsNone(self.received_message) def test_errorOnGetUpdates(self): self._setup_updater('', raise_error=True) d = self.updater.dispatcher d.addErrorHandler(self.errorHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, "Test Error 2") def test_addRemoveTypeHandler(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addTypeHandler(dict, self.stringHandlerTest) queue = self.updater.start_polling(0.01) payload = {"Test": 42} queue.put(payload) sleep(.1) self.assertEqual(self.received_message, payload) # Remove handler d.removeTypeHandler(dict, self.stringHandlerTest) self.reset() queue.put(payload) sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveInlineHandlerQuery(self): print('Testing add/removeInlineHandler') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addTelegramInlineHandler(self.telegramInlineHandlerTest) queue = self.updater.start_polling(0.01) update = Update(update_id=0, inline_query="testquery") update2 = Update(update_id=0, chosen_inline_result="testresult") queue.put(update) sleep(.1) self.assertEqual(self.received_message[0], "testquery") queue.put(update2) sleep(.1) self.assertEqual(self.received_message[1], "testresult") # Remove handler d.removeTelegramInlineHandler(self.telegramInlineHandlerTest) self.reset() queue.put(update) sleep(.1) self.assertTrue(None is self.received_message) def test_runAsync(self): self._setup_updater('Test5', messages=2) d = self.updater.dispatcher d.addTelegramMessageHandler(self.asyncHandlerTest) self.updater.start_polling(0.01) sleep(1.2) self.assertEqual(self.received_message, 'Test5') self.assertEqual(self.message_count, 2) def test_additionalArgs(self): self._setup_updater('', messages=0) self.updater.dispatcher.addStringCommandHandler( 'test5', self.additionalArgsTest) queue = self.updater.start_polling(0.01) queue.put('/test5 resend') sleep(.1) self.assertEqual(self.received_message, '/test5 noresend') self.assertEqual(self.message_count, 2) def test_context(self): context = "context_data" self._setup_updater('', messages=0) self.updater.dispatcher.addStringCommandHandler( 'test_context', self.contextTest) queue = self.updater.start_polling(0.01) queue.put('/test_context', context=context) sleep(.5) self.assertEqual(self.received_message, '/test_context') self.assertEqual(self.message_count, 1) self.assertEqual(self.context, context) def test_regexGroupHandler(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringRegexHandler('^(This).*?(?P<testgroup>regex group).*', self.regexGroupHandlerTest) queue = self.updater.start_polling(0.01) queue.put('This is a test message for regex group matching.') sleep(.1) self.assertEqual(self.received_message, (('This', 'regex group'), { 'testgroup': 'regex group' })) def test_runAsyncWithAdditionalArgs(self): self._setup_updater('Test6', messages=2) d = self.updater.dispatcher d.addTelegramMessageHandler(self.asyncAdditionalHandlerTest) self.updater.start_polling(0.01) sleep(1.2) self.assertEqual(self.received_message, 'Test6') self.assertEqual(self.message_count, 2) def test_webhook(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addTelegramMessageHandler(self.telegramHandlerTest) ip = '127.0.0.1' port = randrange(1024, 49152) # Select random port for travis self.updater.start_webhook(ip, port, url_path='TOKEN', cert='./tests/test_updater.py', key='./tests/test_updater.py') sleep(0.5) # SSL-Wrapping will fail, so we start the server without SSL Thread(target=self.updater.httpd.serve_forever).start() # Now, we send an update to the server via urlopen message = Message(1, User(1, "Tester"), datetime.now(), Chat(1, "group", title="Test Group")) message.text = "Webhook Test" update = Update(1) update.message = message self._send_webhook_msg(ip, port, update.to_json(), 'TOKEN') sleep(1) self.assertEqual(self.received_message, 'Webhook Test') print("Test other webhook server functionalities...") response = self._send_webhook_msg(ip, port, None, 'webookhandler.py') self.assertEqual(b'', response.read()) self.assertEqual(200, response.code) response = self._send_webhook_msg(ip, port, None, 'webookhandler.py', get_method=lambda: 'HEAD') self.assertEqual(b'', response.read()) self.assertEqual(200, response.code) # Test multiple shutdown() calls self.updater.httpd.shutdown() self.updater.httpd.shutdown() self.assertTrue(True) def test_webhook_no_ssl(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addTelegramMessageHandler(self.telegramHandlerTest) ip = '127.0.0.1' port = randrange(1024, 49152) # Select random port for travis self.updater.start_webhook(ip, port) sleep(0.5) # Now, we send an update to the server via urlopen message = Message(1, User(1, "Tester 2"), datetime.now(), Chat(1, 'group', title="Test Group 2")) message.text = "Webhook Test 2" update = Update(1) update.message = message self._send_webhook_msg(ip, port, update.to_json()) sleep(1) self.assertEqual(self.received_message, 'Webhook Test 2') def test_webhook_invalid_posts(self): self._setup_updater('', messages=0) ip = '127.0.0.1' port = randrange(1024, 49152) # select random port for travis thr = Thread(target=self.updater._start_webhook, args=(ip, port, '', None, None)) thr.start() sleep(0.5) try: with self.assertRaises(HTTPError) as ctx: self._send_webhook_msg(ip, port, '<root><bla>data</bla></root>', content_type='application/xml') self.assertEqual(ctx.exception.code, 403) with self.assertRaises(HTTPError) as ctx: self._send_webhook_msg(ip, port, 'dummy-payload', content_len=-2) self.assertEqual(ctx.exception.code, 403) # TODO: prevent urllib or the underlying from adding content-length # with self.assertRaises(HTTPError) as ctx: # self._send_webhook_msg(ip, port, 'dummy-payload', # content_len=None) # self.assertEqual(ctx.exception.code, 411) with self.assertRaises(HTTPError) as ctx: self._send_webhook_msg(ip, port, 'dummy-payload', content_len='not-a-number') self.assertEqual(ctx.exception.code, 403) finally: self.updater._stop_httpd() thr.join() def _send_webhook_msg(self, ip, port, payload_str, url_path='', content_len=-1, content_type='application/json', get_method=None): headers = { 'content-type': content_type, } if not payload_str: content_len = None payload = None else: payload = bytes(payload_str, encoding='utf-8') if content_len == -1: content_len = len(payload) if content_len is not None: headers['content-length'] = str(content_len) url = 'http://{ip}:{port}/{path}'.format(ip=ip, port=port, path=url_path) req = Request(url, data=payload, headers=headers) if get_method is not None: req.get_method = get_method return urlopen(req) def signalsender(self): sleep(0.5) os.kill(os.getpid(), signal.SIGTERM) def test_idle(self): self._setup_updater('Test6', messages=0) self.updater.start_polling(poll_interval=0.01) Thread(target=self.signalsender).start() self.updater.idle() # If we get this far, idle() ran through sleep(1) self.assertFalse(self.updater.running) def test_createBot(self): updater = Updater('123:abcd') self.assertIsNotNone(updater.bot) def test_mutualExclusiveTokenBot(self): bot = Bot('123:zyxw') self.assertRaises(ValueError, Updater, token='123:abcd', bot=bot) def test_noTokenOrBot(self): self.assertRaises(ValueError, Updater)
class UpdaterTest(BaseTest, unittest.TestCase): """ This object represents Tests for Updater, Dispatcher, WebhookServer and WebhookHandler """ def setUp(self): self.updater = None self.received_message = None self.message_count = 0 self.lock = Lock() def _setup_updater(self, *args, **kwargs): bot = MockBot(*args, **kwargs) self.updater = Updater(workers=2, bot=bot) def tearDown(self): if self.updater is not None: self.updater.stop() def reset(self): self.message_count = 0 self.received_message = None def telegramHandlerTest(self, bot, update): self.received_message = update.message.text self.message_count += 1 def telegramInlineHandlerTest(self, bot, update): self.received_message = (update.inline_query, update.chosen_inline_result) self.message_count += 1 @run_async def asyncHandlerTest(self, bot, update, **kwargs): sleep(1) with self.lock: self.received_message = update.message.text self.message_count += 1 def stringHandlerTest(self, bot, update): self.received_message = update self.message_count += 1 def regexGroupHandlerTest(self, bot, update, groups=None, groupdict=None): self.received_message = (groups, groupdict) self.message_count += 1 def additionalArgsTest(self, bot, update, update_queue, args): self.received_message = update self.message_count += 1 if args[0] == 'resend': update_queue.put('/test5 noresend') elif args[0] == 'noresend': pass def contextTest(self, bot, update, context): self.received_message = update self.message_count += 1 self.context = context @run_async def asyncAdditionalHandlerTest(self, bot, update, update_queue=None, **kwargs): sleep(1) with self.lock: if update_queue is not None: self.received_message = update.message.text self.message_count += 1 def errorRaisingHandlerTest(self, bot, update): raise TelegramError(update) def errorHandlerTest(self, bot, update, error): self.received_message = error.message self.message_count += 1 def test_addRemoveTelegramMessageHandler(self): self._setup_updater('Test') d = self.updater.dispatcher d.addTelegramMessageHandler( self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, 'Test') # Remove handler d.removeTelegramMessageHandler(self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addTelegramMessageHandlerMultipleMessages(self): self._setup_updater('Multiple', 100) self.updater.dispatcher.addTelegramMessageHandler( self.telegramHandlerTest) self.updater.start_polling(0.0) sleep(2) self.assertEqual(self.received_message, 'Multiple') self.assertEqual(self.message_count, 100) def test_addRemoveTelegramRegexHandler(self): self._setup_updater('Test2') d = self.updater.dispatcher regobj = re.compile('Te.*') self.updater.dispatcher.addTelegramRegexHandler(regobj, self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, 'Test2') # Remove handler d.removeTelegramRegexHandler(regobj, self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveTelegramCommandHandler(self): self._setup_updater('/test') d = self.updater.dispatcher self.updater.dispatcher.addTelegramCommandHandler( 'test', self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, '/test') # Remove handler d.removeTelegramCommandHandler('test', self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveUnknownTelegramCommandHandler(self): self._setup_updater('/test2') d = self.updater.dispatcher self.updater.dispatcher.addUnknownTelegramCommandHandler( self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, '/test2') # Remove handler d.removeUnknownTelegramCommandHandler(self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveStringRegexHandler(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringRegexHandler('Te.*', self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('Test3') sleep(.1) self.assertEqual(self.received_message, 'Test3') # Remove handler d.removeStringRegexHandler('Te.*', self.stringHandlerTest) self.reset() queue.put('Test3') sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveStringCommandHandler(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringCommandHandler( 'test3', self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('/test3') sleep(.1) self.assertEqual(self.received_message, '/test3') # Remove handler d.removeStringCommandHandler('test3', self.stringHandlerTest) self.reset() queue.put('/test3') sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveUnknownStringCommandHandler(self): self._setup_updater('/test') d = self.updater.dispatcher d.addUnknownStringCommandHandler( self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('/test4') sleep(.1) self.assertEqual(self.received_message, '/test4') # Remove handler d.removeUnknownStringCommandHandler(self.stringHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveErrorHandler(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addErrorHandler(self.errorHandlerTest) queue = self.updater.start_polling(0.01) error = TelegramError("Unauthorized.") queue.put(error) sleep(.1) self.assertEqual(self.received_message, "Unauthorized.") # Remove handler d.removeErrorHandler(self.errorHandlerTest) self.reset() queue.put(error) sleep(.1) self.assertTrue(None is self.received_message) def test_errorInHandler(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringRegexHandler('.*', self.errorRaisingHandlerTest) self.updater.dispatcher.addErrorHandler(self.errorHandlerTest) queue = self.updater.start_polling(0.01) queue.put('Test Error 1') sleep(.1) self.assertEqual(self.received_message, 'Test Error 1') def test_cleanBeforeStart(self): self._setup_updater('') d = self.updater.dispatcher d.addTelegramMessageHandler(self.telegramHandlerTest) self.updater.start_polling(0.01, clean=True) sleep(.1) self.assertEqual(self.message_count, 0) self.assertIsNone(self.received_message) def test_errorOnGetUpdates(self): self._setup_updater('', raise_error=True) d = self.updater.dispatcher d.addErrorHandler(self.errorHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, "Test Error 2") def test_addRemoveTypeHandler(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addTypeHandler(dict, self.stringHandlerTest) queue = self.updater.start_polling(0.01) payload = {"Test": 42} queue.put(payload) sleep(.1) self.assertEqual(self.received_message, payload) # Remove handler d.removeTypeHandler(dict, self.stringHandlerTest) self.reset() queue.put(payload) sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveInlineHandlerQuery(self): print('Testing add/removeInlineHandler') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addTelegramInlineHandler(self.telegramInlineHandlerTest) queue = self.updater.start_polling(0.01) update = Update(update_id=0, inline_query="testquery") update2 = Update(update_id=0, chosen_inline_result="testresult") queue.put(update) sleep(.1) self.assertEqual(self.received_message[0], "testquery") queue.put(update2) sleep(.1) self.assertEqual(self.received_message[1], "testresult") # Remove handler d.removeTelegramInlineHandler(self.telegramInlineHandlerTest) self.reset() queue.put(update) sleep(.1) self.assertTrue(None is self.received_message) def test_runAsync(self): self._setup_updater('Test5', messages=2) d = self.updater.dispatcher d.addTelegramMessageHandler( self.asyncHandlerTest) self.updater.start_polling(0.01) sleep(1.2) self.assertEqual(self.received_message, 'Test5') self.assertEqual(self.message_count, 2) def test_additionalArgs(self): self._setup_updater('', messages=0) self.updater.dispatcher.addStringCommandHandler( 'test5', self.additionalArgsTest) queue = self.updater.start_polling(0.01) queue.put('/test5 resend') sleep(.1) self.assertEqual(self.received_message, '/test5 noresend') self.assertEqual(self.message_count, 2) def test_context(self): context = "context_data" self._setup_updater('', messages=0) self.updater.dispatcher.addStringCommandHandler( 'test_context', self.contextTest) queue = self.updater.start_polling(0.01) queue.put('/test_context', context=context) sleep(.5) self.assertEqual(self.received_message, '/test_context') self.assertEqual(self.message_count, 1) self.assertEqual(self.context, context) def test_regexGroupHandler(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringRegexHandler('^(This).*?(?P<testgroup>regex group).*', self.regexGroupHandlerTest) queue = self.updater.start_polling(0.01) queue.put('This is a test message for regex group matching.') sleep(.1) self.assertEqual(self.received_message, (('This', 'regex group'), {'testgroup': 'regex group'})) def test_runAsyncWithAdditionalArgs(self): self._setup_updater('Test6', messages=2) d = self.updater.dispatcher d.addTelegramMessageHandler( self.asyncAdditionalHandlerTest) self.updater.start_polling(0.01) sleep(1.2) self.assertEqual(self.received_message, 'Test6') self.assertEqual(self.message_count, 2) def test_webhook(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addTelegramMessageHandler( self.telegramHandlerTest) ip = '127.0.0.1' port = randrange(1024, 49152) # Select random port for travis self.updater.start_webhook(ip, port, url_path='TOKEN', cert='./tests/test_updater.py', key='./tests/test_updater.py') sleep(0.5) # SSL-Wrapping will fail, so we start the server without SSL Thread(target=self.updater.httpd.serve_forever).start() # Now, we send an update to the server via urlopen message = Message(1, User(1, "Tester"), datetime.now(), Chat(1, "group", title="Test Group")) message.text = "Webhook Test" update = Update(1) update.message = message self._send_webhook_msg(ip, port, update.to_json(), 'TOKEN') sleep(1) self.assertEqual(self.received_message, 'Webhook Test') print("Test other webhook server functionalities...") response = self._send_webhook_msg(ip, port, None, 'webookhandler.py') self.assertEqual(b'', response.read()) self.assertEqual(200, response.code) response = self._send_webhook_msg(ip, port, None, 'webookhandler.py', get_method=lambda: 'HEAD') self.assertEqual(b'', response.read()) self.assertEqual(200, response.code) # Test multiple shutdown() calls self.updater.httpd.shutdown() self.updater.httpd.shutdown() self.assertTrue(True) def test_webhook_no_ssl(self): self._setup_updater('', messages=0) d = self.updater.dispatcher d.addTelegramMessageHandler( self.telegramHandlerTest) ip = '127.0.0.1' port = randrange(1024, 49152) # Select random port for travis self.updater.start_webhook(ip, port) sleep(0.5) # Now, we send an update to the server via urlopen message = Message(1, User(1, "Tester 2"), datetime.now(), Chat(1, 'group', title="Test Group 2")) message.text = "Webhook Test 2" update = Update(1) update.message = message self._send_webhook_msg(ip, port, update.to_json()) sleep(1) self.assertEqual(self.received_message, 'Webhook Test 2') def test_webhook_invalid_posts(self): self._setup_updater('', messages=0) ip = '127.0.0.1' port = randrange(1024, 49152) # select random port for travis thr = Thread(target=self.updater._start_webhook, args=(ip, port, '', None, None)) thr.start() sleep(0.5) try: with self.assertRaises(HTTPError) as ctx: self._send_webhook_msg(ip, port, '<root><bla>data</bla></root>', content_type='application/xml') self.assertEqual(ctx.exception.code, 403) with self.assertRaises(HTTPError) as ctx: self._send_webhook_msg(ip, port, 'dummy-payload', content_len=-2) self.assertEqual(ctx.exception.code, 403) # TODO: prevent urllib or the underlying from adding content-length # with self.assertRaises(HTTPError) as ctx: # self._send_webhook_msg(ip, port, 'dummy-payload', # content_len=None) # self.assertEqual(ctx.exception.code, 411) with self.assertRaises(HTTPError) as ctx: self._send_webhook_msg(ip, port, 'dummy-payload', content_len='not-a-number') self.assertEqual(ctx.exception.code, 403) finally: self.updater._stop_httpd() thr.join() def _send_webhook_msg(self, ip, port, payload_str, url_path='', content_len=-1, content_type='application/json', get_method=None): headers = { 'content-type': content_type, } if not payload_str: content_len = None payload = None else: payload = bytes(payload_str, encoding='utf-8') if content_len == -1: content_len = len(payload) if content_len is not None: headers['content-length'] = str(content_len) url = 'http://{ip}:{port}/{path}'.format(ip=ip, port=port, path=url_path) req = Request(url, data=payload, headers=headers) if get_method is not None: req.get_method = get_method return urlopen(req) def signalsender(self): sleep(0.5) os.kill(os.getpid(), signal.SIGTERM) def test_idle(self): self._setup_updater('Test6', messages=0) self.updater.start_polling(poll_interval=0.01) Thread(target=self.signalsender).start() self.updater.idle() # If we get this far, idle() ran through sleep(1) self.assertFalse(self.updater.running) def test_createBot(self): updater = Updater('123:abcd') self.assertIsNotNone(updater.bot) def test_mutualExclusiveTokenBot(self): bot = Bot('123:zyxw') self.assertRaises(ValueError, Updater, token='123:abcd', bot=bot) def test_noTokenOrBot(self): self.assertRaises(ValueError, Updater)
class Bot(object): translations = {} bot = None def __init__(self): self.playing_state = dict() self.updater = Updater(token=dungeon.get_bot_conf("TOKEN")) self.dispatcher = self.updater.dispatcher self.add_handlers() try: self.tzinfo = timezone(dungeon.get_bot_conf("TIMEZONE")) except: self.tzinfo = pytz.utc # i18n BLOCK (see dungeon world commit 66 / haibot commits) def start_polling_loop(self): self.disable_webhook() self.update_queue = self.updater.start_polling() self.updater.idle() self.cleaning() def start_webhook_server(self): self.set_webhook() self.update_queue = self.updater.start_webhook(dungeon.get_env_conf("IP","127.0.0.1"), int(dungeon.get_env_conf("PORT","8080")), dungeon.get_bot_conf("TOKEN")) self.updater.idle() self.cleaning() def cleaning(self): dungeon.logger.info("Finished program.") def set_webhook(self): s = self.updater.bot.setWebhook(dungeon.get_bot_conf("WEBHOOK_URL") + "/" + dungeon.get_bot_conf("TOKEN")) if s: dungeon.logger.info("webhook setup worked") else: dungeon.logger.warning("webhook setup failed") return s def disable_webhook(self): s = self.updater.bot.setWebhook("") if s: dungeon.logger.info("webhook was disabled") else: dungeon.logger.warning("webhook couldn't be disabled") return s def add_handlers(self): self.dispatcher.addTelegramCommandHandler("start", self.command_start) self.dispatcher.addTelegramCommandHandler("help", self.command_help) self.dispatcher.addTelegramCommandHandler("exit", self.command_exit) self.dispatcher.addTelegramCommandHandler("pj", self.command_pj) self.dispatcher.addTelegramCommandHandler("master", self.command_master) self.dispatcher.addTelegramCommandHandler("play", self.command_play) def get_chat_info(self, update): self.last_chat = update.message.chat chad_id = update.message.chat.id sender = update.message.from_user text = update.message.text chat_data = db.chats.find_one({"_id" : chad_id}) if not chat_data: chat_data = {"_id" : chad_id, "state" : const.STOPPED, "context": None} return chat_data, sender, text def command_start(self, bot, update): chat, sender, text = self.get_chat_info(update) if chat["state"] == const.STOPPED: chat["state"] = const.STOPPED self.send_message(messages.welcome) self.send_message(messages.help[chat["state"]]) else: self.send_message(messages.already_started[chat["state"]]) def command_help(self, bot, update): chat, sender, text = self.get_chat_info(update) self.send_message(messages.help[chat["state"]]) def command_exit(self, bot, update): chat, sender, text = self.get_chat_info(update) if chat["state"] != const.STOPPED: self.send_message(messages.exit[chat["state"]]) chat["state"] = const.STOPPED db.chats.replace_one({"_id":chat["_id"]}, chat, upsert=True ) chat["context"] = None else: self.send_message(messages.no_exit) def command_pj(self, bot, update): chat, sender, text = self.get_chat_info(update) if chat["state"] == const.STOPPED: chat["state"] = const.NEWPJ db.chats.replace_one({"_id":chat["_id"]}, chat, upsert=True ) self.send_message("guay") else: self.send_message("ya") def command_master(self, bot, update): pass def command_play(self, bot, update): pass def send_message(self, text): try: self.updater.bot.sendMessage(chat_id=self.last_chat.id, text=text) return True except TelegramError as e: if self.last_chat.type == "private": dungeon.logger.warning("Message sending error to %s [%d] [%s] (TelegramError: %s)" % (self.last_chat.first_name, self.last_chat.id, self.last_chat.type, e)) else: dungeon.logger.warning("Message sending error to %s [%d] [%s] (TelegramError: %s)" % (self.last_chat.title, self.last_chat.id, self.last_chat.type, e)) return False except: if self.last_chat.type == "private": dungeon.logger.warning("Message sending error to %s [%d] [%s]" % (self.last_chat.first_name, self.last_chat.id, self.last_chat.type)) else: dungeon.logger.warning("Message sending error to %s [%d] [%s]" % (self.last_chat.title, self.last_chat.id, self.last_chat.type)) return False
class UpdaterTest(BaseTest, unittest.TestCase): """ This object represents Tests for Updater, Dispatcher, WebhookServer and WebhookHandler """ def setUp(self): self.updater = Updater('', workers=2) self.received_message = None self.message_count = 0 self.lock = Lock() def tearDown(self): self.updater.stop() def reset(self): self.message_count = 0 self.received_message = None def telegramHandlerTest(self, bot, update): self.received_message = update.message.text self.message_count += 1 @run_async def asyncHandlerTest(self, bot, update): sleep(1) with self.lock: self.received_message = update.message.text self.message_count += 1 def stringHandlerTest(self, bot, update): self.received_message = update self.message_count += 1 def additionalArgsTest(self, bot, update, update_queue, args): self.received_message = update self.message_count += 1 if args[0] == 'resend': update_queue.put('/test5 noresend') elif args[0] == 'noresend': pass def errorRaisingHandlerTest(self, bot, update): raise TelegramError(update) def errorHandlerTest(self, bot, update, error): self.received_message = error.message self.message_count += 1 def test_addRemoveTelegramMessageHandler(self): print('Testing add/removeTelegramMessageHandler') bot = MockBot('Test') self.updater.bot = bot d = self.updater.dispatcher d.addTelegramMessageHandler(self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, 'Test') # Remove handler d.removeTelegramMessageHandler(self.telegramHandlerTest) self.reset() bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addTelegramMessageHandlerMultipleMessages(self): print('Testing addTelegramMessageHandler and send 100 messages...') self.updater.bot = MockBot('Multiple', 100) self.updater.dispatcher.addTelegramMessageHandler( self.telegramHandlerTest) self.updater.start_polling(0.0) sleep(.5) self.assertEqual(self.received_message, 'Multiple') self.assertEqual(self.message_count, 100) def test_addRemoveTelegramRegexHandler(self): print('Testing add/removeStringRegexHandler') bot = MockBot('Test2') self.updater.bot = bot d = self.updater.dispatcher regobj = re.compile('Te.*') self.updater.dispatcher.addTelegramRegexHandler( regobj, self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, 'Test2') # Remove handler d.removeTelegramRegexHandler(regobj, self.telegramHandlerTest) self.reset() bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveTelegramCommandHandler(self): print('Testing add/removeTelegramCommandHandler') bot = MockBot('/test') self.updater.bot = bot d = self.updater.dispatcher self.updater.dispatcher.addTelegramCommandHandler( 'test', self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, '/test') # Remove handler d.removeTelegramCommandHandler('test', self.telegramHandlerTest) self.reset() bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveUnknownTelegramCommandHandler(self): print('Testing add/removeUnknownTelegramCommandHandler') bot = MockBot('/test2') self.updater.bot = bot d = self.updater.dispatcher self.updater.dispatcher.addUnknownTelegramCommandHandler( self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, '/test2') # Remove handler d.removeUnknownTelegramCommandHandler(self.telegramHandlerTest) self.reset() bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveStringRegexHandler(self): print('Testing add/removeStringRegexHandler') bot = MockBot('', messages=0) self.updater.bot = bot d = self.updater.dispatcher d.addStringRegexHandler('Te.*', self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('Test3') sleep(.1) self.assertEqual(self.received_message, 'Test3') # Remove handler d.removeStringRegexHandler('Te.*', self.stringHandlerTest) self.reset() queue.put('Test3') sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveStringCommandHandler(self): print('Testing add/removeStringCommandHandler') bot = MockBot('', messages=0) self.updater.bot = bot d = self.updater.dispatcher d.addStringCommandHandler('test3', self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('/test3') sleep(.1) self.assertEqual(self.received_message, '/test3') # Remove handler d.removeStringCommandHandler('test3', self.stringHandlerTest) self.reset() queue.put('/test3') sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveUnknownStringCommandHandler(self): print('Testing add/removeUnknownStringCommandHandler') bot = MockBot('/test') self.updater.bot = bot d = self.updater.dispatcher d.addUnknownStringCommandHandler(self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('/test4') sleep(.1) self.assertEqual(self.received_message, '/test4') # Remove handler d.removeUnknownStringCommandHandler(self.stringHandlerTest) self.reset() bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveErrorHandler(self): print('Testing add/removeErrorHandler') bot = MockBot('', messages=0) self.updater.bot = bot d = self.updater.dispatcher d.addErrorHandler(self.errorHandlerTest) queue = self.updater.start_polling(0.01) error = TelegramError("Unauthorized.") queue.put(error) sleep(.1) self.assertEqual(self.received_message, "Unauthorized.") # Remove handler d.removeErrorHandler(self.errorHandlerTest) self.reset() queue.put(error) sleep(.1) self.assertTrue(None is self.received_message) def test_errorInHandler(self): print('Testing error in Handler') bot = MockBot('', messages=0) self.updater.bot = bot d = self.updater.dispatcher d.addStringRegexHandler('.*', self.errorRaisingHandlerTest) self.updater.dispatcher.addErrorHandler(self.errorHandlerTest) queue = self.updater.start_polling(0.01) queue.put('Test Error 1') sleep(.1) self.assertEqual(self.received_message, 'Test Error 1') def test_errorOnGetUpdates(self): print('Testing error on getUpdates') bot = MockBot('', raise_error=True) self.updater.bot = bot d = self.updater.dispatcher d.addErrorHandler(self.errorHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, "Test Error 2") def test_addRemoveTypeHandler(self): print('Testing add/removeTypeHandler') bot = MockBot('', messages=0) self.updater.bot = bot d = self.updater.dispatcher d.addTypeHandler(dict, self.stringHandlerTest) queue = self.updater.start_polling(0.01) payload = {"Test": 42} queue.put(payload) sleep(.1) self.assertEqual(self.received_message, payload) # Remove handler d.removeTypeHandler(dict, self.stringHandlerTest) self.reset() queue.put(payload) sleep(.1) self.assertTrue(None is self.received_message) def test_runAsync(self): print('Testing @run_async') bot = MockBot('Test5', messages=2) self.updater.bot = bot d = self.updater.dispatcher d.addTelegramMessageHandler(self.asyncHandlerTest) self.updater.start_polling(0.01) sleep(1.2) self.assertEqual(self.received_message, 'Test5') self.assertEqual(self.message_count, 2) def test_additionalArgs(self): print('Testing additional arguments for handlers') self.updater.bot = MockBot('', messages=0) self.updater.dispatcher.addStringCommandHandler( 'test5', self.additionalArgsTest) queue = self.updater.start_polling(0.01) queue.put('/test5 resend') sleep(.1) self.assertEqual(self.received_message, '/test5 noresend') self.assertEqual(self.message_count, 2) def test_webhook(self): print('Testing Webhook') bot = MockBot('', messages=0) self.updater.bot = bot d = self.updater.dispatcher d.addTelegramMessageHandler(self.telegramHandlerTest) # Select random port for travis port = randrange(1024, 49152) self.updater.start_webhook('127.0.0.1', port, './tests/test_updater.py', './tests/test_updater.py', listen='127.0.0.1') sleep(0.5) # SSL-Wrapping will fail, so we start the server without SSL Thread(target=self.updater.httpd.serve_forever).start() # Now, we send an update to the server via urlopen message = Message(1, User(1, "Tester"), datetime.now(), GroupChat(1, "Test Group")) message.text = "Webhook Test" update = Update(1) update.message = message try: payload = bytes(update.to_json(), encoding='utf-8') except TypeError: payload = bytes(update.to_json()) header = { 'content-type': 'application/json', 'content-length': str(len(payload)) } r = Request('http://127.0.0.1:%d/TOKEN' % port, data=payload, headers=header) urlopen(r) sleep(1) self.assertEqual(self.received_message, 'Webhook Test') print("Test other webhook server functionalites...") request = Request('http://localhost:%d/webookhandler.py' % port) response = urlopen(request) self.assertEqual(b'', response.read()) self.assertEqual(200, response.code) request.get_method = lambda: 'HEAD' response = urlopen(request) self.assertEqual(b'', response.read()) self.assertEqual(200, response.code) # Test multiple shutdown() calls self.updater.httpd.shutdown() self.updater.httpd.shutdown() self.assertTrue(True) def signalsender(self): sleep(0.5) os.kill(os.getpid(), signal.SIGTERM) def test_idle(self): print('Testing idle') self.updater.bot = MockBot('Test6', messages=0) self.updater.start_polling(poll_interval=0.01) Thread(target=self.signalsender).start() self.updater.idle() # If we get this far, idle() ran through sleep(1) self.updater.running = False
class UpdaterTest(BaseTest, unittest.TestCase): """ This object represents Tests for Updater, Dispatcher, WebhookServer and WebhookHandler """ def setUp(self): self.updater = None self.received_message = None self.message_count = 0 self.lock = Lock() def _setup_updater(self, *args, **kwargs): bot = MockBot(*args, **kwargs) self.updater = Updater(workers=2, bot=bot) def tearDown(self): if self.updater is not None: self.updater.stop() def reset(self): self.message_count = 0 self.received_message = None def telegramHandlerTest(self, bot, update): self.received_message = update.message.text self.message_count += 1 @run_async def asyncHandlerTest(self, bot, update, **kwargs): sleep(1) with self.lock: self.received_message = update.message.text self.message_count += 1 def stringHandlerTest(self, bot, update): self.received_message = update self.message_count += 1 def regexGroupHandlerTest(self, bot, update, groups=None, groupdict=None): self.received_message = (groups, groupdict) self.message_count += 1 def additionalArgsTest(self, bot, update, update_queue, args): self.received_message = update self.message_count += 1 if args[0] == "resend": update_queue.put("/test5 noresend") elif args[0] == "noresend": pass def contextTest(self, bot, update, context): self.received_message = update self.message_count += 1 self.context = context @run_async def asyncAdditionalHandlerTest(self, bot, update, update_queue=None, **kwargs): sleep(1) with self.lock: if update_queue is not None: self.received_message = update.message.text self.message_count += 1 def errorRaisingHandlerTest(self, bot, update): raise TelegramError(update) def errorHandlerTest(self, bot, update, error): self.received_message = error.message self.message_count += 1 def test_addRemoveTelegramMessageHandler(self): print("Testing add/removeTelegramMessageHandler") self._setup_updater("Test") d = self.updater.dispatcher d.addTelegramMessageHandler(self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(0.1) self.assertEqual(self.received_message, "Test") # Remove handler d.removeTelegramMessageHandler(self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(0.1) self.assertTrue(None is self.received_message) def test_addTelegramMessageHandlerMultipleMessages(self): print("Testing addTelegramMessageHandler and send 100 messages...") self._setup_updater("Multiple", 100) self.updater.dispatcher.addTelegramMessageHandler(self.telegramHandlerTest) self.updater.start_polling(0.0) sleep(2) self.assertEqual(self.received_message, "Multiple") self.assertEqual(self.message_count, 100) def test_addRemoveTelegramRegexHandler(self): print("Testing add/removeStringRegexHandler") self._setup_updater("Test2") d = self.updater.dispatcher regobj = re.compile("Te.*") self.updater.dispatcher.addTelegramRegexHandler(regobj, self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(0.1) self.assertEqual(self.received_message, "Test2") # Remove handler d.removeTelegramRegexHandler(regobj, self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(0.1) self.assertTrue(None is self.received_message) def test_addRemoveTelegramCommandHandler(self): print("Testing add/removeTelegramCommandHandler") self._setup_updater("/test") d = self.updater.dispatcher self.updater.dispatcher.addTelegramCommandHandler("test", self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(0.1) self.assertEqual(self.received_message, "/test") # Remove handler d.removeTelegramCommandHandler("test", self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(0.1) self.assertTrue(None is self.received_message) def test_addRemoveUnknownTelegramCommandHandler(self): print("Testing add/removeUnknownTelegramCommandHandler") self._setup_updater("/test2") d = self.updater.dispatcher self.updater.dispatcher.addUnknownTelegramCommandHandler(self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(0.1) self.assertEqual(self.received_message, "/test2") # Remove handler d.removeUnknownTelegramCommandHandler(self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(0.1) self.assertTrue(None is self.received_message) def test_addRemoveStringRegexHandler(self): print("Testing add/removeStringRegexHandler") self._setup_updater("", messages=0) d = self.updater.dispatcher d.addStringRegexHandler("Te.*", self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put("Test3") sleep(0.1) self.assertEqual(self.received_message, "Test3") # Remove handler d.removeStringRegexHandler("Te.*", self.stringHandlerTest) self.reset() queue.put("Test3") sleep(0.1) self.assertTrue(None is self.received_message) def test_addRemoveStringCommandHandler(self): print("Testing add/removeStringCommandHandler") self._setup_updater("", messages=0) d = self.updater.dispatcher d.addStringCommandHandler("test3", self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put("/test3") sleep(0.1) self.assertEqual(self.received_message, "/test3") # Remove handler d.removeStringCommandHandler("test3", self.stringHandlerTest) self.reset() queue.put("/test3") sleep(0.1) self.assertTrue(None is self.received_message) def test_addRemoveUnknownStringCommandHandler(self): print("Testing add/removeUnknownStringCommandHandler") self._setup_updater("/test") d = self.updater.dispatcher d.addUnknownStringCommandHandler(self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put("/test4") sleep(0.1) self.assertEqual(self.received_message, "/test4") # Remove handler d.removeUnknownStringCommandHandler(self.stringHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(0.1) self.assertTrue(None is self.received_message) def test_addRemoveErrorHandler(self): print("Testing add/removeErrorHandler") self._setup_updater("", messages=0) d = self.updater.dispatcher d.addErrorHandler(self.errorHandlerTest) queue = self.updater.start_polling(0.01) error = TelegramError("Unauthorized.") queue.put(error) sleep(0.1) self.assertEqual(self.received_message, "Unauthorized.") # Remove handler d.removeErrorHandler(self.errorHandlerTest) self.reset() queue.put(error) sleep(0.1) self.assertTrue(None is self.received_message) def test_errorInHandler(self): print("Testing error in Handler") self._setup_updater("", messages=0) d = self.updater.dispatcher d.addStringRegexHandler(".*", self.errorRaisingHandlerTest) self.updater.dispatcher.addErrorHandler(self.errorHandlerTest) queue = self.updater.start_polling(0.01) queue.put("Test Error 1") sleep(0.1) self.assertEqual(self.received_message, "Test Error 1") def test_errorOnGetUpdates(self): print("Testing error on getUpdates") self._setup_updater("", raise_error=True) d = self.updater.dispatcher d.addErrorHandler(self.errorHandlerTest) self.updater.start_polling(0.01) sleep(0.1) self.assertEqual(self.received_message, "Test Error 2") def test_addRemoveTypeHandler(self): print("Testing add/removeTypeHandler") self._setup_updater("", messages=0) d = self.updater.dispatcher d.addTypeHandler(dict, self.stringHandlerTest) queue = self.updater.start_polling(0.01) payload = {"Test": 42} queue.put(payload) sleep(0.1) self.assertEqual(self.received_message, payload) # Remove handler d.removeTypeHandler(dict, self.stringHandlerTest) self.reset() queue.put(payload) sleep(0.1) self.assertTrue(None is self.received_message) def test_runAsync(self): print("Testing @run_async") self._setup_updater("Test5", messages=2) d = self.updater.dispatcher d.addTelegramMessageHandler(self.asyncHandlerTest) self.updater.start_polling(0.01) sleep(1.2) self.assertEqual(self.received_message, "Test5") self.assertEqual(self.message_count, 2) def test_additionalArgs(self): print("Testing additional arguments for handlers") self._setup_updater("", messages=0) self.updater.dispatcher.addStringCommandHandler("test5", self.additionalArgsTest) queue = self.updater.start_polling(0.01) queue.put("/test5 resend") sleep(0.1) self.assertEqual(self.received_message, "/test5 noresend") self.assertEqual(self.message_count, 2) def test_context(self): print("Testing context for handlers") context = "context_data" self._setup_updater("", messages=0) self.updater.dispatcher.addStringCommandHandler("test_context", self.contextTest) queue = self.updater.start_polling(0.01) queue.put("/test_context", context=context) sleep(0.5) self.assertEqual(self.received_message, "/test_context") self.assertEqual(self.message_count, 1) self.assertEqual(self.context, context) def test_regexGroupHandler(self): print("Testing optional groups and groupdict parameters") self._setup_updater("", messages=0) d = self.updater.dispatcher d.addStringRegexHandler("^(This).*?(?P<testgroup>regex group).*", self.regexGroupHandlerTest) queue = self.updater.start_polling(0.01) queue.put("This is a test message for regex group matching.") sleep(0.1) self.assertEqual(self.received_message, (("This", "regex group"), {"testgroup": "regex group"})) def test_runAsyncWithAdditionalArgs(self): print("Testing @run_async with additional parameters") self._setup_updater("Test6", messages=2) d = self.updater.dispatcher d.addTelegramMessageHandler(self.asyncAdditionalHandlerTest) self.updater.start_polling(0.01) sleep(1.2) self.assertEqual(self.received_message, "Test6") self.assertEqual(self.message_count, 2) def test_webhook(self): print("Testing Webhook") self._setup_updater("", messages=0) d = self.updater.dispatcher d.addTelegramMessageHandler(self.telegramHandlerTest) # Select random port for travis port = randrange(1024, 49152) self.updater.start_webhook( "127.0.0.1", port, url_path="TOKEN", cert="./tests/test_updater.py", key="./tests/test_updater.py" ) sleep(0.5) # SSL-Wrapping will fail, so we start the server without SSL Thread(target=self.updater.httpd.serve_forever).start() # Now, we send an update to the server via urlopen message = Message(1, User(1, "Tester"), datetime.now(), Chat(1, "group", title="Test Group")) message.text = "Webhook Test" update = Update(1) update.message = message try: payload = bytes(update.to_json(), encoding="utf-8") except TypeError: payload = bytes(update.to_json()) header = {"content-type": "application/json", "content-length": str(len(payload))} r = Request("http://127.0.0.1:%d/TOKEN" % port, data=payload, headers=header) urlopen(r) sleep(1) self.assertEqual(self.received_message, "Webhook Test") print("Test other webhook server functionalities...") request = Request("http://localhost:%d/webookhandler.py" % port) response = urlopen(request) self.assertEqual(b"", response.read()) self.assertEqual(200, response.code) request.get_method = lambda: "HEAD" response = urlopen(request) self.assertEqual(b"", response.read()) self.assertEqual(200, response.code) # Test multiple shutdown() calls self.updater.httpd.shutdown() self.updater.httpd.shutdown() self.assertTrue(True) def test_webhook_no_ssl(self): print("Testing Webhook without SSL") self._setup_updater("", messages=0) d = self.updater.dispatcher d.addTelegramMessageHandler(self.telegramHandlerTest) # Select random port for travis port = randrange(1024, 49152) self.updater.start_webhook("127.0.0.1", port) sleep(0.5) # Now, we send an update to the server via urlopen message = Message(1, User(1, "Tester 2"), datetime.now(), Chat(1, "group", title="Test Group 2")) message.text = "Webhook Test 2" update = Update(1) update.message = message try: payload = bytes(update.to_json(), encoding="utf-8") except TypeError: payload = bytes(update.to_json()) header = {"content-type": "application/json", "content-length": str(len(payload))} r = Request("http://127.0.0.1:%d/" % port, data=payload, headers=header) urlopen(r) sleep(1) self.assertEqual(self.received_message, "Webhook Test 2") def signalsender(self): sleep(0.5) os.kill(os.getpid(), signal.SIGTERM) def test_idle(self): print("Testing idle") self._setup_updater("Test6", messages=0) self.updater.start_polling(poll_interval=0.01) Thread(target=self.signalsender).start() self.updater.idle() # If we get this far, idle() ran through sleep(1) self.updater.running = False def test_createBot(self): updater = Updater("123:abcd") self.assertIsNotNone(updater.bot) def test_mutualExclusiveTokenBot(self): bot = Bot("123:zyxw") self.assertRaises(ValueError, Updater, token="123:abcd", bot=bot) def test_noTokenOrBot(self): self.assertRaises(ValueError, Updater)
class UpdaterTest(BaseTest, unittest.TestCase): """ This object represents Tests for Updater, Dispatcher, WebhookServer and WebhookHandler """ def setUp(self): self.updater = None self.received_message = None self.message_count = 0 self.lock = Lock() def _setup_updater(self, *args, **kwargs): bot = MockBot(*args, **kwargs) self.updater = Updater(workers=2, bot=bot) def tearDown(self): if self.updater is not None: self.updater.stop() def reset(self): self.message_count = 0 self.received_message = None def telegramHandlerTest(self, bot, update): self.received_message = update.message.text self.message_count += 1 @run_async def asyncHandlerTest(self, bot, update, **kwargs): sleep(1) with self.lock: self.received_message = update.message.text self.message_count += 1 def stringHandlerTest(self, bot, update): self.received_message = update self.message_count += 1 def regexGroupHandlerTest(self, bot, update, groups=None, groupdict=None): self.received_message = (groups, groupdict) self.message_count += 1 def additionalArgsTest(self, bot, update, update_queue, args): self.received_message = update self.message_count += 1 if args[0] == 'resend': update_queue.put('/test5 noresend') elif args[0] == 'noresend': pass def contextTest(self, bot, update, context): self.received_message = update self.message_count += 1 self.context = context @run_async def asyncAdditionalHandlerTest(self, bot, update, update_queue=None, **kwargs): sleep(1) with self.lock: if update_queue is not None: self.received_message = update.message.text self.message_count += 1 def errorRaisingHandlerTest(self, bot, update): raise TelegramError(update) def errorHandlerTest(self, bot, update, error): self.received_message = error.message self.message_count += 1 def test_addRemoveTelegramMessageHandler(self): print('Testing add/removeTelegramMessageHandler') self._setup_updater('Test') d = self.updater.dispatcher d.addTelegramMessageHandler(self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, 'Test') # Remove handler d.removeTelegramMessageHandler(self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addTelegramMessageHandlerMultipleMessages(self): print('Testing addTelegramMessageHandler and send 100 messages...') self._setup_updater('Multiple', 100) self.updater.dispatcher.addTelegramMessageHandler( self.telegramHandlerTest) self.updater.start_polling(0.0) sleep(2) self.assertEqual(self.received_message, 'Multiple') self.assertEqual(self.message_count, 100) def test_addRemoveTelegramRegexHandler(self): print('Testing add/removeStringRegexHandler') self._setup_updater('Test2') d = self.updater.dispatcher regobj = re.compile('Te.*') self.updater.dispatcher.addTelegramRegexHandler( regobj, self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, 'Test2') # Remove handler d.removeTelegramRegexHandler(regobj, self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveTelegramCommandHandler(self): print('Testing add/removeTelegramCommandHandler') self._setup_updater('/test') d = self.updater.dispatcher self.updater.dispatcher.addTelegramCommandHandler( 'test', self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, '/test') # Remove handler d.removeTelegramCommandHandler('test', self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveUnknownTelegramCommandHandler(self): print('Testing add/removeUnknownTelegramCommandHandler') self._setup_updater('/test2') d = self.updater.dispatcher self.updater.dispatcher.addUnknownTelegramCommandHandler( self.telegramHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, '/test2') # Remove handler d.removeUnknownTelegramCommandHandler(self.telegramHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveStringRegexHandler(self): print('Testing add/removeStringRegexHandler') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringRegexHandler('Te.*', self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('Test3') sleep(.1) self.assertEqual(self.received_message, 'Test3') # Remove handler d.removeStringRegexHandler('Te.*', self.stringHandlerTest) self.reset() queue.put('Test3') sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveStringCommandHandler(self): print('Testing add/removeStringCommandHandler') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringCommandHandler('test3', self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('/test3') sleep(.1) self.assertEqual(self.received_message, '/test3') # Remove handler d.removeStringCommandHandler('test3', self.stringHandlerTest) self.reset() queue.put('/test3') sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveUnknownStringCommandHandler(self): print('Testing add/removeUnknownStringCommandHandler') self._setup_updater('/test') d = self.updater.dispatcher d.addUnknownStringCommandHandler(self.stringHandlerTest) queue = self.updater.start_polling(0.01) queue.put('/test4') sleep(.1) self.assertEqual(self.received_message, '/test4') # Remove handler d.removeUnknownStringCommandHandler(self.stringHandlerTest) self.reset() self.updater.bot.send_messages = 1 sleep(.1) self.assertTrue(None is self.received_message) def test_addRemoveErrorHandler(self): print('Testing add/removeErrorHandler') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addErrorHandler(self.errorHandlerTest) queue = self.updater.start_polling(0.01) error = TelegramError("Unauthorized.") queue.put(error) sleep(.1) self.assertEqual(self.received_message, "Unauthorized.") # Remove handler d.removeErrorHandler(self.errorHandlerTest) self.reset() queue.put(error) sleep(.1) self.assertTrue(None is self.received_message) def test_errorInHandler(self): print('Testing error in Handler') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringRegexHandler('.*', self.errorRaisingHandlerTest) self.updater.dispatcher.addErrorHandler(self.errorHandlerTest) queue = self.updater.start_polling(0.01) queue.put('Test Error 1') sleep(.1) self.assertEqual(self.received_message, 'Test Error 1') def test_errorOnGetUpdates(self): print('Testing error on getUpdates') self._setup_updater('', raise_error=True) d = self.updater.dispatcher d.addErrorHandler(self.errorHandlerTest) self.updater.start_polling(0.01) sleep(.1) self.assertEqual(self.received_message, "Test Error 2") def test_addRemoveTypeHandler(self): print('Testing add/removeTypeHandler') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addTypeHandler(dict, self.stringHandlerTest) queue = self.updater.start_polling(0.01) payload = {"Test": 42} queue.put(payload) sleep(.1) self.assertEqual(self.received_message, payload) # Remove handler d.removeTypeHandler(dict, self.stringHandlerTest) self.reset() queue.put(payload) sleep(.1) self.assertTrue(None is self.received_message) def test_runAsync(self): print('Testing @run_async') self._setup_updater('Test5', messages=2) d = self.updater.dispatcher d.addTelegramMessageHandler(self.asyncHandlerTest) self.updater.start_polling(0.01) sleep(1.2) self.assertEqual(self.received_message, 'Test5') self.assertEqual(self.message_count, 2) def test_additionalArgs(self): print('Testing additional arguments for handlers') self._setup_updater('', messages=0) self.updater.dispatcher.addStringCommandHandler( 'test5', self.additionalArgsTest) queue = self.updater.start_polling(0.01) queue.put('/test5 resend') sleep(.1) self.assertEqual(self.received_message, '/test5 noresend') self.assertEqual(self.message_count, 2) def test_context(self): print('Testing context for handlers') context = "context_data" self._setup_updater('', messages=0) self.updater.dispatcher.addStringCommandHandler( 'test_context', self.contextTest) queue = self.updater.start_polling(0.01) queue.put('/test_context', context=context) sleep(.5) self.assertEqual(self.received_message, '/test_context') self.assertEqual(self.message_count, 1) self.assertEqual(self.context, context) def test_regexGroupHandler(self): print('Testing optional groups and groupdict parameters') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringRegexHandler('^(This).*?(?P<testgroup>regex group).*', self.regexGroupHandlerTest) queue = self.updater.start_polling(0.01) queue.put('This is a test message for regex group matching.') sleep(.1) self.assertEqual(self.received_message, (('This', 'regex group'), { 'testgroup': 'regex group' })) def test_runAsyncWithAdditionalArgs(self): print('Testing @run_async with additional parameters') self._setup_updater('Test6', messages=2) d = self.updater.dispatcher d.addTelegramMessageHandler(self.asyncAdditionalHandlerTest) self.updater.start_polling(0.01) sleep(1.2) self.assertEqual(self.received_message, 'Test6') self.assertEqual(self.message_count, 2) def test_webhook(self): print('Testing Webhook') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addTelegramMessageHandler(self.telegramHandlerTest) # Select random port for travis port = randrange(1024, 49152) self.updater.start_webhook('127.0.0.1', port, url_path='TOKEN', cert='./tests/test_updater.py', key='./tests/test_updater.py') sleep(0.5) # SSL-Wrapping will fail, so we start the server without SSL Thread(target=self.updater.httpd.serve_forever).start() # Now, we send an update to the server via urlopen message = Message(1, User(1, "Tester"), datetime.now(), Chat(1, "group", title="Test Group")) message.text = "Webhook Test" update = Update(1) update.message = message try: payload = bytes(update.to_json(), encoding='utf-8') except TypeError: payload = bytes(update.to_json()) header = { 'content-type': 'application/json', 'content-length': str(len(payload)) } r = Request('http://127.0.0.1:%d/TOKEN' % port, data=payload, headers=header) urlopen(r) sleep(1) self.assertEqual(self.received_message, 'Webhook Test') print("Test other webhook server functionalities...") request = Request('http://localhost:%d/webookhandler.py' % port) response = urlopen(request) self.assertEqual(b'', response.read()) self.assertEqual(200, response.code) request.get_method = lambda: 'HEAD' response = urlopen(request) self.assertEqual(b'', response.read()) self.assertEqual(200, response.code) # Test multiple shutdown() calls self.updater.httpd.shutdown() self.updater.httpd.shutdown() self.assertTrue(True) def test_webhook_no_ssl(self): print('Testing Webhook without SSL') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addTelegramMessageHandler(self.telegramHandlerTest) # Select random port for travis port = randrange(1024, 49152) self.updater.start_webhook('127.0.0.1', port) sleep(0.5) # Now, we send an update to the server via urlopen message = Message(1, User(1, "Tester 2"), datetime.now(), Chat(1, 'group', title="Test Group 2")) message.text = "Webhook Test 2" update = Update(1) update.message = message try: payload = bytes(update.to_json(), encoding='utf-8') except TypeError: payload = bytes(update.to_json()) header = { 'content-type': 'application/json', 'content-length': str(len(payload)) } r = Request('http://127.0.0.1:%d/' % port, data=payload, headers=header) urlopen(r) sleep(1) self.assertEqual(self.received_message, 'Webhook Test 2') def signalsender(self): sleep(0.5) os.kill(os.getpid(), signal.SIGTERM) def test_idle(self): print('Testing idle') self._setup_updater('Test6', messages=0) self.updater.start_polling(poll_interval=0.01) Thread(target=self.signalsender).start() self.updater.idle() # If we get this far, idle() ran through sleep(1) self.updater.running = False def test_createBot(self): updater = Updater('123:abcd') self.assertIsNotNone(updater.bot) def test_mutualExclusiveTokenBot(self): bot = Bot('123:zyxw') self.assertRaises(ValueError, Updater, token='123:abcd', bot=bot) def test_noTokenOrBot(self): self.assertRaises(ValueError, Updater)
import os from datetime import datetime from bot_token import Token from calendar_utils import greg2flawless as g2f, flawless_months updater = Updater(token=Token) dispatcher = updater.dispatcher def now_handler(bot, update): fl_today = g2f(datetime.now().date()) text = "It's the %dth day of %s(%d) %d." % (fl_today[2], flawless_months[fl_today[1]], fl_today[1], fl_today[0]) bot.sendMessage(chat_id=update.message.chat_id, text=text) def help_handler(bot, update): text = "This bot converts a gregorian date into a flawless date(a particular calendar based on regular months and years)" bot.sendMessage(chat_id=update.message.chat_id, text=text) if __name__ == "__main__": dispatcher.addTelegramCommandHandler("now", now_handler) dispatcher.addTelegramCommandHandler("help", help_handler) # Get the port to bind to port = int(os.environ.get("PORT", 5000)) # Start the updater listening on all public IPs updater.start_webhook("0.0.0.0", port)
class Bot(object): translations = {} bot = None def __init__(self): self.config = configparser.ConfigParser() self.config.read( CONFIGFILE_PATH ) self.updater = Updater(token=self.get_bot_conf("TOKEN")) self.dispatcher = self.updater.dispatcher self.add_handlers() try: self.tzinfo = timezone(self.get_bot_conf("TIMEZONE")) except: self.tzinfo = pytz.utc def get_bot_conf(self, value): return self.config["bot"][value] def get_env_conf(self, value, default_value=None): if default_value: return os.environ.get(self.config["env"][value], default_value) else: return os.environ.get(self.config["env"][value]) def start_polling_loop(self): self.disable_webhook() self.update_queue = self.updater.start_polling() self.updater.idle() self.cleaning() def start_webhook_server(self): self.set_webhook() self.update_queue = self.updater.start_webhook(self.get_env_conf("IP","127.0.0.1"), int(self.get_env_conf("PORT","8080")), self.get_bot_conf("TOKEN")) self.updater.idle() self.cleaning() def cleaning(self): logger.info("Finished program.") def set_webhook(self): s = self.updater.bot.setWebhook(self.get_bot_conf("WEBHOOK_URL") + "/" + self.get_bot_conf("TOKEN")) if s: logger.info("webhook setup worked") else: logger.warning("webhook setup failed") return s def disable_webhook(self): s = self.updater.bot.setWebhook("") if s: logger.info("webhook was disabled") else: logger.warning("webhook couldn't be disabled") return s def add_handlers(self): self.dispatcher.addTelegramCommandHandler("start", self.command_start) self.dispatcher.addTelegramCommandHandler("help", self.command_help) self.dispatcher.addTelegramCommandHandler("time", self.command_time) self.dispatcher.addTelegramMessageHandler(self.command_echo) #self.dispatcher.addUnknownTelegramCommandHandler(self.command_unknown) #self.dispatcher.addErrorHandler(self.error_handle) def command_start(self, bot, update): self.send_message(bot, update.message.chat, _("Welcome to Dungeon World Bot.")) def command_help(self, bot, update): self.send_message(bot, update.message.chat, _( """Available Commands: /start - Iniciciate or Restart the bot /help - Show the command list. /time - Bot local time check""")) def command_time(self, bot , update): utc_date = datetime.utcnow() local_date = pytz.utc.localize(utc_date).astimezone(self.tzinfo) formated_string = local_date.strftime("%d/%m/%y %H:%M") self.send_message(bot, update.message.chat, formated_string) def command_echo(self, bot , update): self.send_message(bot, update.message.chat, update.message.text) def send_message(self, bot, chat, text): try: bot.sendMessage(chat_id=chat.id, text=text) return True except TelegramError as e: logger.warning("Message sending error to %s [%d] [%s] (TelegramError: %s)" % (chat.name, chat.id, chat.type, e)) return False except: logger.warning("Message sending error to %s [%d] [%s]" % (chat.name, chat.id, chat.type)) return False
class HaiBot(object): translations = {} bot = None def __init__(self): self.terraria = Terraria() self.play_status = None self.play_user = None #LANGUAGE STUFF self.language_list = os.listdir(haibot.config.get("haibot","LOCALE_DIR")) for l in self.language_list: self.translations[l] = gettext.translation("telegrambot", haibot.config.get("haibot","LOCALE_DIR"), languages=[l], fallback=True) try: if haibot.config.get("haibot","LANGUAGE") in self.language_list: translation_install(self.translations[haibot.config.get("haibot","LANGUAGE")]) else: translation_install(self.translations[DEFAULT_LANGUAGE]) except: translation_install(self.translations[DEFAULT_LANGUAGE]) # bot INICIALIZATION self.updater = Updater(token=haibot.config.get("haibot","TOKEN")) self.play_job_queue = self.updater.job_queue self.dispatcher = self.updater.dispatcher self.add_handlers() # Timezone Stuff try: self.tzinfo = pytz.timezone(haibot.config.get("haibot","TIMEZONE")) except: self.tzinfo = pytz.utc def start_polling_loop(self): self.disable_webhook() self.update_queue = self.updater.start_polling() self.updater.idle() self.cleaning() def start_webhook_server(self): # url/token/server_on | url/token/server_off | url/token/server_on?hostname | url/token/server_off?hostname from telegram.utils.webhookhandler import WebhookHandler from .terraria_server_urls import do_GET WebhookHandler.do_GET = do_GET self.set_webhook() self.update_queue = self.updater.start_webhook(haibot.config.get("haibot","IP"), haibot.config.getint("haibot","PORT"), haibot.config.get("haibot","TOKEN")) self.updater.idle() self.cleaning() def cleaning(self): with open(haibot.CONFIGFILE_PATH, "w") as configfile: haibot.config.write(configfile) haibot.logger.info("Saving config file...") haibot.logger.info("Finished program.") def set_webhook(self): s = self.updater.bot.setWebhook(haibot.config.get("haibot","WEBHOOK_URL") + "/" + haibot.config.get("haibot","TOKEN")) if s: haibot.logger.info("webhook setup worked") else: haibot.logger.warning("webhook setup failed") return s def disable_webhook(self): s = self.updater.bot.setWebhook("") if s: haibot.logger.info("webhook was disabled") else: haibot.logger.warning("webhook couldn't be disabled") return s def add_handlers(self): self.dispatcher.addTelegramCommandHandler("start", self.command_start) self.dispatcher.addTelegramCommandHandler("help", self.command_help) self.dispatcher.addTelegramCommandHandler("terraria", self.command_terraria) self.dispatcher.addTelegramCommandHandler("list", self.command_list) self.dispatcher.addTelegramCommandHandler("quote", self.command_quote) self.dispatcher.addTelegramCommandHandler("search", self.command_search) self.dispatcher.addTelegramCommandHandler("autonot", self.command_autonot) self.dispatcher.addTelegramCommandHandler("play", self.command_play) self.dispatcher.addTelegramCommandHandler("settings",self.command_settings) self.dispatcher.addTelegramCommandHandler("profile",self.command_profile) self.dispatcher.addUnknownTelegramCommandHandler(self.command_unknown) #self.dispatcher.addErrorHandler(self.error_handle) self.dispatcher.addStringCommandHandler("terraria_on", self.stringcommand_terraria_on) self.dispatcher.addStringCommandHandler("terraria_off", self.stringcommand_terraria_off) self.dispatcher.addStringCommandHandler("notify", self.stringcommand_notify) @save_user def command_start(self, bot, update, args): self.send_message(bot, update.message.chat_id, _("Bot was initiated. Use /help for commands.")) @save_user def command_help(self, bot, update, args): self.send_message(bot, update.message.chat_id, _( """Available Commands: /start - Iniciciate or Restart the bot /help - Show the command list. /terraria status/log/ip/milestone/on/off - Terraria options /list - Manage your lists (Use /list help) /quote - Save your group chat quotes (Use /quote help) /autonot on/off - Enable or disable autonotifications /play - Set \"want to play to X\" for a amount of hours [Autonot] /search engine word - Search using a engine. /settings - Change bot options (language, etc.) /profile - Show your user profile """)) @save_user def command_terraria(self, bot, update, args): chat = update.message.chat_id sender = update.message.from_user help_text = _( """Use one of the following commands: /terraria status - Server status (s) /terraria log <number> - Show Server history (l) /terraria ip - Display server IP (i) /terraria milestone - Add a milestone to server (m)[Autonot] /terraria on/off manually change server status [Autonot]""") if len(args) < 1: self.send_message(bot,chat, help_text) else: if args[0] == "status" or args[0] == "s": self.send_message(bot, chat, self.terraria.get_status()) elif args[0] == "log" or args[0] == "l": if len(args) > 1: try: log_text = self.terraria.get_log(int(args[1]), tzinfo=self.tzinfo) except: if args[1] == "m": log_text = self.terraria.get_log(5, only_milestone=True, tzinfo=self.tzinfo) else: log_text = _("/terraria log <number> - Number of log entries to show\n" "/terraria log m - Show only milestones") else: log_text = self.terraria.get_log(5, tzinfo=self.tzinfo) if log_text: self.send_message(bot, chat, log_text) else: self.send_message(bot, chat, _("There is no Log History")) elif args[0] == "autonot" or args[0] == "a": self.send_message(bot, chat, _("This is a legacy (v0.1) command.\n Use the new command: /autonot <on/off> ")) elif args[0] == "ip" or args[0] == "i": self.send_message(bot, chat, self.terraria.get_ip()) elif args[0] == "milestone" or args[0] == "m": if len(args) > 1: milestone_text = self.terraria.add_milestone(sender.name, " ".join(args[1:])) is_confirmated = self.send_message(bot, chat, milestone_text) self.autonotify(milestone_text, check_double=is_confirmated, previous_chat_id=chat) else: self.send_message(bot, chat,_("Use /terraria milestone <TEXT>")) elif args[0] == "on": if len(args) > 1: text = self.terraria.change_status(True, sender.name, args[1]) else: text = self.terraria.change_status(True, sender.name) self.send_message(bot, chat,_("Note: You can set a IP with:\n/terraria on <your ip>" )) is_confirmated = self.send_message(bot, chat, text) self.autonotify(text, check_double=is_confirmated, previous_chat_id=chat) elif args[0] == "off": text = self.terraria.change_status(False, sender.name) is_confirmated = self.send_message(bot, chat, text) self.autonotify(text, check_double=is_confirmated, previous_chat_id=chat) else: self.send_message(bot, chat, help_text) @save_user def command_list(self, bot, update, args): chat = update.message.chat_id sender = update.message.from_user current_list = profile.get_user_value(sender.id,"current_list") sender_is_writer = profile.get_user_value(sender.id, "is_writer") no_writer_text = _("You have no writting rights") no_reader_text = _("You have no reading rights") non_existent_list_text = _("List \"%s\" does not exist. Select another list with /list use") % (current_list) if not profile.get_user_value(sender.id,"is_reader"): self.send_message(bot, chat, no_reader_text) else: help_text = _( """Use one of the following commands: /list show <all:done:notdone> - show entries in the current list (s) /list <number> - Show only one entry using his index /list add - add a new entry to the current list (a) /list delete - delete an entry from the current list (d) /list lists <show:add:delete:clone> - manage lists (l) /list use - select a list (makes the list the current list) (u) /list writers <show:add:delete> - manage admins for the list (w) /list readers <show:add:delete> - manage readers for the list (if apply) (r) /list done - mark an entry as <done> (do) /list random - pick a random entry and show it (ra) /list search - show all entries matching a text (se)""") if len(args) < 1: self.send_message(bot, chat, help_text) else: if args[0] == "show" or args[0] == "s": show_help = False if len(args) <2: entry_list = lists.get_entries(current_list,mode="notdone") else: if args[1] == "done" or args[1] == "d": entry_list = lists.get_entries(current_list, mode="done") elif args[1] == "notdone" or args[1] == "n": entry_list = lists.get_entries(current_list, mode="notdone") elif args[1] == "all" or args[1] == "a": entry_list = lists.get_entries(current_list, mode="all") else: show_help = True if show_help: self.send_message(bot, chat, _("Use /list show <all:done:notdone>")) else: if lists.has_list(current_list): if entry_list: entry_text= "%s: \n" % (current_list) for entry in entry_list: if entry["done"]: entry_text += _("[%d][done] %s\n") % (entry["index"], entry["entry"] ) else: entry_text += "[%d] %s\n" % (entry["index"], entry["entry"] ) self.send_message(bot, chat, entry_text) else: self.send_message(bot, chat, _("Your list is empty")) else: self.send_message(bot, chat, non_existent_list_text ) elif args[0] == "add" or args[0] == "a": if len(args) <2: self.send_message(bot, chat, _("/list add <name>")) else: if sender_is_writer: new_entry = " ".join(args[1:]) if lists.has_list(current_list): new_index = lists.add_entry(new_entry,current_list, sender.name) self.send_message(bot, chat, _("Entry #%d was added to list \"%s\"") % (new_index, current_list)) else: self.send_message(bot, chat, non_existent_list_text ) else: self.send_message(bot, chat, no_writer_text) elif args[0] == "delete" or args[0] == "d": if len(args) <2: self.send_message(bot, chat, _("/list delete <entry index>")) else: if sender_is_writer: if lists.has_list(current_list): try: if lists.has_entry_index(int(args[1]), current_list): deleted_entry = lists.delete_entry(int(args[1]),current_list) self.send_message(bot, chat, _("Entry #%d was deleted from list \"%s\".")%(deleted_entry["index"], current_list)) else: self.send_message(bot, chat, _("The entry number does not exist. Use /list show")) except: self.send_message(bot, chat, _("Use /list delete <entry number>")) else: self.send_message(bot, chat, non_existent_list_text ) else: self.send_message(bot, chat, no_writer_text) elif args[0] == "lists" or args[0] == "l": if len(args) <2: self.send_message(bot, chat, "/list lists <show:add:delete:clone>") else: if args[1] == "show" or args[1] == "s": show_text = "" for list in lists.get_lists(enumerated=True): show_text += "%s: %s\n" % (str(list[0]), list[1]) if show_text: self.send_message(bot, chat, show_text) else: self.send_message(bot, chat, _("There is no lists. Create one.")) elif args[1] == "add" or args[1] == "a": if len(args) <3: self.send_message(bot, chat, _("/list lists add <something>")) else: if sender_is_writer: new_list = " ".join(args[2:]) if lists.has_list(new_list): self.send_message(bot, chat, _("\"%s\" already exists!") % (new_list)) else: list_index = lists.add_list(new_list, sender.name) self.send_message(bot, chat, _("\"%s\" list was created. Switch with /list use %d") % (new_list, list_index)) else: self.send_message(bot, chat, no_writer_text) elif args[1] == "delete" or args[1] == "d": if len(args) <3: self.send_message(bot, chat, _("/list lists delete <list index>")) else: if sender_is_writer: list_array = lists.get_lists(enumerated=True) was_deleted = False for list in list_array: try: if list[0] == int(args[2]): lists.delete_list(list[1]) was_deleted = True self.send_message(bot, chat, _("\"%s\" list was deleted. Use \"show\" for the new order. ")%(list[1])) except: was_deleted = False if not was_deleted: self.send_message(bot, chat, _("The list could not be deleted. Use:\n" "/list lists delete <list index>")) else: self.send_message(bot, chat, no_writer_text) elif args[1] == "clone" or args[1] == "c": if len(args) <4: self.send_message(bot, chat, _("Use: /list clone <list_index> new name")) else: if sender_is_writer: list_array = lists.get_lists(enumerated=True) was_cloned = False new_list = " ".join(args[3:]) if lists.has_list(new_list): self.send_message(bot, chat, _("Cannot be cloned. \"%s\" already exists!") % (new_list)) else: for list in list_array: try: if list[0] == int(args[2]): was_cloned = lists.clone_list(list[1], new_list, sender.name) if was_cloned: self.send_message(bot, chat, _("\"%s\" list was cloned to \"%s\" and" " entries were ordered.")%(list[1], new_list)) except: was_cloned = False if not was_cloned: self.send_message(bot, chat, _("The list could not be cloned. Use:\n" "Use: /list clone <list_index> new name")) else: self.send_message(bot, chat, no_writer_text) else: self.send_message(bot, chat, "/list lists <show:add:delete:clone>") elif args[0] == "use" or args[0] == "u": if len(args) <2: self.send_message(bot, chat, _("/list use <list ID>\nUse /list lists show for IDs")) else: enumerated_list = lists.get_lists(enumerated=True) is_changed = False for list in enumerated_list: try: if list[0] == int(args[1]): profile.set_user_value(sender.id, "current_list", list[1]) self.send_message(bot, chat, _("%s selected list: \"%s\"") % (sender.name, list[1]) ) is_changed = True except: is_changed = False if is_changed == False: self.send_message(bot, chat, _("/Invalid ID. Use /list lists show") ) elif args[0] == "writers" or args[0] == "w": if len(args) <2: self.send_message(bot, chat, "/list writers <show:add:delete:clone>") else: if args[1] == "show" or args[1] == "s": show_text = "" for list in profile.get_users("is_writer",with_name=True): show_text += "%s: %s\n" % (list["user_id"], list["user_name"]) if show_text: self.send_message(bot, chat, show_text) else: self.send_message(bot, chat, _("There is no writers.")) haibot.logger.warning("No writers. There should be one. Add bot owner to config file") elif args[1] == "add" or args[1] == "a": add_writers_help = _("/list writer add ID.\n Use \"/profile list\" for a list of known IDs") if len(args) <3: self.send_message(bot, chat, add_writers_help) else: if sender_is_writer: try: new_writer = int(args[2]) if profile.has_user(new_writer): profile.set_user_value(new_writer, "is_writer", True) self.send_message(bot, chat, _("writer rights for (ID:%d) were added") % (new_writer)) else: self.send_message(bot, chat, add_writers_help) except: self.send_message(bot, chat, add_writers_help) else: self.send_message(bot, chat, no_writer_text) elif args[1] == "delete" or args[1] == "d": delete_writers_help = _("/list writer delete ID.\n Use \"/list writers show\" for a list of writers IDs") if len(args) <3: self.send_message(bot, chat, delete_writers_help) else: if sender_is_writer: try: del_writer = int(args[2]) if profile.has_user(del_writer): if del_writer != sender.id: profile.set_user_value(del_writer, "is_writer", False) self.send_message(bot, chat, _("writer rights for (ID:%d) were deleted") % (del_writer)) else: self.send_message(bot, chat, _("You can't delete your own rights")) else: self.send_message(bot, chat, delete_writers_help) except: self.send_message(bot, chat, delete_writers_help) else: self.send_message(bot, chat, no_writer_text) else: self.send_message(bot, chat, "/list writers <show:add:delete>") elif args[0] == "readers" or args[0] == "r": if len(args) <2: self.send_message(bot, chat, "/list readers <show:add:delete:clone>") else: if args[1] == "show" or args[1] == "s": show_text = "" for list in profile.get_users("is_reader",with_name=True): show_text += "%s: %s\n" % (list["user_id"], list["user_name"]) if show_text: self.send_message(bot, chat, show_text) else: self.send_message(bot, chat, _("There is no readers.")) haibot.logger.warning("No readers. There should be one. Add bot owner to config file") elif args[1] == "add" or args[1] == "a": add_readers_help = _("/list reader add ID.\n Use \"/profile list\" for a list of known IDs") if len(args) <3: self.send_message(bot, chat, add_readers_help) else: if sender_is_writer: try: new_reader = int(args[2]) if profile.has_user(new_reader): profile.set_user_value(new_reader, "is_reader", True) self.send_message(bot, chat, _("reader rights for (ID:%d) were added") % (new_reader)) else: self.send_message(bot, chat, add_readers_help) except: self.send_message(bot, chat, add_readers_help) else: self.send_message(bot, chat, no_writer_text) elif args[1] == "delete" or args[1] == "d": delete_readers_help = _("/list reader delete ID.\n Use \"/list readers show\" for a list of readers IDs") if len(args) <3: self.send_message(bot, chat, delete_readers_help) else: if sender_is_writer: try: del_reader = int(args[2]) if profile.has_user(del_reader): if del_reader != sender.id: profile.set_user_value(del_reader, "is_reader", False) self.send_message(bot, chat, _("reader rights for (ID:%d) were deleted") % (del_reader)) else: self.send_message(bot, chat, _("You can't delete your own rights")) else: self.send_message(bot, chat, delete_readers_help) except: self.send_message(bot, chat, delete_readers_help) else: self.send_message(bot, chat, no_writer_text) else: self.send_message(bot, chat, "/list readers <show:add:delete>") elif args[0] == "done" or args[0] == "do": if len(args) <2: self.send_message(bot, chat, _("/list done <entry index>")) else: if sender_is_writer: if lists.has_list(current_list): try: if lists.has_entry_index(int(args[1]), current_list): entry, done_status = lists.toogle_done_entry(int(args[1]),current_list) if done_status: self.send_message(bot, chat,_("#%d: done (list:%s)")%(entry["index"],current_list)) self.send_message(bot, chat,_("See: \list show <all:done:notdone>")) else: self.send_message(bot, chat,_("#%d: notdone (list:%s)")%(entry["index"],current_list)) else: self.send_message(bot, chat, _("The entry number does not exist. Use /list show all")) except: self.send_message(bot, chat, _("Use /list done <entry number>")) else: self.send_message(bot, chat, non_existent_list_text ) else: self.send_message(bot, chat, no_writer_text) elif args[0] == "random" or args[0] == "ra": if lists.has_list(current_list): entry = lists.get_random_entry(current_list) if entry: if entry["done"] == True: self.send_message(bot, chat, _("[%d][done] %s\n") % (entry["index"], entry["entry"])) else: self.send_message(bot, chat, "[%d] %s\n" % (entry["index"], entry["entry"])) else: self.send_message(bot, chat, _("Your list is empty")) else: self.send_message(bot, chat, non_existent_list_text ) elif args[0] == "search" or args[0] == "se": if len(args) <2: self.send_message(bot, chat, _("/list search <words>")) else: if lists.has_list(current_list): result = lists.search_entries(" ".join(args[1:]), current_list) if result: self.send_message(bot, chat, result) else: self.send_message(bot, chat, _("No entries were found")) else: self.send_message(bot, chat, non_existent_list_text ) else: try: if lists.has_entry_index(int(args[0]), current_list ) : if lists.has_list(current_list): entry = lists.get_entry( int(args[0]), current_list) if entry["done"] == True: self.send_message(bot, chat, _("[%d][done] %s\n") % (entry["index"], entry["entry"])) else: self.send_message(bot, chat, "[%d] %s\n" % (entry["index"], entry["entry"])) else: self.send_message(bot, chat, non_existent_list_text ) else: self.send_message(bot, chat, _("Invalid number. Use /list show o /list search <word>")) except: self.send_message(bot, chat, help_text) @save_user def command_quote(self, bot, update, args): chat = update.message.chat_id sender = update.message.from_user no_write = _("You have no writting rights. See /list writers") help_text = _( "You can add a quote, selecting a message and clicking on \"reply\" and then writting /quote\n\n" "/quote search - show all quote matching a text (s/se)\n" "/quote <number> show the quote associated to a index\n" "/quote delete - delete a quote (d)\n" "/quote random - pick a random quote and show it (r/ra)\n" "/quote islist - Show the quotes as a list in the command /list (i/is)") if len(args) < 1: if update.message.reply_to_message: username = update.message.reply_to_message.from_user.name new_quote = update.message.reply_to_message.text new_index = lists.add_entry(new_quote, "quote", username) if not new_index: self.send_message(bot, chat, _("Error: There is not Quote List in database. Use: /list lists add quote")) haibot.logger.warning("There is not Quote List in database.") else: self.send_message(bot, chat, _("Quote #%d was recorded") % (new_index)) else: self.send_message(bot, chat, help_text) else: if args[0] == "delete" or args[0] == "d": if len(args) <2: self.send_message(bot, chat, _("/quote delete <entry index>")) else: if profile.get_user_value(sender.id, "is_writer"): try: if lists.has_entry_index(int(args[1]), "quote"): deleted_entry = lists.delete_entry(int(args[1]), "quote") self.send_message(bot, chat, _("Quote #%d was deleted.")%(deleted_entry["index"])) else: self.send_message(bot, chat, _("The quote number does not exist. Use /quote search <word>")) except: self.send_message(bot, chat, _("Use /quote delete <entry number>")) else: self.send_message(bot, chat, no_write) elif args[0] == "random" or args[0] == "r" or args[0] == "ra" : entry = lists.get_random_entry("quote") if entry: self.send_message(bot, chat, "*%s*\n`[%d] %s`\n" % (entry["owner"], entry["index"], entry["entry"]), with_markdown=True) else: self.send_message(bot, chat, _("There is no quotes")) elif args[0] == "search" or args[0] == "s" or args[0] == "se": if len(args) <2: self.send_message(bot, chat, _("/quote search <words>")) else: result = lists.search_entries(" ".join(args[1:]), "quote") if result: self.send_message(bot, chat, result) else: self.send_message(bot, chat, _("No quotes were found")) elif args[0] == "islist" or args[0] == "i" or args[0] == "is": if profile.get_user_value(sender.id, "is_writer"): hidden = lists.toogle_hidden_list("quote") if not hidden: self.send_message(bot, chat, _("The quotes are now a list.\nBe careful: all the quotes can now be deleted, cloned or full showed")) else: self.send_message(bot, chat, _("The quotes are now hidden in list command.")) else: self.send_message(bot, chat, no_write) else: try: if lists.has_entry_index(int(args[0]), "quote" ) : entry = lists.get_entry( int(args[0]), "quote") self.send_message(bot, chat, "*%s*\n`[%d] %s`\n" % (entry["owner"], entry["index"], entry["entry"]), with_markdown=True) else: self.send_message(bot, chat, _("Invalid number. Use /quote search <word>")) except: self.send_message(bot, chat, help_text) @save_user def command_autonot(self, bot, update, args): sender = update.message.from_user chat = update.message.chat_id if len(args) > 0: if args[0] == "on": profile.set_user_value(sender.id,"in_autonot", True) self.send_message(bot, chat, sender.name+_(" was added to auto notifications.")) elif args[0] == "off": profile.set_user_value(sender.id,"in_autonot", False) self.send_message(bot, chat, sender.name+_(" was removed from auto notifications.")) else: self.send_message(bot, chat, "/terraria autonot\n/terraria autonot on/off") else: if profile.get_user_value(sender.id, "in_autonot"): profile.set_user_value(sender.id,"in_autonot", False) self.send_message(bot, chat, sender.name+_(" was removed from auto notifications.")) else: profile.set_user_value(sender.id,"in_autonot", True) self.send_message(bot, chat, sender.name+_(" was added to auto notifications.")) @save_user def command_play(self, bot, update, args): sender = update.message.from_user chat = update.message.chat_id help_text = _("/play <hours> <game> - Display that you are playing a game for X hours. " "(Example: play 2.5 dota2 ). The message will be sent to users with autonot enabled. " "Another notification will be sent automatically when the time indicated elapses. \n\n" "/play status - Display the play message if there is one active \n" "/play stop - Manually stops the play, instead of waiting that the time elapses ") if len(args) < 1: self.send_message(bot, chat, help_text ) if len(args) < 2: if args[0] == "status" or args[0] == "s": if self.play_job_queue.running: self.send_message(bot, chat, self.play_status) else: self.send_message(bot, chat, _("There is not \"play\" ongoing")) elif args[0] == "stop" or args[0] == "st": if self.play_user == sender.name: if self.play_job_queue.running: self.stop_play(bot) self.send_message(bot, chat, _("Done.")) else: self.send_message(bot, chat, _("You can only stop your own \"play\"")) else: self.send_message(bot, chat, _("There is not \"play\" to stop.")) else: self.send_message(bot, chat, help_text ) else: try: total_hours = float(args[0]) if total_hours > MAX_PLAY_HOURS: self.send_message(bot, chat, _("The max number of hours allowed is %d") % (MAX_PLAY_HOURS)) elif total_hours < 0.02: self.send_message(bot, chat, _("You tried to set up less than 1 minute of play")) else: if not self.play_job_queue.running: game = " ".join(args[1:]) hour = datetime.now(self.tzinfo) hour_until = (hour + timedelta(hours=total_hours)).strftime("%H:%M") self.play_user = sender.name self.play_status = _("%s is ready to play: %s (until %s)") % (sender.name, game, hour_until ) self.send_message(bot, chat, _("A notification was sent to all subscribed users. Use /autonot for subscribing")) self.autonotify(self.play_status) self.play_job_queue.put(self.stop_play, total_hours*60*60, repeat=False) else: self.send_message(bot, chat, _("There is already a play. See /play status for info.")) except: self.send_message(bot, update.message.chat_id, help_text ) @save_user def command_search(self, bot, update, args): self.send_message(bot, update.message.chat_id, _("NOT IMPLEMENTED")) @save_user def command_settings(self, bot,update, args): chat = update.message.chat_id languages_codes_text = _("Language codes:\n") for lang in self.language_list: languages_codes_text+= "<"+lang+"> " help_text = _("Use /settings language language_code\n\n" + languages_codes_text) if len(args) < 2: self.send_message(bot, chat, help_text) else: if args[0] == "language" or args[0] == "l": if args[1] in self.language_list: try: haibot.config.set("haibot","LANGUAGE", args[1] ) translation_install(self.translations[haibot.config.get("haibot","LANGUAGE")]) self.send_message(bot, chat, _("Language changed to %s") % (args[1])) haibot.logger.info("Language was changed to %s" % (args[1])) except: haibot.logger.info("A error happened changing language to %s" % (args[1])) else: self.send_message(bot, chat, _("Unknown language code\n\n" + languages_codes_text)) else: self.send_message(bot, chat, help_text) @save_user def command_profile(self, bot, update,args): if len(args) < 1: user = profile.get_user(update.message.from_user.id) profile_text = "" if user: for i in user: profile_text += "%s = %s\n" % (str(i), str(user[i])) else: profile_text = _("Could not get user profile") else: if args[0] == "list" or args[0] == "l": users = profile.get_allusers(projection={"user_id":True, "user_name":True }) profile_text = "" if users: for u in users: profile_text += "%s : %s\n" % (str(u["user_id"]), u["user_name"]) else: profile_text = _("Could not get profile list") else: try: profile_id = int(args[0]) user = profile.get_user(profile_id) profile_text = "" if user: for i in user: profile_text += "%s = %s\n" % (str(i), str(user[i])) else: profile_text = _("Could not get profile from user <%s>") % (profile_id) except: profile_text = _("Use a profile ID with only numbers") self.send_message(bot, update.message.chat_id, profile_text) @save_user def command_unknown(self, bot, update,args): self.send_message(bot, update.message.chat_id, _("%s is a unknown command. Use /help for available commands.") % (update.message.text)) # /terraria_on IP user def stringcommand_terraria_on(self, bot, update, args): if len(args) > 1: text = self.terraria.change_status(True, " ".join(args[1:]), args[0]) else: text = self.terraria.change_status(True) self.autonotify(text) # /terraria_off user def stringcommand_terraria_off(self, bot, update, args): if len(args) > 0: text = self.terraria.change_status(False, " ".join(args[0:])) else: text = self.terraria.change_status(False) self.autonotify(text) # /notify ID text def stringcommand_notify(self, bot, update, args): self.send_message(bot, int(args[0]), " ".join(args[1:])) def autonotify(self, text, check_double=False, previous_chat_id=None ): autonot_list = profile.get_users("in_autonot") for user in autonot_list: if check_double and user["user_id"] == previous_chat_id: break else: text_to_queue = str("/notify %s %s" % (user["user_id"], text)) self.update_queue.put(text_to_queue) def stop_play(self,bot): self.autonotify( self.play_user + _(" stopped playing.")) self.play_job_queue.stop() self.play_status = None self.play_user = None def send_message(self, bot, chat_id, text, with_markdown=False): try: if with_markdown: bot.sendMessage(chat_id=chat_id, text=text, disable_web_page_preview=True, parse_mode="Markdown") else: bot.sendMessage(chat_id=chat_id, text=text, disable_web_page_preview=True) return True except TelegramError as e: try: user_name = profile.get_user_value(chat_id, "user_name") except: user_name = "unknown" haibot.logger.warning("A Message could not be sent to User: %s [%d] (TelegramError: %s)" % (user_name, chat_id , e)) return False except: haibot.logger.warning("A Message could not be sent:\n%s " % (text)) return False
class Bot(object): translations = {} bot = None def __init__(self): self.config = configparser.ConfigParser() self.config.read(CONFIGFILE_PATH) self.updater = Updater(token=self.get_bot_conf("TOKEN")) self.dispatcher = self.updater.dispatcher self.add_handlers() try: self.tzinfo = timezone(self.get_bot_conf("TIMEZONE")) except: self.tzinfo = pytz.utc def get_bot_conf(self, value): return self.config["bot"][value] def get_env_conf(self, value, default_value=None): if default_value: return os.environ.get(self.config["env"][value], default_value) else: return os.environ.get(self.config["env"][value]) def start_polling_loop(self): self.disable_webhook() self.update_queue = self.updater.start_polling() self.updater.idle() self.cleaning() def start_webhook_server(self): self.set_webhook() self.update_queue = self.updater.start_webhook( self.get_env_conf("IP", "127.0.0.1"), int(self.get_env_conf("PORT", "8080")), self.get_bot_conf("TOKEN")) self.updater.idle() self.cleaning() def cleaning(self): logger.info("Finished program.") def set_webhook(self): s = self.updater.bot.setWebhook( self.get_bot_conf("WEBHOOK_URL") + "/" + self.get_bot_conf("TOKEN")) if s: logger.info("webhook setup worked") else: logger.warning("webhook setup failed") return s def disable_webhook(self): s = self.updater.bot.setWebhook("") if s: logger.info("webhook was disabled") else: logger.warning("webhook couldn't be disabled") return s def add_handlers(self): self.dispatcher.addTelegramCommandHandler("start", self.command_start) self.dispatcher.addTelegramCommandHandler("help", self.command_help) self.dispatcher.addTelegramCommandHandler("time", self.command_time) self.dispatcher.addTelegramMessageHandler(self.command_echo) #self.dispatcher.addUnknownTelegramCommandHandler(self.command_unknown) #self.dispatcher.addErrorHandler(self.error_handle) def command_start(self, bot, update): self.send_message(bot, update.message.chat, _("Welcome to Dungeon World Bot.")) def command_help(self, bot, update): self.send_message( bot, update.message.chat, _("""Available Commands: /start - Iniciciate or Restart the bot /help - Show the command list. /time - Bot local time check""")) def command_time(self, bot, update): utc_date = datetime.utcnow() local_date = pytz.utc.localize(utc_date).astimezone(self.tzinfo) formated_string = local_date.strftime("%d/%m/%y %H:%M") self.send_message(bot, update.message.chat, formated_string) def command_echo(self, bot, update): self.send_message(bot, update.message.chat, update.message.text) def send_message(self, bot, chat, text): try: bot.sendMessage(chat_id=chat.id, text=text) return True except TelegramError as e: logger.warning( "Message sending error to %s [%d] [%s] (TelegramError: %s)" % (chat.name, chat.id, chat.type, e)) return False except: logger.warning("Message sending error to %s [%d] [%s]" % (chat.name, chat.id, chat.type)) return False