コード例 #1
0
class TelegramBot:
    def __init__(self, token: str, user_id: str):
        self.user_id = user_id
        self.bot = TeleBot(token)
        # current answer from bot.
        # Can be '' or 'new_captcha'
        self.answer = None

        @self.bot.message_handler()
        def company_receiving(message):
            self.bot.send_message(message.from_user.id, 'Received')
            self.bot.stop_polling()
            self.answer = message.text

        @self.bot.callback_query_handler(lambda query: query.data == 'button_1'
                                         )
        def process_callback(query):
            self.bot.stop_polling()
            self.answer = 'new_captcha'

    def send_photo(self, img: bytes):
        keyboard = button_add()
        self.answer = ''
        self.bot.send_photo(self.user_id, photo=img, reply_markup=keyboard)
        self.bot.polling()
コード例 #2
0
class TelegramBot:
    def __init__(self, token: str, mongo: MongoDB):
        self._mongo = mongo
        self._bot = TeleBot(token)

        @self._bot.message_handler(commands=['start', 'help'])
        def send_welcome(message):
            try:
                self._mongo.update_telegram_id(message.chat.username,
                                               message.chat.id)
                self._bot.reply_to(message, "Howdy, how are you doing?")
            except Exception as e:
                self._bot.reply_to(message, str(e))

    def set_bot(self, bot: TeleBot):
        self._bot = bot

        @self._bot.message_handler(commands=['start', 'help'])
        def send_welcome(message):
            try:
                self._mongo.update_telegram_id(message.chat.username,
                                               message.chat.id)
                self._bot.reply_to(message, "Howdy, how are you doing?")
            except Exception as e:
                self._bot.reply_to(message, str(e))

    def get_bot(self):
        return self._bot

    def close(self):
        self._bot.stop_polling()
        self._bot.stop_bot()

    def start(self):
        self._bot.polling()

    def send_message(self, recipient: int, message: str):
        self._bot.send_message(recipient, message)
コード例 #3
0
class BOT:
    index = 0
    count_films = utils.STEP
    config_file_name = 'config.json'

    def __init__(self):
        self.cfg = self.JSON()
        self.construct()

    def construct(self):
        self.bot = TeleBot(self.cfg['token'])
        self.commands = {
            "List films": utils.call(self.manage),
            "Unsubscribe": utils.call(self.del_user),
        }
        self.film_view_markup = {
            "back": utils.call(self.revert),
            "open": utils.call(lambda *x, **b:...),
        }
        self.markup = {
            "1": utils.call(self.film, 0),
            "2": utils.call(self.film, 1),
            "3": utils.call(self.film, 2),
            "4": utils.call(self.film, 3),
            "5": utils.call(self.film, 4),
            "6": utils.call(self.film, 5),
            "7": utils.call(self.film, 6),
            "8": utils.call(self.film, 7),
            "9": utils.call(self.film, 8),
            "10": utils.call(self.film, 9),
            "prev": utils.call(self.prev),
            "next": utils.call(self.next),
        }

        @self.bot.message_handler(
            commands=['subscribe', 'unsubscribe', 'categories', 'find'])
        def subscribe_detector(message):
            try:
                if "/subscribe" in message.text:
                    category = message.text.split("/subscribe")[-1].strip()
                    if category in list(self.cfg['categories'].keys()):
                        uinfo = (message.chat.id, category)
                        db = utils.DATABASE(self.cfg["db_name"])
                        db.insert(table_name="subscribe_categories",
                                  args=uinfo)
                        self.bot.reply_to(
                            message, self.cfg["subscribe_category"].replace(
                                "{}", category))
                    else:
                        self.bot.send_message(message.chat.id,
                                              self.cfg["category_not_found"])

                elif "/unsubscribe" in message.text:
                    category = message.text.split("/unsubscribe")[-1].strip()
                    if category in self.cfg['categories']:
                        db = utils.DATABASE(self.cfg["db_name"])
                        db.delete(table_name="subscribe_categories",
                                  where=" chat_id =  " + str(message.chat.id))
                        self.bot.reply_to(
                            message, self.cfg["unsibscribe_category"].replace(
                                "{}", category))
                    else:
                        self.bot.send_message(message.chat.id,
                                              self.cfg["category_not_found"])

                elif "/find" in message.text:
                    film_name = message.text.split("/find")[-1].strip()
                    finded = utils.load_films(
                        db_name=self.cfg['db_name'],
                        find_perc=[film_name, self.cfg['film_perc']])
                    finded.extend(
                        utils.load_films(db_name=self.cfg['db_name'],
                                         find=film_name))

                    message_ = ""
                    for i, film in enumerate(finded):
                        message_ += "{}. {}\n{}\n\n".format(
                            i + 1, film[1], film[3])

                    messages_ = []

                    if len(message_) > 2800:
                        count = int(len(message_) / 2800)
                        s = 0
                        for i in range(count):
                            ns = s + 2800
                            if len(message_) < ns:
                                ns = -1
                            msg = message_[s:ns]
                            messages_.append(msg)
                            s = ns
                            if not ns:
                                break
                    else:
                        messages_.append(message_)

                    for msg in messages_:
                        if len(msg) > 2:
                            self.bot.send_message(message.chat.id, msg)
                        else:
                            self.bot.send_message(message.chat.id,
                                                  self.cgf['no_film_error'])

                elif "/categories" in message.text:
                    msg = ""
                    for i, key in enumerate(list(self.cfg["categories"])):
                        msg += "{} : {}\n".format(i, key)

                    self.bot.send_message(
                        message.chat.id,
                        self.cfg['categories_text'].replace("{}", msg))

            except Exception as e:
                # utils.log(e)
                raise

        @self.bot.callback_query_handler(func=lambda call: True)
        def callback_query(call):
            try:
                if call.data in self.markup.keys():
                    self.markup[call.data](call)
                elif call.data in self.film_view_markup.keys():
                    self.film_view_markup[call.data](call)
            except Exception as e:
                utils.log(e)

        @self.bot.message_handler(func=lambda x: True)
        def main(message):
            try:
                utils.add_user(message=message, db_name=self.cfg['db_name'])
                if message.text in self.commands:
                    self.commands[message.text](message)
                else:
                    self.bot.send_message(message.chat.id,
                                          text=self.cfg['base_message'],
                                          reply_markup=utils.repl_markup(
                                              list(self.commands.keys())))
            except Exception as e:
                utils.log(e)

    def JSON(self):
        return utils.loads(open(self.config_file_name).read())

    def del_user(self, message):
        self.bot.send_message(message.chat.id, self.cfg["global_unsubscribe"])
        utils.delete_subscriber(message.chat.id, db_name=self.cfg['db_name'])

    def manage(self, message, text=None):
        self.bot.send_message(
            message.chat.id,
            text=utils.new_message(
                msg=text if text else self.cfg['default_message'],
                db_name=self.cfg["db_name"],
                repl=self.cfg['message_repl']),
            reply_markup=utils.inline_markup(self.markup))

    def revert(self, call):
        id = call.message.chat.id
        messages = utils.new_message(index=self.index,
                                     msg=self.cfg['default_message'],
                                     repl=self.cfg['message_repl'],
                                     db_name=self.cfg["db_name"])
        self.bot.delete_message(id, call.message.message_id)
        self.bot.send_message(id,
                              text=messages,
                              reply_markup=utils.inline_markup(self.markup))
        self.bot.answer_callback_query(call.id, "Success")

    def send_all(self, msg):
        mkp = utils.repl_markup(utils.START_MARKUP)
        for id in utils.get_all_subscribers_id(db_name=self.cfg["db_name"]):
            try:
                self.bot.send_message(id, msg, reply_markup=mkp)
            except Exception as e:
                utils.delete_subscriber(id, db_name=self.cfg["db_name"])

    def film(self, call, id=0):
        id_ = call.message.chat.id

        db = utils.DATABASE(self.cfg['db_name'])
        film_info = db.read(table_name="films",
                            where=" id = '{}'".format(
                                utils.class_db.film_list[id][1]))[0]
        db.close()

        def download():
            utils.image_download(film_info[2])

        t = Thread(target=download)
        t.start()
        t.join()

        self.bot.delete_message(id_, call.message.message_id)

        self.bot.send_photo(
            chat_id=id_,
            photo=open(".image.jpg", "rb"),
            reply_markup=utils.inline_markup(self.film_view_markup),
            caption=utils.render_film_info(film_info[0],
                                           db_name=self.cfg["db_name"]))

    def next(self, call):
        utils.class_db.index += utils.STEP

        messages = utils.new_message(msg=self.cfg['default_message'],
                                     repl=self.cfg['message_repl'],
                                     index=utils.class_db.index,
                                     db_name=self.cfg["db_name"])
        self.bot.edit_message_text(text=messages,
                                   chat_id=call.message.chat.id,
                                   message_id=call.message.message_id,
                                   reply_markup=utils.inline_markup(
                                       self.markup),
                                   inline_message_id=call.inline_message_id)

    def prev(self, call):
        utils.class_db.index -= utils.STEP
        if utils.class_db.index < 0:
            utils.class_db.index = 0
            self.bot.answer_callback_query(call.id, self.cfg['no_films_error'])
            return True

        message = utils.new_message(msg=self.cfg['default_message'],
                                    repl=self.cfg['message_repl'],
                                    index=utils.class_db.index,
                                    db_name=self.cfg["db_name"])
        self.bot.edit_message_text(text=message,
                                   chat_id=call.message.chat.id,
                                   message_id=call.message.message_id,
                                   reply_markup=utils.inline_markup(
                                       self.markup),
                                   inline_message_id=call.inline_message_id)

    def start(self, msg=True):
        if msg:
            self.send_all(self.cfg["start_message"])
        utils.new_message(msg=self.cfg['default_message'],
                          repl=self.cfg['message_repl'],
                          db_name=self.cfg["db_name"])
        self.bot.polling()

    def stop(self):
        self.bot.stop_polling()
コード例 #4
0
                }
            )
        else:
            break
    return keboard_list


def make_keyboard(list_item):

    keyboard = types.InlineKeyboardMarkup(row_width=20)
    for item in list_item:
        btn = types.InlineKeyboardButton(
            text=item['text'],
            callback_data='('+item['tyle']+')'+item['callback_data']
        )
        keyboard.add(btn)
    return keyboard


if __name__ == '__main__':

    while True:
        try:
            print('Bot restart at ', str(datetime.now()))
            bot.polling(True)
        except Exception:
            print('Something wrong...')
        print('Bot is sleeping...')
        bot.stop_polling()
        time.sleep(60)
コード例 #5
0
ファイル: __init__.py プロジェクト: vixfwis/ydl_bot
class TelegramBot:
    def __init__(self, work_dir: Path, token: str):
        self.last_requests = {}  # type: Dict[int, List[datetime]]
        self.work_dir = work_dir
        self.work_dir.mkdir(0o755, parents=True, exist_ok=True)
        self.token = token
        self.bot = TeleBot(token)
        self.bot.add_message_handler({
            'function': self.process_link,
            'filters': {
                'regexp': r'https?:\/\/.+\..+'
            }
        })
        self.bot.add_message_handler({
            'function': self.process_message,
            'filters': {
                'func': lambda _: True
            }
        })

    def process_link(self, message: Message):
        user_id = message.from_user.id
        if user_id not in self.last_requests:
            self.last_requests[user_id] = []
        limit_req, limit_min = get_rate_limit()
        now = datetime.now(tz=timezone.utc)
        last_requests = []
        for dt in self.last_requests[user_id]:
            time_passed = now - dt
            if time_passed.min < timedelta(minutes=limit_min):
                last_requests.append(dt)
        self.last_requests[user_id] = last_requests

        if len(self.last_requests[user_id]) > limit_req:
            next_available = self.last_requests[user_id][0] + timedelta(
                minutes=limit_min) - now
            self.bot.reply_to(
                message,
                f'Rate limited. Try again in {next_available.seconds} seconds')
            return
        else:
            self.last_requests[user_id].append(now)
        msg = self.bot.reply_to(message, "Link detected, processing")

        # detach from telebot update thread
        def download():
            try:
                with YoutubeDL({'noplaylist': True}) as ydl:
                    info = ydl.extract_info(message.text, download=False)
                    if info['duration'] > 900:
                        self.bot.edit_message_text('Source too long',
                                                   message_id=msg.id,
                                                   chat_id=msg.chat.id)
                        return
                with YoutubeDL(get_options_audio(self.work_dir)) as ydl:
                    ydl.add_post_processor(
                        UploadHandler(self.bot, msg.id, msg.chat.id))
                    self.bot.edit_message_text('Downloading',
                                               message_id=msg.id,
                                               chat_id=msg.chat.id)
                    ydl.download([message.text])
            except UnsupportedError:
                self.bot.edit_message_text('Unsupported URL',
                                           message_id=msg.id,
                                           chat_id=msg.chat.id)
            except DownloadError:
                self.bot.edit_message_text('Download error',
                                           message_id=msg.id,
                                           chat_id=msg.chat.id)
            except Exception as e:
                self.bot.edit_message_text('Unknown error',
                                           message_id=msg.id,
                                           chat_id=msg.chat.id)
                logger.error('Unknown error', exc_info=e)

        reactor.callInThread(lambda: download())

    def process_message(self, message: Message):
        self.bot.reply_to(message, 'Send me a link')

    def polling(self):
        self.bot.delete_webhook()
        self.bot.polling(long_polling_timeout=5)

    def stop_polling(self):
        self.bot.stop_polling()

    def set_webhook(self, host: str, port: int):
        cert_path, pkey_path = get_or_create_root_cert(self.work_dir, host)
        self.bot.remove_webhook()
        self.bot.set_webhook(url=f'https://{host}:{port}/{self.token}/',
                             certificate=open(cert_path, 'r'))
        bot = self.bot

        class WebhookHandler(Resource):
            isLeaf = True

            def render_POST(self, request):
                request_body_dict = json.load(request.content)
                update = Update.de_json(request_body_dict)
                reactor.callInThread(lambda: bot.process_new_updates([update]))
                return b''

        root = ErrorPage(403, 'Forbidden', '')
        root.putChild(self.token.encode(), WebhookHandler())
        site = Site(root)
        sslcontext = ssl.DefaultOpenSSLContextFactory(str(pkey_path),
                                                      str(cert_path))
        reactor.listenSSL(port, site, sslcontext)