예제 #1
0
class Telegram(Channel):
    name: str = "Telegram"

    updater: Updater
    update: Update

    last_message: str = None

    def save_message(self, update: Update, context: CallbackContext):
        self.update = update
        self.last_message = update.message.text

    def __init__(self):
        self.updater = Updater(
            "1647754237:AAGo-sBhgQvyyZjm6Y94_pjENirXpwmqiDE")

        echo_handler = MessageHandler(Filters.text & (~Filters.command),
                                      self.save_message)
        self.updater.dispatcher.add_handler(echo_handler)

        self.updater.start_polling()

    def get_input(self) -> str:
        last_message = self.last_message

        while True:
            time.sleep(1)
            if last_message != self.last_message:
                return self.last_message

    def output(self, output: str):
        self.updater.bot.send_message(chat_id=self.update.effective_chat.id,
                                      text=output)
예제 #2
0
def main():
    updater = Updater(TELEGRAM["token"])
    dp = updater.dispatcher

    dp.add_handler(CallbackQueryHandler(answer_callback))
    updater.start_polling()
    updater.idle()
예제 #3
0
def main():
    TOKEN = '<YOUR TOKEN>'
    updater = Updater(TOKEN, use_context=True)
    dp = updater.dispatcher
    dp.add_handler(CommandHandler("start", start))
    dp.add_handler(CommandHandler("set", set_vars))
    dp.add_handler(CommandHandler("help", help))
    dp.add_handler(CommandHandler("send", b_send))
    dp.add_handler(CommandHandler("show", show))
    dp.add_handler(CommandHandler("exchange", exchange))
    updater.start_polling()
    updater.idle()
예제 #4
0
파일: bot.py 프로젝트: Maliaotw/RssNews
def main():
    # MarioNews_bot
    tg_token = get_tg_admin_token()
    updater = Updater(tg_token)
    updater.dispatcher.add_handler(CommandHandler('start', start))
    updater.dispatcher.add_handler(CommandHandler('help', start))
    updater.dispatcher.add_handler(CommandHandler('echo', echo))
    updater.dispatcher.add_handler(CommandHandler('hello', hello))
    updater.dispatcher.add_handler(CommandHandler('favor', favor))
    updater.dispatcher.add_handler(CommandHandler('binduser', binduser, pass_args=True))
    updater.start_polling()
    updater.idle()
예제 #5
0
    def init_bot(self):
        log.debug('initiating connection to telegram bot')
        updater = Updater(token=self.bot_token)
        dispatcher = updater.dispatcher

        handlers, error_handlers = get_handler_lists()
        for handler in handlers:
            log.debug('registering handler %s', repr(handler))
            dispatcher.add_handler(handler)
        for error_handler in error_handlers:
            log.debug('registering error handler %s', repr(error_handler))
            dispatcher.add_error_handler(error_handler)
        updater.start_polling()
        updater.idle()
예제 #6
0
def main():
    db.create_tables([
        File, Publication, Vote, ParsingSource, VkPhoto, Contributor, Moderator
    ],
                     safe=True)
    load_parsing_sources()
    updater = Updater(cfg.token)
    dp = updater.dispatcher
    references.set_bot_reference(updater.bot)
    [dp.add_handler(handler) for handler in handlers]
    dp.add_error_handler(error)
    updater.start_polling()
    publication_service.prepare_publications()
    schedule = Schedule()
    schedule.start()
    updater.idle()
예제 #7
0
def start_bot_thread():
    print("Start bot Thread started...")
    updater = Updater(main_bot_token)
    dispatcher = updater.dispatcher
    # logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)
    photo = MessageHandler(Filters.photo, photo_handler)
    video = MessageHandler(Filters.video, video_handler)
    audio = MessageHandler(Filters.audio, audio_handler)
    voice = MessageHandler(Filters.voice, voice_handler)
    document = MessageHandler(Filters.document, document_handler)
    view_q = CommandHandler('viewqueue', view_queue_handler)
    view_c = CommandHandler('viewchannel', view_target_channel)
    change_c = CommandHandler('changechannel', change_target_channel)
    empty_q = CommandHandler('emptyqueue', empty_queue_handler)
    delete_p = CommandHandler('deletepost',
                              delete_post_handler,
                              pass_args=True)
    send_p = CommandHandler('sendpost', manual_send_handler, pass_args=True)
    get_q = CommandHandler('getqueue', get_queue_handler)
    get_t = CommandHandler('gettasks', get_tasks_handler)
    get_t_z_d = CommandHandler('gettimediff', get_time_zone_diff_handler)
    set_t_z_d = CommandHandler('settimediff',
                               set_time_zone_diff_handler,
                               pass_args=True)

    dispatcher.add_handler(photo)
    dispatcher.add_handler(video)
    dispatcher.add_handler(audio)
    dispatcher.add_handler(voice)
    dispatcher.add_handler(document)
    dispatcher.add_handler(view_q)
    dispatcher.add_handler(view_c)
    dispatcher.add_handler(change_c)
    dispatcher.add_handler(empty_q)
    dispatcher.add_handler(delete_p)
    dispatcher.add_handler(send_p)
    dispatcher.add_handler(get_q)
    dispatcher.add_handler(get_t)
    dispatcher.add_handler(get_t_z_d)
    dispatcher.add_handler(set_t_z_d)
    updater.start_polling()
    print("Ending initialization of the bot...")
예제 #8
0
    def __init__(self):
        self.config = {"api_token": os.getenv("API_TOKEN")}

        self.db = load_db()

        updater = Updater(self.config["api_token"])
        dp = updater.dispatcher  # type: Dispatcher

        dp.add_handler(WelcomeConversationHandler(self))
        dp.add_handler(NewOpConversationHandler(self, updater.bot))
        dp.add_handler(OrderConversationHandler(self))
        dp.add_handler(CommandHandler("myorders", self.command_myorders))
        dp.add_handler(ListOpportunitiesConversationHandler(self))

        # Todo: /notify (marudor-only) (Benachrichtigt alle Nutzer in einer Stadt)

        dp.add_handler(MessageHandler(Filters.text, self.handle_fetch_op))

        dp.add_error_handler(self.handle_error)

        updater.start_polling()
        updater.idle()
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_bootstrap_retries_success(self):
        retries = 3
        self._setup_updater('', messages=0, bootstrap_retries=retries)

        self.updater._set_webhook('path', retries)
        self.assertEqual(self.updater.bot.bootstrap_attempts, retries)

    def test_bootstrap_retries_unauth(self):
        retries = 3
        self._setup_updater('', messages=0, bootstrap_retries=retries,
                            bootstrap_err=Unauthorized())

        self.assertRaises(Unauthorized, self.updater._set_webhook, 'path',
                          retries)
        self.assertEqual(self.updater.bot.bootstrap_attempts, 1)

    def test_bootstrap_retries_invalid_token(self):
        retries = 3
        self._setup_updater('', messages=0, bootstrap_retries=retries,
                            bootstrap_err=InvalidToken())

        self.assertRaises(InvalidToken, self.updater._set_webhook, 'path',
                          retries)
        self.assertEqual(self.updater.bot.bootstrap_attempts, 1)

    def test_bootstrap_retries_fail(self):
        retries = 1
        self._setup_updater('', messages=0, bootstrap_retries=retries)

        self.assertRaisesRegexp(TelegramError, 'test',
                                self.updater._set_webhook, 'path', retries - 1)
        self.assertEqual(self.updater.bot.bootstrap_attempts, 1)

    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, 0, 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)
예제 #10
0
# getting the dispatcher required to handle the command /start and send message back to the user
# documentation: https://python-telegram-bot.readthedocs.io/en/latest/telegram.ext.dispatcher.html#telegram.ext.Dispatcher
dispatcher: Dispatcher = updater.dispatcher


def start(update: Update, context: CallbackContext):
    """
    the callback for handling start command
    """
    # getting the bot from context
    # documentation: https://python-telegram-bot.readthedocs.io/en/latest/telegram.bot.html#telegram-bot
    bot: Bot = context.bot

    # sending message to the chat from where it has received the message
    # documentation: https://python-telegram-bot.readthedocs.io/en/latest/telegram.bot.html#telegram.Bot.send_message
    bot.send_message(chat_id=update.effective_chat.id,
                     text="You have just entered start command")


# register a handler (here command handler)
# documentation: https://python-telegram-bot.readthedocs.io/en/latest/telegram.ext.dispatcher.html#telegram.ext.Dispatcher.add_handler
dispatcher.add_handler(
    # it can accept all the telegram.ext.Handler, CommandHandler inherits Handler class
    # documentation: https://python-telegram-bot.readthedocs.io/en/latest/telegram.ext.commandhandler.html#telegram-ext-commandhandler
    CommandHandler("start", start))

# starting polling updates from Telegram
# documentation: https://python-telegram-bot.readthedocs.io/en/latest/telegram.ext.updater.html#telegram.ext.Updater.start_polling
updater.start_polling()
예제 #11
0
class TelegramManager(Component):
    INTERCOM_MESSAGE_EVENT_CHAT_START = 'telegram-event-chat-start'
    INTERCOM_MESSAGE_EVENT_CHAT_MESSAGE = 'telegram-event-chat-message'

    INTERCOM_MESSAGE_DO_VIDEO_MESSAGE = 'telegram-do-video-message'
    INTERCOM_MESSAGE_DO_PHOTO_MESSAGE = 'telegram-do-photo-message'
    INTERCOM_MESSAGE_DO_DOCUMENT_MESSAGE = 'telegram-do-document-message'

    INTERCOM_MESSAGE_DO_CHAT_MESSAGE = 'telegram-do-chat-message'
    INTERCOM_MESSAGE_DO_SEND_CAM_SNAPSHOT = 'telegram-do-send-cam-snapshot'
    INTERCOM_MESSAGE_DO_SEND_CAM_VIDEO = 'telegram-do-send-cam-video'

    _allowed_users = []
    _token = None
    _current_token = None
    _updater = None
    _bot = None

    _runtime_file_mutex = Lock()

    _chat_ids = {}

    def _get_settings_file(cls):
        return App.get_settings_path() + '/telegram.yml'

    def _get_runtime_file(cls):
        return App.get_settings_path() + '/telegram_runtime.yml'

    def _load_runtime(self):
        self._chat_ids = {}

        runtime_file = self._get_runtime_file()
        try:
            runtime = yaml.load(open(runtime_file, 'r'))
            Log.info("Loading runtime from " + runtime_file)
        except:
            Log.error("Loading runtime failed from " + runtime_file)
            return

        self._chat_ids = runtime['chat_ids']

    def _save_runtime(self):
        runtime_file = self._get_runtime_file()

        runtime = {'chat_ids': self._chat_ids}

        self._runtime_file_mutex.acquire()
        yaml.dump(runtime, open(runtime_file, 'w'), default_flow_style=False)
        self._runtime_file_mutex.release()

    def _add_chat_id(self, user, chat_id):
        must_save = (user not in self._chat_ids
                     or self._chat_ids[user] != chat_id)
        self._chat_ids[user] = chat_id

        if must_save:
            self._save_runtime()

    def get_variables(self):
        if self.get_bot() is not None:

            return {
                'telegram_bot_name': self.get_bot().username,
                'telegram_bot_first_name': self.get_bot().first_name,
                'telegram_bot_last_name': self.get_bot().last_name,
            }
        else:
            return {}

    def load_settings(self):
        self._allowed_users = []

        settings_file = self._get_settings_file()
        try:
            settings = yaml.load(open(settings_file, 'r'))
            Log.info("Loading settings from " + settings_file)
        except:
            Log.error("Loading settings failed from " + settings_file)
            return

        self._token = settings['token']
        self._allowed_users = settings['users']

    def get_is_allowed_message(self, update: Update):
        """
        Return true if user is allowed to send messages
        :param update:
        :return:
        """
        return update.message.from_user.username in self._allowed_users

    def get_bot(self) -> Bot:
        return self._bot

    def get_chat_id(self, username):
        if username not in self._chat_ids:
            return None

        return self._chat_ids[username]

    def send_message(self, text, recipients=None):
        if recipients is None:
            recipients = self._allowed_users

        for recipient in recipients:
            chat_id = self.get_chat_id(recipient)
            if chat_id is not None:
                self.get_bot().sendMessage(chat_id, text)
            else:
                Log.error('Unknown chat ID for user ' + recipient +
                          ', please send a message to this bot')

    def send_picture(self, file_name, caption=None, recipients=None):
        if file_name is None:
            return

        try:
            if recipients is None:
                recipients = self._allowed_users

            for recipient in recipients:
                chat_id = self.get_chat_id(recipient)
                if chat_id is not None:
                    self.get_bot().sendPhoto(chat_id=chat_id,
                                             photo=open(file_name, 'rb'),
                                             caption=caption)
                else:
                    Log.error('Unknown chat ID for user ' + recipient +
                              ', please send a message to this bot')
        except telegram.error.BadRequest:
            pass

        except FileNotFoundError:
            Log.error('File ' + file_name + ' not found')

    def send_video(self, file, caption=None, recipients=None):
        if file is None:
            return

        try:
            if recipients is None:
                recipients = self._allowed_users

            for recipient in recipients:
                chat_id = self.get_chat_id(recipient)
                if chat_id is not None:
                    self.get_bot().sendDocument(
                        chat_id=chat_id,
                        document=open(file, 'rb'),
                        filename=os.path.basename(file),
                        caption=caption)
                else:
                    Log.error('Unknown chat ID for user ' + recipient +
                              ', please send a message to this bot')
        except telegram.error.BadRequest:
            pass

        except FileNotFoundError:
            Log.error('File ' + file + ' not found')

    send_document = send_video

    def _on_intercom_message_send_chat(self, message: Message) -> Reply:
        payload = message.message_payload

        recipients = None
        if 'to' in payload:
            recipients = re.split(r'\s*,\s*', payload['to'])

        self.send_message(text=payload['text'], recipients=recipients)
        return Reply(Reply.INTERCOM_STATUS_SUCCESS)

    def _send_cam_snapshot(self, cam: Cam, recipients):
        cam_snapshot = self.send_intercom_message(
            CamManager.INTERCOM_MESSAGE_DO_SNAPSHOT, {'cam': cam})

        if cam_snapshot != Reply.INTERCOM_STATUS_SUCCESS:
            return

        caption = CamRepo.get_by_code(cam).name

        reply_payload = cam_snapshot.get_payload()
        for from_component, component_payload in reply_payload.items():
            if component_payload['status'] == Reply.INTERCOM_STATUS_SUCCESS and \
                            from_component == CamManager.get_instance().get_code():

                file_name = component_payload['payload']['filename']

                # Async upload
                threading.Thread(target=self.send_picture,
                                 kwargs={
                                     'file_name': file_name,
                                     'caption': caption,
                                     'recipients': recipients,
                                 }).start()

    def _send_cam_video(self, cam: Cam, recipients, duration):
        res = self.send_intercom_message(
            CamManager.INTERCOM_MESSAGE_DO_VIDEO_START, {'cam': cam})

        if res != Reply.INTERCOM_STATUS_SUCCESS:
            return

        time.sleep(duration)

        res = self.send_intercom_message(
            CamManager.INTERCOM_MESSAGE_DO_VIDEO_STOP, {'cam': cam})

        if res != Reply.INTERCOM_STATUS_SUCCESS:
            return

        caption = CamRepo.get_by_code(cam).name

        reply_payload = res.get_payload()
        for from_component, component_payload in reply_payload.items():
            if component_payload['status'] == Reply.INTERCOM_STATUS_SUCCESS and \
                            from_component == CamManager.get_instance().get_code():
                file_name = component_payload['payload']['filename']

                # Async upload
                threading.Thread(target=self.send_video,
                                 kwargs={
                                     'file_name': file_name,
                                     'caption': caption,
                                     'recipients': recipients,
                                 }).start()

    def _on_cam_action(self, message: Message) -> Reply:
        payload = message.message_payload

        cams = payload['cam'].split(',')
        for cam in cams:
            recipients = None
            if 'to' in payload:
                recipients = re.split(r'\s*,\s*', payload['to'])

            if message == self.INTERCOM_MESSAGE_DO_SEND_CAM_SNAPSHOT:
                self._send_cam_snapshot(cam=cam, recipients=recipients)

            elif message == self.INTERCOM_MESSAGE_DO_SEND_CAM_VIDEO:
                duration = 10
                if 'duration' in message.message_payload:
                    duration = message.message_payload['duration']

                self._send_cam_video(cam=cam,
                                     recipients=recipients,
                                     duration=duration)

        return Reply(Reply.INTERCOM_STATUS_SUCCESS)

    def _on_intercom_message_cam_action(self, message: Message) -> Reply:
        payload = message.message_payload

        cams = payload['cam'].split(',')
        for cam in cams:
            recipients = None
            if 'to' in payload:
                recipients = re.split(r'\s*,\s*', payload['to'])

            # Async images send
            threading.Thread(target=self._on_cam_action,
                             kwargs={
                                 'cam': cam,
                                 'recipients': recipients
                             }).start()

        return Reply(Reply.INTERCOM_STATUS_SUCCESS)

    def _on_intercom_message_complex_message(self, message: Message) -> Reply:
        payload = message.message_payload

        filename = message.message_payload['filename']
        if not os.path.isfile(filename) or not App.can_access_file(filename):
            return Reply(Reply.INTERCOM_STATUS_NON_BLOCKING_FAILURE)

        caption = os.path.basename()
        if 'caption' in message.message_payload:
            caption = message.message_payload[filename]

        recipients = None
        if 'to' in payload:
            recipients = re.split(r'\s*,\s*', payload['to'])

        if message == self.INTERCOM_MESSAGE_DO_PHOTO_MESSAGE:
            self.send_picture(file_name=filename,
                              caption=caption,
                              recipients=recipients)

        elif message == self.INTERCOM_MESSAGE_DO_VIDEO_MESSAGE:
            self.send_video(file=filename,
                            caption=caption,
                            recipients=recipients)

        elif message == self.INTERCOM_MESSAGE_DO_DOCUMENT_MESSAGE:
            self.send_video(file=filename,
                            caption=caption,
                            recipients=recipients)

        return Reply(Reply.INTERCOM_STATUS_SUCCESS)

    def _on_intercom_message(self, message: Message) -> Reply:
        if message == self.INTERCOM_MESSAGE_DO_CHAT_MESSAGE:
            return self._on_intercom_message_send_chat(message)

        if message in [
                self.INTERCOM_MESSAGE_DO_SEND_CAM_SNAPSHOT,
                self.INTERCOM_MESSAGE_DO_SEND_CAM_VIDEO
        ]:
            return self._on_cam_action(message)

        if message in [
                self.INTERCOM_MESSAGE_DO_PHOTO_MESSAGE,
                self.INTERCOM_MESSAGE_DO_VIDEO_MESSAGE,
                self.INTERCOM_MESSAGE_DO_DOCUMENT_MESSAGE
        ]:
            return self._on_intercom_message_complex_message(message)

        return Component._on_intercom_message(self, message)

    def _get_update_info_for_payload(self, update: Update):
        return {
            'from': update.message.from_user.username,
            'from_first_name': update.message.from_user.first_name,
            'from_last_name': update.message.from_user.last_name,
            'text': update.message.text,
        }

    def _on_command_start(self, bot: Bot, update: Update):
        self._add_chat_id(update.message.from_user.username,
                          update.message.chat_id)

        if self.get_is_allowed_message(update):
            self.send_intercom_message(
                self.INTERCOM_MESSAGE_EVENT_CHAT_START,
                self._get_update_info_for_payload(update))

    def _on_message(self, bot: Bot, update: Update):
        self._add_chat_id(update.message.from_user.username,
                          update.message.chat_id)

        if self.get_is_allowed_message(update):
            self.send_intercom_message(
                self.INTERCOM_MESSAGE_EVENT_CHAT_MESSAGE,
                self._get_update_info_for_payload(update))

    def _start_bot(self):
        self._updater = Updater(token=self._token)
        self._bot = self._updater.bot
        self._updater.dispatcher.add_handler(
            CommandHandler('start', self._on_command_start))
        self._updater.dispatcher.add_handler(
            MessageHandler([Filters.text], self._on_message))
        self._updater.start_polling()

    def _stop_bot(self):
        if self._updater is not None:
            self._updater.stop()
            del self._updater

    def _reload(self):
        self.load_settings()

        if self._current_token != self._token:
            self._current_token = self._token

            self._stop_bot()
            self._load_runtime()
            self._start_bot()

        return True

    def start(self):
        Component.start(self)
        self.reload()
예제 #12
0
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_bootstrap_retries_success(self):
        retries = 3
        self._setup_updater('', messages=0, bootstrap_retries=retries)

        self.updater._set_webhook('path', retries)
        self.assertEqual(self.updater.bot.bootstrap_attempts, retries)

    def test_bootstrap_retries_unauth(self):
        retries = 3
        self._setup_updater('',
                            messages=0,
                            bootstrap_retries=retries,
                            bootstrap_err=Unauthorized())

        self.assertRaises(Unauthorized, self.updater._set_webhook, 'path',
                          retries)
        self.assertEqual(self.updater.bot.bootstrap_attempts, 1)

    def test_bootstrap_retries_invalid_token(self):
        retries = 3
        self._setup_updater('',
                            messages=0,
                            bootstrap_retries=retries,
                            bootstrap_err=InvalidToken())

        self.assertRaises(InvalidToken, self.updater._set_webhook, 'path',
                          retries)
        self.assertEqual(self.updater.bot.bootstrap_attempts, 1)

    def test_bootstrap_retries_fail(self):
        retries = 1
        self._setup_updater('', messages=0, bootstrap_retries=retries)

        self.assertRaisesRegexp(TelegramError, 'test',
                                self.updater._set_webhook, 'path', retries - 1)
        self.assertEqual(self.updater.bot.bootstrap_attempts, 1)

    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, 0, 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)
예제 #13
0
class Server:
    def __init__(self):
        """Initialize the Server object for the bot
        TOKEN -> API key of the bot
        """
        self.TOKEN = self.read_token_from_config_file(
            './configfiles/config.cfg')
        self.updater = Updater(self.TOKEN, use_context=True)
        self.dispatcher: Dispatcher = self.updater.dispatcher
        self.dispatcher.add_handler(CommandHandler("start", self.start))
        self.dialogflow = dialogflow_endpoint.DialogFlowWrapper()
        self.dispatcher.add_handler(CommandHandler("end", self.end))
        self.dispatcher.add_handler(
            MessageHandler(Filters.all,
                           self.make_response,
                           pass_user_data=True))
        self.lm = packages.location_mapper.LocationMapper()
        self.covidwrapper = packages.covid_endpoint.CovidWrapper()

    def read_token_from_config_file(self, config):
        """ Reads the token from the config.cfg file
        config -> Location of the config.cfg file
        """
        parser = cfg.ConfigParser()
        parser.read(config)
        return parser.get('creds', 'token')

    def prefix_reply(self, responses):
        """Returns a random string from a given set of responses"""
        pos = random.randint(0, len(responses) - 1)
        return responses[pos]

    def start(self, update: Update, context: CallbackContext):
        """Callback for start command"""
        bot: Bot = context.bot
        responses = ['Hi ', 'Hello ', 'Whats up ', 'How are you ']
        reply = self.prefix_reply(responses) + \
            update.message.from_user.first_name
        bot.send_message(chat_id=update.effective_chat.id, text=reply)
        responses = ['😌', '🙂']
        reply = self.prefix_reply(responses)
        bot.send_message(chat_id=update.effective_chat.id, text=reply)

    def end(self, update: Update, context: CallbackContext):
        """Callback for end command"""
        bot: Bot = context.bot
        responses = [
            'Nice talking you ', 'See you soon ', 'Hope you liked it ',
            'Thank you for your time '
        ]
        reply = self.prefix_reply(responses) + \
            update.message.from_user.first_name
        bot.send_message(chat_id=update.effective_chat.id, text=reply)
        responses = ['👋', '🖖', '🙏']
        reply = self.prefix_reply(responses)
        bot.send_message(chat_id=update.effective_chat.id, text=reply)

    def respond_text(self, update: Update, context: CallbackContext):
        """Respond to user with a text reply"""
        bot: Bot = context.bot
        parent_dir = os.getcwd()
        dir_name = os.path.join(parent_dir, 'logfiles')
        file_name = 'messages.log'
        reply = self.dialogflow.process_input(
            update.message.text, update.message.chat_id,
            update.message.from_user.first_name)
        log_reply = reply.replace('\n', ' ')
        log_reply = log_reply.replace(',', ' ')
        line = f'{update.message.date}, {update.message.from_user.first_name}, {update.message.from_user.last_name}, {update.message.chat_id}, {update.message.text}, {log_reply}\n'
        with open(os.path.join(dir_name, file_name), 'a') as file_pointer:
            file_pointer.writelines(line)
        bot.send_message(chat_id=update.message.chat_id, text=reply)

    def respond_images(self, update: Update, context: CallbackContext):
        """Respond to user with a image reply"""

    def respond_video(self, update: Update, context: CallbackContext):
        """Respond to user with a video reply"""

    def respond_sticker(self, update: Update, context: CallbackContext):
        """Respond to user with a sticker reply"""
        bot: Bot = context.bot
        reply = "Wait there!! I am still learning"
        bot.send_message(chat_id=update.effective_chat.id, text=reply)
        responses = ['🙄', '🤔', '😬', '😐']
        reply = self.prefix_reply(responses)
        bot.send_message(chat_id=update.effective_chat.id, text=reply)
        reply = 'This is all I can understand ' + update.message.sticker.emoji
        bot.send_message(chat_id=update.effective_chat.id, text=reply)

    def respond_location(self, update: Update, context: CallbackContext):
        """Respond to the location sent by the user"""
        bot: Bot = context.bot
        coordinates = f"{update.message['location']['latitude']}, {update.message['location']['longitude']}"
        lst_location = self.lm.get_location_info(coordinates)
        city_name = lst_location[0]
        reply = ""
        confirmed_cases, active_cases, recovered, deaths = self.covidwrapper.get_district_data(
            city_name)
        reply += f'The details for {city_name}\nConfirmed Cases: {confirmed_cases}\nActive Cases: {active_cases}\nRecovered: {recovered}\nDeaths: {deaths}\n'
        state_name = lst_location[1]
        bot.send_message(chat_id=update.effective_chat.id, text=reply)
        reply = ""
        confirmed_cases, active_cases, recovered, deaths = self.covidwrapper.get_state_data(
            state_name)
        reply += f'The details for {state_name}\nConfirmed Cases: {confirmed_cases}\nActive Cases: {active_cases}\nRecovered: {recovered}\nDeaths: {deaths}\n'
        bot.send_message(chat_id=update.effective_chat.id, text=reply)
        reply = ""
        confirmed_cases, active_cases, recovered, deaths = self.covidwrapper.get_country_data(
        )
        reply += f'The details for India\nConfirmed Cases: {confirmed_cases}\nActive Cases: {active_cases}\nRecovered: {recovered}\nDeaths: {deaths}\n'
        bot.send_message(chat_id=update.effective_chat.id, text=reply)

    def reply_to_messages(self, update: Update, context: CallbackContext):
        """Determine message type and then reply accordingly"""
        bot: Bot = context.bot
        if update.message.text:
            self.respond_text(update, context)
        elif update.message.video:
            self.respond_video(update, context)
        elif update.message.photo:
            self.respond_images(update, context)
        elif update.message.sticker:
            self.respond_sticker(update, context)
        elif update.message.location:
            self.respond_location(update, context)
        elif update.message.contact:
            # Respond to contact messages
            pass

    def make_response(self, update: Update, context: CallbackContext):
        """Callback for making reponses to the user"""
        bot: Bot = context.bot
        self.reply_to_messages(update, context)

    def start_server(self):
        self.updater.start_polling()
예제 #14
0
class TelegramMessageHandler(object):
    def __init__(self):
        self.updater = Updater(
            '475775136:AAFkVNGakPSCINOHKdE6jv7MKRPZXN5WoQ4')  #Token

    def start(self, bot, update):
        update.message.reply_text('Olá {}! Seja muito bem-vindo'.format(
            update.message.from_user.first_name))
        time.sleep(3)
        update.message.reply_text('Muito prazer, eu sou o Jay')
        time.sleep(3)
        update.message.reply_text(
            'e estou aqui para te ajudar a conhecer São José dos Campos. \nVamos lá!? \õ/'
        )

    def hello(self, bot, update):
        update.message.reply_text('Oi {}! É bom ter você por aqui :D'.format(
            update.message.from_user.first_name))
        time.sleep(2)
        self.reply_text('Olha... eu garanto que você não vai se arrepender!')

    def support(self, bot, update):
        update.message.reply_text(
            'vejo que você precisa de ajuda uma ajuda {}'.format(
                update.message.from_user.first_name))
        time.sleep(2)
        update.message.reply_text('me diz o que precisa..')

    def mess_receive_user(self, bot, update):

        nbCustom = NaiveBayesCustom()
        nbCustom.classifyTextFromIM(
            update.message.text)  # self.get_last_mess()
        place = nbCustom.getClassification()
        probMax = nbCustom.getProbMaxClassification()
        #print('\nProbabilidade Máxima: ', probMax)
        #print('\nClasse: ', place)
        if (probMax < 0.5000):
            update.message.reply_text(
                'não consigo te orientar porque não entendi o que vc quis dizer'
            )
        elif (probMax >= 0.5000 and probMax < 0.7500):
            update.message.reply_text('olha {}, não é certeza mas.. '.format(
                update.message.from_user.first_name))
            time.sleep(2)
            update.message.reply_text('talvez vc vai gostar de ir no ' + place)
        elif (probMax <= 0.7500 and probMax < 0.8500):
            update.message.reply_text(
                place + ' seria um bom lugar pra vc ir {}'.format(
                    update.message.from_user.first_name))
        else:
            update.message.reply_text(
                place + ' é o lugar pra vc ir com toda certeza!'.format(
                    update.message.from_user.first_name))

    '''       
    def get_last_mess(self):
        messages = self.updater.bot.getUpdates()
        print(len(messages))
        if (len(messages) == 0):
            return ''
        else:
            print("mensagens: ", messages)
            print("Ultima msg: ", messages[len(messages)-1]['message']['text'])
            return messages[len(messages)-1]['message']['text']
    '''

    def run_dispatcher(self):
        self.updater.dispatcher.add_handler(CommandHandler(
            'start', self.start))
        self.updater.dispatcher.add_handler(CommandHandler(
            'hello', self.hello))
        self.updater.dispatcher.add_handler(
            CommandHandler('support', self.support))

        receive_msg_handler = MessageHandler([Filters.text],
                                             self.mess_receive_user)
        self.updater.dispatcher.add_handler(receive_msg_handler)

    def start_bot(self):
        self.run_dispatcher()
        self.updater.start_polling()
        print("\n-------------------------------------------------")
        print("|\tTelegram Bot Inicialized with Success  \t|")
        print("-------------------------------------------------\n")
        self.updater.idle()

    def stop_bot(self):
        self.updater.stop()
예제 #15
0
        msg = json.dumps(update.message.to_dict(), indent=True)
        bot.send_message(chat_id=update.message.chat_id,
                         parse_mode='Markdown',
                         text=f'```{msg}```')


def error_callback(bot, update, error):
    logging.error(error)


if __name__ == '__main__':
    with open('token.txt') as token_file:
        token = token_file.read().strip()
    
    updater = Updater(token)
    dispatcher = updater.dispatcher

    dispatcher.add_handler(CommandHandler('start', start_cmd))
    dispatcher.add_handler(CommandHandler('about', about_cmd))
    dispatcher.add_handler(CommandHandler('help', help_cmd))
    dispatcher.add_handler(CommandHandler('roll', roll_cmd, pass_args=True))
    dispatcher.add_handler(CommandHandler('save', save_cmd, pass_args=True))
    dispatcher.add_handler(CommandHandler('delete', delete_cmd, pass_args=True))

    dispatcher.add_handler(MessageHandler(None, test))

    dispatcher.add_error_handler(error_callback)

    print('Starting bot...')
    updater.start_polling()