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()
def send_photo(bot: TeleBot,
               bot_state: BotState,
               message: Message,
               database: DataBase,
               ydisk: YandexDisk,
               is_canceled: bool = False):
    state_additional = bot_state.get_state(message.from_user.id)["additional"]
    keyboard = None
    if is_canceled:
        keyboard = state_additional["keyboard"]["with_cancel"]
    else:
        keyboard = state_additional["keyboard"]["normal"]
    photo = database.get_random_photos(1)
    if len(photo) > 0:
        photo = photo[0]
        photo_url = ydisk.disk.get_download_link(photo["filepath"])
        bot.send_photo(message.chat.id,
                       photo_url,
                       reply_markup=keyboard,
                       caption="https://www.instagram.com/{}".format(
                           photo["source"]))
    else:
        bot.send_message(
            message.chat.id,
            "Фотографии закончились :(\nВведите /help, остановите эту хреновину."
        )
        bot_state.add_state(message.chat.id, "help")

    return photo
Exemple #3
0
def send_photos(bot: TeleBot, database: DataBase, ydisk: YandexDisk, num: int = 10):
    photos = database.get_random_photos(num, "checked")
    if len(photos) > 0:
        for photo in photos:
            if ydisk.disk.exists(photo["filepath"]):
                bot.send_photo(os.environ["CHANNEL"], ydisk.disk.get_download_link(photo["filepath"]),
                               disable_notification=True)
                database.set_photo_status(photo["hash"], "published")
                database.increment_insta_stat(photo["source"], "approved_photos")
        print("Publishing complete ({})".format(num))
    else:
        print("The photos are over")
class PostSender:

    def __init__(self, token: str):
        self.__bot = TeleBot(token)
        self.__api_worker = ApiWorker()

    def get_categories(self) -> List[Category]:
        return self.__api_worker.get_categories()

    def get_posts(self, category: Union[Category, str], limit: int = 1, likes: int = 1):
        if isinstance(category, Category):
            category = category.channel_id
        return self.__api_worker.get_items(category, limit=limit, likes=likes)

    def get_recomendation(self, limit=1, likes=1):
        return self.__api_worker.get_recomendations(limit=limit, likes=likes)

    def __send_post(self, chat_id: Union[str, int], post_item: PostItem) -> bool:
        if post_item:
            try:
                if post_item.type in ('pic', 'mem'):
                    self.__bot.send_photo(chat_id, photo=post_item.url, caption=post_item.title)
                elif post_item.type == 'gif_caption':
                    self.__bot.send_animation(chat_id, animation=post_item.url, caption=post_item.title)
                elif post_item.type == 'video_clip':
                    self.__bot.send_video(chat_id, data=post_item.url, caption=post_item.title)
            except ApiTelegramException as e:
                logging.error(f"Bot can't send message error_code: {e.error_code} - {e.result_json['description']}")
                if e.error_code == 429:
                    print('timeout ', e.result_json['parameters']['retry_after'])
                    time.sleep(e.result_json['parameters']['retry_after'])
                    return self.__send_post(chat_id, post_item)
                raise
            return True

    def _check_chat(self, chat_id) -> bool:
        try:
            self.__bot.get_chat(chat_id)
            return True
        except ApiTelegramException as e:
            logging.error(f'bad chat {chat_id}: {e.result_json["description"]}')
            raise

    def publish_post(self, chat_id: Union[int, str], post_items: Union[PostItem, List[PostItem]]) -> Union[
        bool, List[bool]]:
        if self._check_chat(chat_id):
            if isinstance(post_items, PostItem):
                return self.__send_post(chat_id, post_items)
            else:
                for it in post_items:
                    self.__send_post(chat_id, it)
                    time.sleep(1)
Exemple #5
0
def echo(bot: TeleBot, bot_state: BotState, message: Message, database: DataBase, ydisk: YandexDisk):
    photos = database.get_random_photos(int(message.text), "checked")
    if len(photos) > 0:
        for photo in photos:
            if ydisk.disk.exists(photo["filepath"]):
                bot.send_photo(os.environ["CHANNEL"], ydisk.disk.get_download_link(photo["filepath"]),
                               disable_notification=True)
                database.set_photo_status(photo["hash"], "published")
                database.increment_insta_stat(photo["source"], "approved_photos")
        print("{}: posted photos".format(message.from_user.username))
        bot.send_message(message.chat.id, "Фотографии успешно опубликованы.")
    else:
        print("{}: could not post photos".format(message.from_user.username))
        bot.send_message(message.chat.id, "Фотографии закончились :(")
Exemple #6
0
def main():
    bot = TeleBot(config.BotToken)
    list_of_hashes = ListOfHashes(config.FileWithListOfHashesOfImages)
    while True:
        list_of_images_for_post = get_names_of_not_posted_images(
            list_of_hashes)
        for image_name in list_of_images_for_post:
            try:
                path_to_image = config.DirectoryWithImages + '\\' + image_name
                image_for_post = open(path_to_image, 'rb')
                bot.send_chat_action(config.ChanelId, 'upload_photo')
                bot.send_photo(config.ChanelId, image_for_post)
                image_for_post.close()
            except:
                print('Error In Main')
def show_milestone(bot: TeleBot, mess: Message, content: str):
    photo_exist = False
    if os.path.exists(os.path.join("content", content + ".png")):
        photo_path = os.path.join("content", content + ".png")
        photo_exist = True
    if os.path.exists(os.path.join("content", content + ".jpg")):
        photo_path = os.path.join("content", content + ".jpg")
        photo_exist = True

    with open(os.path.join("content", content + ".txt")) as f:
        caption = f.read()

    if photo_exist:
        with open(photo_path, 'rb') as f:
            bot.send_photo(mess.chat.id, photo=f, caption=caption)
    else:
        bot.send_message(mess.chat.id, caption)
class TlgrmBot:
    def __init__(self, botid, chatid):
        self.botid = botid
        self.chatid = chatid
        self.bot = TeleBot(self.botid)

    def send(self, photo, caption):
        self.bot.send_photo(chat_id=self.chatid,
                            photo=photo,
                            caption=caption,
                            parse_mode="Markdown")

    def alive(self):
        try:
            self.bot.get_me()
        except Exception:
            return False
        else:
            return True
Exemple #9
0
def handle_message(bot: TeleBot, message):
    try:
        if message.text == get_button('russia'):
            with open(get_actual_data().get_image(), 'rb') as f:
                return bot.send_photo(message.chat.id, photo=f).photo
        elif message.text == get_button('world'):
            with open(get_actual_data(True).get_image(), 'rb') as f:
                return bot.send_photo(message.chat.id, photo=f).photo
        elif message.text == get_button('joke'):
            return bot.send_message(message.chat.id, get_joke())
        elif 'слава' in str(message.text).lower():
            return bot.send_message(
                message.chat.id,
                'Слава мой создатель,но вообще мог бы и с пользой время потратить'
            )
        else:
            return bot.send_message(message.chat.id,
                                    get_small_talk_response(message.text))
    except Exception:
        raise
Exemple #10
0
    def send(self, bot: TeleBot, group):
        msg: Message
        if self.type == 'text':
            msg = bot.send_message(group, self.text)
        elif self.type == 'photo':
            msg = bot.send_photo(group, self.photo_id, self.caption)
        elif self.type == 'video':
            msg = bot.send_video(group, self.video_id, caption=self.caption)
        elif self.type == 'document':
            msg = bot.send_document(group, self.doc_id, caption=self.caption)
        else:
            print('А где содержимое письма?!')

        return msg
Exemple #11
0
class TgBot(threading.Thread):
    def loadCommandConfig(self):
        pass

    def loadPersonConfig(self):
        persons = {}
        return persons

    def __init__(self, config, admins, tunnels, loopDelay=0.1, debug=False):
        super(TgBot, self).__init__()
        self.debug = debug
        self.stopped = Event()
        self.loopDelay = loopDelay

        self.admins = admins
        self.tunnels = tunnels
        self.config = config
        self.botUserName = config['botUserName']
        self.bot = TeleBot(config['token'])

        self.commands = [
            # AddAdmin(bot=self, cmd=['add-admin']),
            # Alarm('alarm', time.time())
            Bind(bot=self, cmd=['b', 'bind']),
            ListBind(bot=self, cmd=['lb', 'listbind', 'list-bind']),
            Toggle(bot=self, cmd=['t', 'toggle']),
            ListToggle(bot=self, cmd=['lt', 'listtoggle', 'list-toggle']),
            UnBind(bot=self, cmd=['ub', 'unbind', 'un-bind'])
        ]
        self.persons = self.loadPersonConfig()

    def sendMessage(self, _id, _msg, parse_mode=None):
        self.bot.send_message(chat_id=_id, text=_msg, parse_mode=parse_mode)

    def replyTo(self, msg, _msg):
        self.bot.reply_to(msg, _msg)

    def listbind_handler(self, message):
        print(message)

    def handler(self, msg):
        for each in msg:
            try:
                _from = each.from_user
                _chat = each.chat
                if each.text and each.text.startswith('#'):
                    _text = each.text
                    for tunnel in getMatchTunnels(self.tunnels, tgId=_chat.id):
                        if tunnel.tg['toggle']:
                            name = _from.username or _from.first_name or _from.last_name
                            message = '[Anonymous]: {0}'.format(
                                _text[2:]) if _text.startswith(
                                    '##') else '[{0}]: {1}'.format(
                                        name, _text[1:])
                            tunnel.tk['queue'].put(message)
                if self.debug:
                    print(each)
            except Exception as e:
                if self.debug:
                    traceback.print_exc()

    def queueHandler(self):
        while not self.stopped.wait(self.loopDelay):
            for each in self.tunnels:
                tg = each.tg
                while not tg['queue'].empty() and tg['toggle']:
                    chatId = tg['id']
                    msg = tg['queue'].get()
                    try:
                        if '<img' in msg:
                            link = re.search('src=\".*?\"', msg).group(0)[5:-1]
                            if '.gif' in msg:
                                self.bot.send_document(chatId, link)
                            else:
                                self.bot.send_photo(chatId, link)
                        elif '</' in msg:
                            self.bot.send_message(chatId,
                                                  msg,
                                                  parse_mode='HTML')
                        else:
                            self.bot.send_message(chatId,
                                                  msg,
                                                  parse_mode='Markdown')
                    except Exception as e:
                        self.bot.send_message(chatId, msg)
                        if self.debug:
                            traceback.print_exc()

    def start(self):
        super(TgBot, self).start()
        for cmd in self.commands:
            cmd.register()
        self.bot.set_update_listener(self.handler)
        thread = threading.Thread(target=self.queueHandler)
        thread.start()

    def run(self):
        while not self.stopped.wait(self.loopDelay):
            try:
                self.bot.polling(none_stop=False)
            except:
                if self.debug:
                    traceback.print_exc()

    def stop(self):
        self.bot.stop_bot()
        self.stopped.set()
class MyTeleBot(object):
    """
    class of my custom tele-bot
    :param token_path: str;  path to the file with token
    """
    def __init__(self, **kwargs):
        self.token_path = kwargs.get("token_path", None)
        self.MAX_NUM_OF_ARTICLES = 6  # maximum number of articles on each topic
        self.bot = TeleBot(token=self.get_token())  # parent class init
        self.started = False  # True if bot is started
        self.data_base_handler = DataBaseHandler(
            path="news_bot_db")  # creating database handler
        self.news_api_handler = NewsApiHandler(path="secure_codes/newsapi.txt")
        self.language_handler = LanguageHandler()
        self.markup_hider = types.ReplyKeyboardRemove()
        self.news_sender = NewsSender(bot=self.bot,
                                      language_handler=self.language_handler,
                                      news_api_handler=self.news_api_handler,
                                      data_base_handler=self.data_base_handler)

        self.country_name_to_short_name = {  # dictionary with countries short names
            "Russia": "ru",
            "United States": "us",
            "France": "fr",
            "United Kingdom": "gb",
            "Germany": "gr",
            "Canada": "ca",
        }
        self.apologies_options = [
            "Простите, я больше не буду",
            "Извините, пожалуйста",
            "Уважаемый, я прошу прошения",
        ]

        self.basic_markup_buttons = [
            "Add topics  " + u'\U00002795',
            "Change news time  " + u'\U000023F1',
            "Select country  " + u'\U0001F3F3',
            "Delete topics  " + u'\U00002716',
            "Change number of articles  " + u'\U0001F522',
            "Change language  " + u'\U0001F5E3'
        ]  # buttons with emojies on a basic keyboard
        self.russian_basic_markup_buttons = [
            "Добавить темы  " + u'\U00002795',
            "Поменять время отправки новостей  " + u'\U000023F1',
            "Выбрать страну  " + u'\U0001F3F3',
            "Удалить темы  " + u'\U00002716',
            "Изменить число статей  " + u'\U0001F522',
            "Поменять язык  " + u'\U0001F5E3',
        ]
        self.basic_markup = None
        self.topics = [
            "Business", "Entertainment", "Health", "Science", "Sports",
            "Technology", "Girls with a bob cut  " + u'\U0001F469'
        ]  # topics to choose from
        self.all_topics = [
            "Business", "Entertainment", "Health", "Science", "Sports",
            "Technology", "Girls with a bob cut  " + u'\U0001F469',
            "Girls with a bob cut"
        ]
        self.topics_rus = [
            "Бизнес", "Развлечения", "Здоровье", "Наука", "Спорт",
            "Технологии", "Девочки с каре  " + u'\U0001F469'
        ]
        self.all_topics_rus = [
            "Бизнес", "Развлечения", "Здоровье", "Наука", "Спорт",
            "Технологии", "Девочки с каре  " + u'\U0001F469', "Девочки с каре"
        ]
        self.delete_topics = [
            "-Business", "-Entertainment", "-Health", "-Science", "-Sports",
            "-Technology"
        ]
        self.delete_topics_rus = [
            "-Бизнес", "-Развлечения", "-Здоровье", "-Наука", "-Спорт",
            "-Технологии"
        ]
        #  topics items with OK button:
        self.topics_ok = self.topics
        self.topics_ok.append("OK")
        self.topics_ok_rus = self.topics_rus
        self.topics_ok_rus.append("OK")

        self.languages = ["English", "Russian"]  # list of languages of the bot

        self.countries = [
            "Russia", "United States", "France", "United Kingdom", "Germany",
            "Canada"
        ]
        self.countries_rus = [
            "Россия", "США", "Франция", "Объединенное королевство", "Германия",
            "Канада"
        ]

        @self.bot.message_handler(commands=["start"])  # start command handler
        def start(message):
            self.basic_markup = get_custom_keyboard(
                items=self.basic_markup_buttons)
            start_message_text = """Hello, I'm a news bot.\nYou can get news on different topics every day)"""
            nickname = get_user_nickname(message)  # gets user's nickname
            telegram_id = get_user_telegram_id(
                message)  # gets user's telegram id
            data_base_handler.add_chat_id(telegram_id=telegram_id,
                                          chat_id=message.chat.id)

            is_registered = data_base_handler.check_user(
                telegram_id=telegram_id)
            print("registered: ", is_registered)
            choose_topics_text = "Choose topics you want to get news on:"
            welcome_back_message = "Welcome back! What do you want to do?"
            if is_registered:
                language = self.data_base_handler.get_user_language(
                    telegram_id=telegram_id)
                show_basic_keyboard(message,
                                    welcome_back_message,
                                    language=language)
            else:
                add_user_to_database(message)
                self.bot.send_message(message.chat.id,
                                      start_message_text)  # hello message
                select_language(message)
                #select_topics(message)
                #select_num_of_articles(message)
                #select_country(message)

        @self.bot.message_handler(commands=["select_language"])
        def select_language(message):
            markup = get_custom_keyboard(items=self.languages)
            telegram_id = get_user_telegram_id(message)
            select_language_message = "Please, select language of the bot:"
            data_base_handler.add_chat_id(telegram_id=telegram_id,
                                          chat_id=message.chat.id)
            user_language = data_base_handler.get_user_language(
                telegram_id=telegram_id)
            if user_language == "Russian":
                select_language_message = "Пожалуйста, выберите язык бота:"
            self.bot.send_message(message.chat.id,
                                  select_language_message,
                                  reply_markup=markup)

        @self.bot.message_handler(commands=["get_news"])
        def get_news(message):
            self.news_api_handler.get_news(country="ru", topic="business")

        @self.bot.message_handler(commands=["select_country"])
        def select_country(message):
            telegram_id = get_user_telegram_id(message)
            user_language = self.data_base_handler.get_user_language(
                telegram_id=telegram_id)
            choose_country_message = "Select country you want to get news about:"
            choose_country_message_rus = "Выберите страну, из которой Вы хотите получать новости:"
            markup = get_custom_keyboard(items=self.countries,
                                         one_time_keyboard=True,
                                         basic=True)  # markup for reply
            markup_rus = get_custom_keyboard(items=self.countries_rus,
                                             one_time_keyboard=True,
                                             basic=True)  # markup in Russian
            if user_language == "English":  # user uses English
                self.bot.send_message(
                    message.chat.id,
                    choose_country_message,
                    reply_markup=markup)  # sends choose country message
            if user_language == "Russian":  # user uses Russian
                self.bot.send_message(message.chat.id,
                                      choose_country_message_rus,
                                      reply_markup=markup_rus)

        @self.bot.message_handler(commands=["select_num_of_articles"])
        def select_num_of_articles(message):
            telegram_id = get_user_telegram_id(message)
            num_of_articles = self.data_base_handler.get_user_num_of_articles(
                telegram_id=telegram_id)

            select_num_of_articles_message = "Select number of news you want to get on each topic\nNow you receive " + num_of_articles + " articles on each topic every day"
            select_num_of_articles_message_rus = "Выберите сколько статей Вы хотите получать на каждую тему:\nПока что я буду отправлять Вам по " + num_of_articles + " статьи на каждую тему."

            is_user_registered = check_user_registration(
                telegram_id=telegram_id)
            number_of_articles = [
                str(i) for i in range(1, self.MAX_NUM_OF_ARTICLES)
            ]
            user_language = self.data_base_handler.get_user_language(
                telegram_id=telegram_id)

            markup = get_custom_keyboard(items=number_of_articles,
                                         one_time_keyboard=True,
                                         basic=True)
            if user_language == "English":
                self.bot.send_message(message.chat.id,
                                      select_num_of_articles_message,
                                      reply_markup=markup)
            if user_language == "Russian":
                self.bot.send_message(message.chat.id,
                                      select_num_of_articles_message_rus,
                                      reply_markup=markup)

        @self.bot.message_handler(commands=["send_news"])
        def send_news(message):
            telegram_id = get_user_telegram_id(message)
            user_topics = str(
                data_base_handler.get_user_topics(telegram_id=telegram_id))
            user_topics = user_topics.split(";")[:-1]  # user's topics
            user_country = self.data_base_handler.get_user_country(
                telegram_id=telegram_id)
            user_language = self.data_base_handler.get_user_language(
                telegram_id=telegram_id)
            user_num_of_articles = self.data_base_handler.get_user_num_of_articles(
                telegram_id=telegram_id)
            self.news_sender.send_news_to_user(chat_id=message.chat.id,
                                               telegram_id=telegram_id)

        @self.bot.message_handler(commands=["select_time"])
        def select_part_of_day(message):
            """
            Provides user with part of the day options
            opens markup keyboard with part of the day options
            :param message: message from the user
            """
            parts_of_day = ["Morning", "Afternoon", "Evening"]  # options
            parts_of_day_rus = ["Утро", "День", "Вечер"]  # options in Russian
            part_of_day_markup = get_custom_keyboard(items=parts_of_day,
                                                     one_time_keyboard=True)
            part_of_day_markup_rus = get_custom_keyboard(
                items=parts_of_day_rus, one_time_keyboard=True)
            telegram_id = get_user_telegram_id(message)
            user_language = self.data_base_handler.get_user_language(
                telegram_id=telegram_id)
            choose_part_of_day_message = ""  # message to be sent
            if user_language == "English":
                choose_part_of_day_message = "Choose part of the day to get news at:"
                self.bot.send_message(message.chat.id,
                                      choose_part_of_day_message,
                                      reply_markup=part_of_day_markup)
            elif user_language == "Russian":
                choose_part_of_day_message = "Выберите время дня, в которое Вы хотите получать новости:"
                self.bot.send_message(message.chat.id,
                                      choose_part_of_day_message,
                                      reply_markup=part_of_day_markup_rus)

        @self.bot.message_handler(commands=["select_topics"])
        def select_topics(message):
            telegram_id = get_user_telegram_id(message)
            #  flag if user has any topics:
            user_check_topics = data_base_handler.check_topics(
                telegram_id=telegram_id)

            language = self.data_base_handler.get_user_language(
                telegram_id=telegram_id)
            select_topic_message = "Select topics you want to get news on:"
            topics_markup = get_custom_keyboard(items=self.topics,
                                                one_time_keyboard=True,
                                                basic=True)  # topics markup
            markup_items = self.topics  # items to make a markup
            if language == "Russian":
                markup_items = self.topics_rus
                if user_check_topics:
                    markup_items = self.topics_ok_rus
                send_translated_message(select_topic_message,
                                        telegram_id=telegram_id,
                                        chat_id=message.chat.id,
                                        markup_items=markup_items)
            if language == "English":
                markup_items = self.topics
                if user_check_topics:
                    markup_items = self.topics_ok
                self.bot.send_message(message.chat.id,
                                      select_topic_message,
                                      reply_markup=get_custom_keyboard(
                                          items=markup_items, basic=True))

        @self.bot.message_handler(commands=["lul"])
        def lul(message):
            telegram_id = get_user_telegram_id(message)
            self.send_news_to_user(telegram_id=telegram_id,
                                   chat_id=message.chat.id)

        @self.bot.message_handler(commands=["basic"])
        def basic(message):
            show_basic_keyboard(message, text="LUL", language="Russian")

        @self.bot.message_handler(commands=["delete_topics"])
        def delete_topics(message):
            """
            pops up a delete topics markup keyboard

            :param message: message object received from the user

            """
            telegram_id = get_user_telegram_id(message)
            user_language = self.data_base_handler.get_user_language(
                telegram_id=telegram_id)
            are_topics_added = self.data_base_handler.check_topics(
                telegram_id=telegram_id)
            if not are_topics_added:
                no_topics_message = "You have no topics. Add some)"
                no_topics_message_rus = "Вы еще не добавили темы. Добавьте несколько):"
                topics_markup = get_custom_keyboard(items=self.topics,
                                                    one_time_keyboard=True,
                                                    basic=True)
                topics_markup_rus = get_custom_keyboard(items=self.topics_rus,
                                                        one_time_keyboard=True,
                                                        basic=True)
                if user_language == "English":
                    self.bot.send_message(message.chat.id,
                                          no_topics_message,
                                          reply_markup=topics_markup)
                if user_language == "Russian":
                    self.bot.send_message(message.chat.id,
                                          no_topics_message_rus,
                                          reply_markup=topics_markup_rus)

            else:
                user_topics = str(
                    data_base_handler.get_user_topics(telegram_id=telegram_id))
                user_topics = user_topics.split(";")[:-1]  # user's topics
                select_topic_message = "Please select a topic you want to delete:"
                select_topic_message_rus = "Выберите тему, которую Вы хотите удалить:"
                topics_list = []
                for topic in user_topics:
                    if user_language == "English":
                        topics_list.append("- " + topic)
                    elif user_language == "Russian":
                        topic_rus = self.language_handler.translate(
                            topic,
                            first_language="English",
                            second_language="Russian")
                        topics_list.append("- " + topic_rus)
                if user_language == "English":
                    topics_list.append("-Cancel")
                if user_language == "Russian":
                    topics_list.append("-Отмена")
                if user_language == "English":
                    self.bot.send_message(message.chat.id,
                                          select_topic_message,
                                          reply_markup=get_custom_keyboard(
                                              items=topics_list, basic=True))
                if user_language == "Russian":
                    self.bot.send_message(message.chat.id,
                                          select_topic_message_rus,
                                          reply_markup=get_custom_keyboard(
                                              items=topics_list, basic=True))
                """
                TO DO:
                add markup keyboard with user topics
                add method for handling button press
                """

        @self.bot.message_handler(commands=["info"])
        def info(message):
            name = self.get_me()
            print(name)
            print(message.from_user)

        def change_language(message):
            text = str(message.text)
            if text == "Change language  " + u'\U0001F5E3'\
                    or text == "Поменять язык  " + u'\U0001F5E3':
                select_language(message)

        @self.bot.message_handler(content_types=["text"])
        def text_is_received(message):
            select_time(message)
            country_name_selected(message)
            time_selected(message)
            topic_selected(message)
            num_of_articles_selected(message)
            language_selected(message)
            change_language(message)
            ok_message_received(message)
            add_topics_message_received(message)
            select_time_message_received(message)
            delete_topic_selected(message)
            change_num_of_articles_message_received(message)
            delete_topics_message_received(message)
            select_country_message_received(message)
            check_swearing_word(message)
            check_apologies(message)
            cancel_delete_check(message)

        def country_name_selected(message):
            """
            handler for country selection
            :param message:
            """
            country = str(message.text)  # country user sent to the bot
            telegram_id = get_user_telegram_id(message)  # user's telegram id
            user_language = self.data_base_handler.get_user_language(
                telegram_id=telegram_id)
            is_user_registered = check_user_registration(
                telegram_id=telegram_id)
            current_time = date.today()  # current date
            country_name_selected_message = \
                "OK, I will send you news about " + country
            country_name_selected_message_rus = "OK, Я буду отправлять новости из страны \'" + country + "\'"
            if user_language == "English":
                if country in self.countries:  # user uses English
                    if not is_user_registered:
                        self.bot.send_message(message.chat.id,
                                              country_name_selected_message
                                              )  # sends message to the user
                    else:
                        show_basic_keyboard(message,
                                            country_name_selected_message)
                    print("Country is selected")

                    self.data_base_handler.add_country(
                        telegram_id=telegram_id,
                        country_name=country,
                        current_time=current_time)

                    if not is_user_registered:
                        select_num_of_articles(message)
            if user_language == "Russian":  # user uses Russian
                country_eng = self.language_handler.translate(
                    country,
                    first_language="Russian",
                    second_language="English")
                if country in self.countries_rus:
                    if not is_user_registered:  # user is not registered
                        self.bot.send_message(
                            message.chat.id, country_name_selected_message_rus)
                    else:  # user is registered
                        show_basic_keyboard(message,
                                            country_name_selected_message_rus)
                    self.data_base_handler.add_country(
                        telegram_id=telegram_id,
                        country_name=country_eng,
                        current_time=current_time)
                    if not is_user_registered:
                        select_num_of_articles(message)

        def topic_selected(message):
            """
            handler for topic selection
            :param message:  message from the user
            """
            topic = str(get_topic_name(topic=message.text))
            print("TOPIC: ", topic)
            telegram_id = get_user_telegram_id(message)  # user telegram id
            language = data_base_handler.get_user_language(
                telegram_id=telegram_id)

            if topic != "OK" and (topic in self.all_topics
                                  or topic in self.all_topics_rus):
                print("TOPICS: ", self.topics)
                topic_selected_message = "Alright, " + topic + " is added to your topics"
                topic_is_used_message = "You already have " + topic + " in your topics"
                topic_selected_message_rus = "Хорошо, тема \'" + \
                                             self.language_handler.translate(topic, first_language="English",
                                                                             second_language="Russian") + \
                                             "\" добавлена в ваши темы"
                topic_is_used_message_rus = "Тема \'" + topic + "\' уже была добавлена в Ваши темы"
                # makes a request to the database and returns the result:
                if topic in self.topics_rus or topic in self.all_topics_rus:
                    topic_eng = self.language_handler.translate(
                        topic, first_language="rus", second_language="eng")
                else:
                    topic_eng = topic

                res = self.data_base_handler.add_topic(telegram_id=telegram_id,
                                                       topic=topic_eng)
                if res:  # topic could be added

                    if language == "Russian":
                        self.bot.send_message(message.chat.id,
                                              topic_selected_message_rus)
                    else:
                        self.bot.send_message(message.chat.id,
                                              topic_selected_message)
                else:  # topic was added before
                    if language == "English":  # user uses English
                        self.bot.send_message(message.chat.id,
                                              topic_is_used_message)
                    elif language == "Russian":  # user uses Russian
                        self.bot.send_message(message.chat.id,
                                              topic_is_used_message_rus)

        def delete_topic_selected(message):
            """
            Handles topic user sent and deletes it from the user's topics
            :param message:
            :return:
            """
            topic = str(str(message.text)[2:])
            if topic not in self.topics and topic not in self.topics_rus:
                return
            telegram_id = get_user_telegram_id(message)  # user's telegram id
            user_language = self.data_base_handler.get_user_language(
                telegram_id=telegram_id)
            topic_deleted_message = "OK. Topic " + topic + " was deleted from your topics"
            topic_deleted_message_rus = "OK. Тема \'" + topic + "\' была удалена из Ваших тем"
            error_message = "Please, select one topic from the list"
            error_message_rus = "Пожалуйста, выберите одну тему из списка"
            user_topics = str(
                data_base_handler.get_user_topics(telegram_id=telegram_id))
            user_topics = user_topics.split(";")[:-1]  # user's topics

            topics_list = []
            for t in user_topics:
                if user_language == "English":
                    topics_list.append("- " + t)
                elif user_language == "Russian":
                    topic_rus = self.language_handler.translate(
                        t, first_language="English", second_language="Russian")
                    topics_list.append("- " + topic_rus)

            if user_language == "English":
                if topic in self.topics:
                    self.data_base_handler.delete_topic(
                        telegram_id=telegram_id, topic=topic)
                    show_basic_keyboard(message, topic_deleted_message)

            if user_language == "Russian":
                if topic in self.topics_rus:
                    topic_eng = self.language_handler.translate(
                        topic,
                        first_language="Russian",
                        second_language="English")
                    self.data_base_handler.delete_topic(
                        telegram_id=telegram_id, topic=topic_eng)
                    show_basic_keyboard(message, topic_deleted_message_rus)

        def language_selected(message):
            language = str(message.text)
            if language in self.languages:
                telegram_id = get_user_telegram_id(message)  # user telegram id
                language_selected_message = "OK now I will send you messages in " + str(
                    language)
                current_time = date.today()  # current date
                self.data_base_handler.add_language(telegram_id=telegram_id,
                                                    language=language,
                                                    current_time=current_time)

                is_registered = check_user_registration(
                    telegram_id=telegram_id)
                if not is_registered:  # user is not registered
                    select_topics(message)
                if is_registered:
                    show_basic_keyboard(message,
                                        language_selected_message,
                                        language=language)

        def num_of_articles_selected(message):
            max_num_of_articles = self.MAX_NUM_OF_ARTICLES
            num_of_articles = str(message.text)
            telegram_id = get_user_telegram_id(message)
            user_language = self.data_base_handler.get_user_language(
                telegram_id=telegram_id)
            current_time = date.today()
            is_user_registered = check_user_registration(
                telegram_id=telegram_id)
            num_of_articles_selected_message = "OK. I will send you " + str(
                num_of_articles) + " articles on each topic"
            num_of_articles_selected_message_rus = "OK. Я буду отправлять Вам по " + str(
                num_of_articles) + " статьи на каждую тему"
            error_message = "Please, enter a number from 1 to " + str(
                max_num_of_articles)
            error_message_rus = "Пожалуйста, введите число от 1 до " + str(
                max_num_of_articles)

            if user_language == "English":
                if num_of_articles.isdigit(
                ) and 0 < int(num_of_articles) <= max_num_of_articles:
                    self.data_base_handler.add_num_of_articles(
                        telegram_id=telegram_id,
                        current_time=current_time,
                        num_of_articles=num_of_articles)
                    if not is_user_registered:
                        self.data_base_handler.update_user_first_time_enter(
                            telegram_id=telegram_id)
                    show_basic_keyboard(message,
                                        num_of_articles_selected_message)

                else:
                    if num_of_articles.isdigit():
                        self.bot.send_message(message.chat.id, error_message)
            if user_language == "Russian":
                if num_of_articles.isdigit(
                ) and 0 < int(num_of_articles) <= max_num_of_articles:
                    self.data_base_handler.add_num_of_articles(
                        telegram_id=telegram_id,
                        current_time=current_time,
                        num_of_articles=num_of_articles)
                    if not is_user_registered:
                        self.data_base_handler.update_user_first_time_enter(
                            telegram_id=telegram_id)
                    show_basic_keyboard(message,
                                        num_of_articles_selected_message_rus)
                else:
                    if num_of_articles.isdigit():
                        self.bot.send_message(message.chat.id,
                                              error_message_rus)

        def select_time(message):
            """
            Handles part of the day message from the user
            sends markup for time selection
            :param message: message from the user
            """
            morning_time_options = [
                "5:00", "6:00", "7:00", "8:00", "9:00", "10:00", "11:00"
            ]  # options for morning
            afternoon_time_options = [
                "12:00", "13:00", "14:00", "15:00", "16:00"
            ]  # options for afternoon
            evening_time_options = [
                "17:00", "18:00", "19:00", "20:00", "21:00", "22:00", "23:00",
                "00:00"
            ]  # options for evening
            select_time_message = "Select time you want to get news at:"
            select_time_message_rus = "Выберите время, в которое Вы хотите получать новости:"
            text = str(message.text)
            morning_markup = get_custom_keyboard(
                items=morning_time_options,
                one_time_keyboard=True)  # markup for morning options
            afternoon_markup = get_custom_keyboard(
                items=afternoon_time_options,
                one_time_keyboard=True)  # markup for afternoon options
            evening_markup = get_custom_keyboard(
                items=evening_time_options,
                one_time_keyboard=True)  # markup for evening options
            if text == "Morning":
                self.bot.send_message(
                    message.chat.id,
                    select_time_message,
                    reply_markup=morning_markup)  # sends markup for morning
            if text == "Afternoon":
                self.bot.send_message(message.chat.id,
                                      select_time_message,
                                      reply_markup=afternoon_markup
                                      )  # sends markup for afternoon
            if text == "Evening":
                self.bot.send_message(
                    message.chat.id,
                    select_time_message,
                    reply_markup=evening_markup)  # sends markup for evening
            if text == "Утро":
                self.bot.send_message(message.chat.id,
                                      select_time_message_rus,
                                      reply_markup=morning_markup)
            if text == "День":
                self.bot.send_message(message.chat.id,
                                      select_time_message_rus,
                                      reply_markup=afternoon_markup)
            if text == "Вечер":
                self.bot.send_message(message.chat.id,
                                      select_time_message_rus,
                                      reply_markup=evening_markup)

        def time_selected(message):
            """
            Handles time message from user
            :param message: message object received from the user
            :return:
            """
            text = str(message.text)
            hours = [str(i) for i in range(0, 24)]
            print(text.split(":"))
            if text.split(":")[0] in hours and text.split(":")[-1] == "00":
                selected_time = str(message.text)  # selected time
                telegram_id = get_user_telegram_id(
                    message)  # user's telegram id
                current_time = date.today()  # current date
                is_user_registered = check_user_registration(
                    telegram_id=telegram_id)
                user_language = self.data_base_handler.get_user_language(
                    telegram_id=telegram_id)
                self.data_base_handler.add_time(telegram_id=telegram_id,
                                                news_time=selected_time,
                                                current_time=current_time)
                time_selected_message = "OK, I will send you news at " + str(
                    selected_time) + " every day"
                time_selected_message_rus = "OK. Я буду отравлять новости в " + str(
                    selected_time) + " каждый день"
                if user_language == "English":
                    if not is_user_registered:
                        self.bot.send_message(message.chat.id,
                                              time_selected_message)
                    else:
                        show_basic_keyboard(message, time_selected_message)
                if user_language == "Russian":
                    if not is_user_registered:
                        self.bot.send_message(message.chat.id,
                                              time_selected_message_rus)
                    else:
                        show_basic_keyboard(message, time_selected_message_rus)

                if not is_user_registered:
                    select_country(message)

        def ok_message_received(message):
            """
            Handles OK message from user
            Sends the user's list of topics
            :param message: message object received from the user
            """
            text = str(message.text)
            telegram_id = get_user_telegram_id(message)
            user_language = data_base_handler.get_user_language(
                telegram_id=telegram_id)
            user_registered = check_user_registration(telegram_id=telegram_id)
            if text == "OK" or text == "ОК":  # OK in English or Russian
                user_topics = str(
                    data_base_handler.get_user_topics(telegram_id=telegram_id))
                topics_list_message = "OK. Now your topics are: \n"  # string with user topics
                if user_language == "Russian":  # user uses Russian
                    topics_list_message = "OK. Ваши темы: \n"
                user_topics = user_topics.split(";")[:-1]  # user's topics
                print("USER_TOPICS: ", user_topics)
                for topic in user_topics:  # adds all user's topics to string
                    if user_language == "English":
                        topics_list_message += "- " + topic + "\n"
                    if user_language == "Russian":
                        translated_topic = self.language_handler.translate(
                            message=topic,
                            first_language="English",
                            second_language="Russian")
                        topics_list_message += "- " + translated_topic + "\n"
                if not user_registered:
                    self.bot.send_message(message.chat.id, topics_list_message)
                else:
                    show_basic_keyboard(message, topics_list_message)
                if not user_registered:  # user is not registered
                    select_part_of_day(message)

        def add_topics_message_received(message):
            """
            Handles 'Add topics' message from the user
            :param message: message object received from the user
            """
            text = str(message.text)
            telegram_id = get_user_telegram_id(message)
            if text == "Add topics  " + u'\U00002795' or text == "Добавить темы  " + u'\U00002795':
                select_topics(message)

        def select_time_message_received(message):
            """
            Handles 'Change time' message from the user
            :param message: message object from the user
            """
            text = str(message.text)
            if text == "Change news time  " + u'\U000023F1' or \
                    text == "Поменять время отправки новостей  " + u'\U000023F1':
                select_part_of_day(message)

        def select_country_message_received(message):
            text = str(message.text)
            if text == "Select country  " + u'\U0001F3F3' or \
                    text == "Выбрать страну  " + u'\U0001F3F3':
                select_country(message)

        def change_num_of_articles_message_received(message):
            """
            Handles 'Change number of articles message' from the user
            :param message: message object from the user
            :return:
            """
            text = str(message.text)
            if text == "Change number of articles  " + u'\U0001F522' \
                    or text == "Изменить число статей " + u'\U0001F522':
                select_num_of_articles(message)

        def delete_topics_message_received(message):
            text = str(message.text)
            if text == "Delete topics  " + u'\U00002716' or text == "Удалить темы  " + u'\U00002716':
                delete_topics(message)

        def get_user_nickname(message):
            """
            gets user's nickname in telegram
            :param message:
            :return: nickname: str
            """
            nickname = message.from_user.username  # gets nickname
            return nickname

        def get_user_telegram_id(message):
            """
            gets user's telegram id
            :param message:
            :return: telegram_id
            """
            telegram_id = message.from_user.id  # gets telegram id
            return telegram_id

        def get_custom_keyboard(items, basic=False, **k):
            """
            makes custom keyboard with specified items
            :param items: list
            :return: ReplyKeyboardMarkup object
            """
            is_basic_layout = basic
            markup = types.ReplyKeyboardMarkup(**k)
            if is_basic_layout:
                n = len(items)
                NUM_OF_COLUMNS = 2
                for i in range(0, n, NUM_OF_COLUMNS):
                    cur_items = []
                    for j in range(NUM_OF_COLUMNS):
                        if i + j < n:
                            cur_items.append(items[i + j])
                    markup.row(*cur_items)
                return markup
            for item in items:
                markup.add(str(item))
            return markup

        def check_user_registration(telegram_id):
            """

            :param telegram_id: int;  Telegram id of the user
            :return: True if user was registered before
                     False if user wasn't registered
            """
            first_time_enter = self.data_base_handler.get_user_first_time_enter(
                telegram_id=telegram_id)

            print("IS_REGISTERED:", first_time_enter)
            print("RERERE: ", self.invert_bool(first_time_enter))
            return self.invert_bool(first_time_enter)

        def check_swearing_word(message):
            """
            checks if the user enters a swearing word
            """
            words = str(message.text).lower().split("  ")[0].split(" ")
            for word in words:
                if word in swearing_words_rus:  # swearing word in Russian
                    print(word)
                    markup = get_custom_keyboard(items=self.apologies_options)
                    self.bot.send_message(
                        message.chat.id,
                        "Ты сказал некультурное слово!\nИзвинись",
                        reply_markup=markup)
                    break

        def check_apologies(message):
            text = str(message.text)
            if text in self.apologies_options:
                show_basic_keyboard(message,
                                    text="Ваши извинения приняты )",
                                    language="Russian")

        def cancel_delete_check(message):
            text = str(message.text)
            telegram_id = get_user_telegram_id(message)
            user_language = self.data_base_handler.get_user_language(
                telegram_id=telegram_id)
            if text == "-Отмена" or text == "-Cancel":
                if user_language == "Russian":
                    show_basic_keyboard(message,
                                        text="Хорошо, я не буду удалять темы")
                if user_language == "English":
                    show_basic_keyboard(message,
                                        text="OK. I will not delete topics")

        def add_user_to_database(message):
            """
            Adds user data to the database
            :param message:
            """
            current_time = date.today()  # gets current date
            telegram_id = get_user_telegram_id(
                message)  # gets user's telegram id
            try:
                self.data_base_handler.add_user(register_time=current_time,
                                                telegram_id=telegram_id)
            except Exception as e:
                print("Add user crash")
                print(str(e))

        def news_to_text(message, news):
            """
            Transforms news dictionary to text
            Gets list of dictionaries
            :return:
            """
            message_text = ""
            telegram_id = get_user_telegram_id(message)
            user_language = self.data_base_handler.get_user_language(
                telegram_id=telegram_id)
            print("NEWS_TO_TEXT", news)
            for article in news:
                message_text = ""
                photo_url = article["urlToImage"]
                if user_language == "English":  # makes message in English
                    message_text += "- Article by " + article["source"][
                        "name"] + "\n"
                    message_text += "- Title: " + article["title"] + "\n"
                    message_text += "- Article: " + article["content"] + "\n"
                    message_text += "Read full article on " + article["url"]
                if user_language == "Russian":
                    message_text += "- Автор: " + article["source"][
                        "name"] + "\n"
                    message_text += "- Заголовок: " + article["title"] + "\n"
                    message_text += "- Прочитать статью полностью можно на " + article[
                        "url"]
                print("MESSAGE_TEXT", message_text)

                if photo_url != "None" and photo_url != None:
                    self.bot.send_photo(message.chat.id,
                                        photo=photo_url,
                                        caption=message_text)
                else:
                    self.bot.send_message(message.chat.id, message_text)

        def send_translated_message(text, **params):
            telegram_id = params.get("telegram_id", None)  # user's telegram id
            chat_id = params.get("chat_id", None)  # chat id to send message
            markup_items = params.get("markup_items", None)
            user_language = self.data_base_handler.get_user_language(
                telegram_id=telegram_id)

            if user_language == "Russian":
                #  translates message into russian:
                translated_message = self.language_handler.translate(
                    message=text,
                    first_language="English",
                    second_language="Russian")
                # sends message with no markup
                if not markup_items:
                    self.bot.send_message(chat_id, translated_message)
                else:
                    markup = get_custom_keyboard(items=markup_items,
                                                 basic=True)
                    self.bot.send_message(chat_id,
                                          translated_message,
                                          reply_markup=markup)

        def show_basic_keyboard(message, text, **k):
            #self.bot.send_message(message.chat.id, "", reply_markup=self.markup_hider)
            lang = k.get("language", "English")
            telegram_id = get_user_telegram_id(message)
            user_language = self.data_base_handler.get_user_language(
                telegram_id=telegram_id)
            basic_markup = get_custom_keyboard(items=self.basic_markup_buttons,
                                               basic=True)
            if user_language == "Russian":
                text = self.language_handler.translate(
                    text, first_language="English", second_language="Russian")
                basic_markup = get_custom_keyboard(
                    items=self.russian_basic_markup_buttons, basic=True)
            self.bot.send_message(message.chat.id,
                                  str(text),
                                  reply_markup=basic_markup)

        def get_topic_name(topic):
            words = topic.split("  ")
            return words[0]

    def get_token(self):
        """
        gets token from different types of files
        :return: token: str
        """
        token_path_file_name = self.token_path.split("/")[
            -1]  # name of file with token
        token_path_extension = token_path_file_name.split(".")[
            -1]  # extension of token file
        if token_path_extension == "txt":  # text file
            return self.get_token_from_txt()

    def send_news_to_users(self, ids):
        """
        :param ids: list    list of users telegram_ids
        """

    def get_token_from_txt(self):
        """
        gets token from txt file
        :return: token: str
        """
        f = open(self.token_path, "r")
        return f.read()

    def polling(self, *args):
        self.bot.polling(*args)

    def invert_bool(self, x):
        if x == True or x == "True":
            return False
        else:
            return True
Exemple #13
0
    draw.text((margin[0], margin[1]), text, font=fnt, fill=fnt_color)

    if show_image:
        new_img.show()

    file_name = f"{text}_{str(uuid.uuid4())}.jpg"
    file_path = f"storage/{file_name}.jpg"
    new_img.save(file_path)
    return file_name, file_path


@bot.message_handler(commands=["anti"])
def generate(msg: Message):
    txt = msg.text.replace("/anti", "").strip()
    if not txt:
        bot.reply_to(msg, "usage: /anti text")
        return
    if matched := color.search(txt):
        rgb = matched[0]
        name, path = anti(txt.replace(rgb, "").strip(), bg_color=rgb)
    else:
        name, path = anti(txt)
    with open(path, "rb") as f:
        bot.send_photo(msg.chat.id, f)


if '__main__' == __name__:
    """
    anti('Suisei anti detected', margin=(20, 10), show_image=True)"""
    bot.polling()
Exemple #14
0
class RadBot:
    lastUnlockTrigger = 1613408400
    nextUnlockTarget = 0.17

    def __init__(self, token=RADBOT_TOKEN):
        self.telegram = TeleBot(token)
        self.portfolio = RadixPortfolio([])
        self.trender = RewardTrender()
        self.uniswap = UniswapInfo()

    def getSMA(self):
        req = requests.get('http://api.coingecko.com/api/v3/coins/e-radix/market_chart?vs_currency=usd&days=7&interval=hourly')
        prices = pd.DataFrame(req.json()['prices'])
        prices = prices[prices[0]>1000*self.lastUnlockTrigger]
        return prices[1].mean()


    def nextUnlock(self):
        t = time.time()
        self.updatePrice()
        SMA = self.getSMA()

        msg = f"Current spot price: {round(self.price,4)} USDC/eXRD\n"

        timeLeft = (self.lastUnlockTrigger + 60*60*24*7) - t
        if timeLeft < 0:
            msg += "Minimum time to next unlock has passed.\n"
        else:
            days, r = divmod(timeLeft, 60*60*24)
            hours, r = divmod(r, 60*60)
            minutes = int(r/60)
            msg += f"Minimum time to next unlock: {int(days)}d, {int(hours)}h, {int(minutes)}m.\n"

        msg += f"Next unlock SMA target: {self.nextUnlockTarget} $\n"
        msg += f"Current CoinGecko SMA: {round(SMA,4)} $"
        return msg


    def updatePrice(self):
        getReserves = poolContract.functions.getReserves()
        (pool_eXRD, pool_USDC, t) = getReserves.call()
        self.pool_eXRD = pool_eXRD
        self.pool_USDC = pool_USDC

        self.price = self.pool_USDC*1e12/self.pool_eXRD
        return self.price


    def calcMarketCap(self):
        self.lockedAmount = 0
        for l in locked:
            balanceOf = eXRD_Contract.functions.balanceOf(l)
            self.lockedAmount += balanceOf.call()

        totalSupply = eXRD_Contract.functions.totalSupply()
        self.supply = totalSupply.call()
        self.unlocked = self.supply - self.lockedAmount

        self.updatePrice()
        self.mcap = self.price*(self.unlocked)/1e18

        SMA7 = self.getSMA()

        msg =  f"Current spot price: {round(self.price,4)} USDC/eXRD\n"
        msg += f"Current 7-day SMA: ${round(SMA7,4)}\n"
        msg += f"Current Market Cap: {round(self.mcap/1e6,2)} MM USDC\n"
        msg += f"Percentage in LP: {round(100*self.pool_eXRD/self.unlocked,2)}%"

        return msg


    def analyseWallets(self, wallets, colors=False):
        try:
            self.portfolio = RadixPortfolio(wallets)
        except Exception as e:
            print('Failed to retrieve wallet information: ' + repr(e))
            return "Failed to retrieve wallet information"

        try:
            uni_balances = self.uniswap.getBalances(wallets)
        except Exception as e:
            print('Failed to load Uniswap Info: ' + repr(e))
            return "Failed to load Uniswap Info"

        LPs = self.portfolio.assets['naked LP'].sum()+self.portfolio.assets['staked LP'].sum()
        poolShare = LPs / self.portfolio.totalLPs
        pooled_USDC = poolShare * self.portfolio.pool_USDC / 1e6
        pooled_eXRD = poolShare * self.portfolio.pool_eXRD / 1e18
        totalRewards = self.portfolio.assets.rewards.sum()

        msg =   "Analysis of requested wallet(s)\n"
        msg += f"Unstaked USDC: {round(self.portfolio.assets.USDC.sum()/1e6,2)}\n"
        msg += f"Unstaked eXRD: {round(self.portfolio.assets.eXRD.sum()/1e18,2)}\n"
        msg += f"Pooled USDC: {round(pooled_USDC,2)}\n"
        msg += f"Pooled eXRD: {round(pooled_eXRD,2)}\n"
        msg += f"Total Rewards: {round(totalRewards,2)}\n"
        msg += "--------------------------------+\n"
        msg += f"Total value: {round(self.portfolio.assets.value.sum(),2)} USDC"

        t = pd.Timestamp.now()
        trendDF = self.trender.calcRewardsOverTime(self.portfolio.stakes)
        d_columns = [c for c in trendDF.columns if 'donated ' in c]
        donated = trendDF[d_columns].sum(axis=1)
        donated = donated.groupby(donated.index).last()
        donated[t] = np.NaN
        donated = donated.sort_index().interpolate(method='polynomial',order=2)[t]

        msg += f"\n\nRewards mined through staking: {round(totalRewards-donated,2)}"
        msg += f"\nRewards donated by early leavers: {round(donated,2)}"

        if len(uni_balances):
            fees_USDC = 0
            fees_eXRD = 0
            ROI_pool = 0
            ROI_HODL = 0
            invested = 0
            for balance in uni_balances:
                price_change_factor = self.portfolio.pool_USDC / self.portfolio.pool_eXRD / balance['USDC'] * balance['eXRD']
                growth_factor = sqrt(price_change_factor)
                stake_share = balance['LP'] / self.portfolio.totalLPs
                current_USDC = stake_share * self.portfolio.pool_USDC / 1e6
                current_eXRD = stake_share * self.portfolio.pool_eXRD / 1e18
                initial_USDC = balance['USDC'] / 1e6
                initial_eXRD = balance['eXRD'] / 1e18
                expected_USDC = initial_USDC * growth_factor
                expected_eXRD = initial_eXRD / growth_factor
                fees_USDC += current_USDC - expected_USDC
                fees_eXRD += current_eXRD - expected_eXRD
                invested += 2 * initial_USDC
                ROI_pool += 2 * expected_USDC - 2 * initial_USDC
                ROI_HODL += initial_eXRD * (current_USDC / current_eXRD - initial_USDC / initial_eXRD)

            rewardsValue = totalRewards * self.portfolio.spot_price
            totalROI = rewardsValue + ROI_pool + 2*fees_USDC
            msg += f"\n\nUnclaimed reward value: {round(rewardsValue,2)} USDC"
            msg += f"\nUniSwap fees value: {round(2 * fees_USDC, 2)} USDC"
            msg += f"\nPool ROI (ex fees): {round(ROI_pool,2)} USDC"
            msg += f"\nTotal LP+LM ROI: {round(totalROI,2)} USDC ({round(100 * totalROI / invested, 1)}%)"

            msg += f"\n\nROI if you had HODL'd: {round(ROI_HODL,2)} USDC ({round(100 * ROI_HODL / invested, 1)}%)"
            msg += f"\nROI if you had YOLO'd: {round(2*ROI_HODL,2)} USDC ({round(200 * ROI_HODL / invested, 1)}%)"

        if len(self.portfolio.stakes): msg += "\n\nStaking details:"
        for i in range(len(self.portfolio.stakes)):
            stake = self.portfolio.stakes.iloc[i]
            age = round((stake.t1 - stake.t0) / (60 * 60 * 24), 2)
            if colors:
                msg += f"\nStake {i} - age {age}d - current APY {round(stake.APY_current, 2)}% - green {round(stake.green, 2)}% - red {round(stake.red, 2)}% - orange {round(stake.orange, 2)}% - blue {round(stake.blue, 2)}%"
            else:
                msg += f"\nStake {i} - age {age}d - rewards {round(stake.rewards, 2)} - bonus {round(6 * stake.bonus, 2)} - current APY {round(stake.APY_current, 2)}% - average APY {round(stake.APY_realized, 2)}%"

        if len(self.portfolio.stakes) > 1:
            overallAPY = sum(self.portfolio.stakes.stake*self.portfolio.stakes.APY_current)/sum(self.portfolio.stakes.stake)
            overallBonus = 6*sum(self.portfolio.stakes.stake*self.portfolio.stakes.bonus)/sum(self.portfolio.stakes.stake)
            msg += f"\n\nWeighted average current APY: {round(overallAPY,2)}%"
            msg += f"\nWeighted average bonus factor: {round(overallBonus,2)}"
            msg += f"\nTotal unclaimed eXRD rewards: {round(self.portfolio.stakes.rewards.sum(),2)}"

        return msg


    def rewardsProjection(self, wallets):
        try:
            self.portfolio = RadixPortfolio(wallets)
        except:
            raise Exception("Failed")

        self.trender.updateEventList()
        return self.trender.plotRewards(self.portfolio.stakes)


    def calcAPY(self):
        msg =  f"Current spot price: {round(self.updatePrice(),4)} USDC/eXRD\n"
        msg += f"Current initial APY: {round(self.portfolio.initial_APY,2)}%\n"
        msg += f"Current nominal APY: {round(self.portfolio.nominal_APY,2)}% ({round(6*self.portfolio.nominal_APY,2)}%)\n"

        return msg


    def helpMessage(self):
        msg = "Welcome to RadBot!\n"
        msg += "\nCurrent commands:"
        msg += "\n  /a <address(es)> --> Analyse wallet(s)"
        msg += "\n  /apy --> Current LM APY"
        msg += "\n  /mcap --> eXRD market cap"
        msg += "\n  /projection <address> --> Rewards trend"
        msg += "\n  /unlock --> next unlock info"
        msg += "\n  /when --> when negative APY"
        msg += "\n  /donate --> when you're feeling generous"

        return msg


    def whenNegativeAPY(self):
        launchTime = 1605629336
        SiTi = self.portfolio.totalStakeDays
        Si = self.portfolio.totalStake

        ## Weighted average stake time
        WATS = SiTi/self.portfolio.totalStake
        ## Time to replenish the unlocked rewards pool
        resupplyTime = self.portfolio.unlocked/self.portfolio.E/60/60/24

        msg =   "Due to the reward pool mechanism, there is a possibility for older stake to lose unclaimed rewards (experience negative APY). See the slide deck at http://tiny.cc/RadixRewards for details."
        msg += f"\n\nAverage time staked: {round(WATS,2)} days"
        msg += f"\nRewards resupply time: {round(resupplyTime,2)} days"

        T_launch = (int(time.time()) - launchTime)/60/60/24

        U = self.portfolio.unlocked
        E = self.portfolio.E*(60*60*24)
        eXRD_per_LP = 2*self.portfolio.pool_eXRD/self.portfolio.totalLPs

        def APY(T0):
            B_T0 = 1/6+5/6*min((T0/90)**2,1)
            daily_eXRD_per_LP = U*B_T0/SiTi*(1 + T0*(E/U - Si/SiTi) + (T0<90)*10*(T0/90)**2/(1+5*(T0/90)**2))
            yearly_eXRD_per_LP = daily_eXRD_per_LP*365
            return 100*yearly_eXRD_per_LP/eXRD_per_LP


        targetfunc = lambda T0: T0*(E/U-Si/SiTi) + 10*(T0/90)**2/(1+5*(T0/90)**2)
        result = minimize(targetfunc,45,method='Powell',bounds=[(0,min(90,T_launch))])
        if not result['success']:
            print('Failure to optimize target function')
            return "Calculation error"

        T_min = result['x'][0]
        APY_min = APY(T_min)

        ## Weighted average stake time
        WATS = SiTi/Si
        ## Time to replenish the unlocked rewards pool
        RT = U/E

        msg =   "Due to the reward pool mechanism, there is a possibility for older stake to lose unclaimed rewards (experience negative APY). See the slide deck at http://tiny.cc/RadixRewards for details. Key parameters to monitor below:"
        msg += f"\n\nAverage time staked: {round(WATS,2)} days"
        msg += f"\nRewards resupply time: {round(RT,2)} days"

        T_launch = (int(time.time()) - launchTime)/60/60/24
        APY_launch = APY(T_launch)

        msg += f"\n\nNominal APY: {round(self.portfolio.nominal_APY,2)}% ({round(6*self.portfolio.nominal_APY,2)}%)"
        msg += f"\nInitial APY: {round(self.portfolio.initial_APY,2)}% for completely new stake"
        msg += f"\nLowest APY < 90d: {round(APY_min,2)}% for {round(T_min,1)} days old stake"
        msg += f"\nHighest APY: {round(APY(89.9999),2)}% just before reaching 90d"
        msg += f"\nLaunch stake APY: {round(APY_launch,2)}% for {round(T_launch,1)} days old stake"

        if APY_launch > 0:
            criticalStake = (1 + T_launch/RT + (T_launch<90)*(10*(T_launch/90)**2/(1+5*(T_launch/90)**2)))*SiTi/T_launch
            stakeMargin = criticalStake - Si

            USDC_per_LP = 2*self.portfolio.pool_USDC/self.portfolio.totalLPs
            USDC_margin = stakeMargin * USDC_per_LP/1e6

            msg += f"\n\nCurrently launch stake has positive APY. If more than {round(USDC_margin/1e6,2)} MM USDC of fresh stake is added, launch stake APY will go negative."
        else:
            # This should be refined for the remote option that APY_min < 0
            T_critical = max(U*SiTi/(Si*U - E*SiTi),90)
            msg += f"\n\nCurrently all stake older than {round(T_critical,1)} days has negative APY."

        msg += "\n\n"
        return msg


    def handleCommand(self, message):
        command = message.text.split()[0][1:]
        if command in ['start', 'help']:
            self.telegram.reply_to(message, self.helpMessage())
        elif command in ['apy', 'APY']:
            self.telegram.reply_to(message, self.calcAPY())
        elif command in ['a', 'analyse', 'analyze']:
            self.telegram.reply_to(message, self.analyseWallets(message.text.split()[1:]))
        elif command in ['donate']:
            self.telegram.reply_to(message, "RadBot is and will remain free to use for as long as I'll maintain her. If you find her services valuable, donations to show appreciation are welcome. Thanks for your support! \n\nETH address: 0x451423D5CA2618a3CC6944AD754A60083b3a125f")
        elif command in ['mc', 'mcap']:
            self.telegram.reply_to(message, self.calcMarketCap())
        elif command in ['projection']:
            try:
                with self.rewardsProjection(message.text.split()[1:]) as buffer:
                    self.telegram.reply_to(message, "The below is a graph of what your total rewards look like until now, and how they will develop if nobody (un/re)stakes from now on. Your actual future rewards will be less if more stake is added, and more if stake leaves before reaching 6x multiplier.")
                    self.telegram.send_photo(message.chat.id, buffer)
            except:
                self.telegram.reply_to(message, "Failed to analyze address(es).")
        elif command in ['u', 'unlock']:
            self.telegram.reply_to(message, "To reduce channel spam, unlock is now only available in DM.")
            self.telegram.send_message(message.from_user.id, self.nextUnlock())
        elif command in ['when', 'whenZeroAPY']:
            self.telegram.reply_to(message, self.whenNegativeAPY())
        else:
            self.telegram.reply_to(message, "Unknown command. Try /help for command list.")
Exemple #15
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()
Exemple #16
0
def copy_message(bot: telebot.TeleBot, msg: telebot.types.Message, chat_ids: list, disable_notification=False,
                 keyboard=None):
    last_id = chat_ids[-1]
    if len(chat_ids) > 1:
        chat_ids = chat_ids[:-1]
    else:
        chat_ids = []
    if msg.content_type == 'text':
        text = check_msg_entities(msg.entities, msg.html_text)
        for chat_id in chat_ids:
            try:
                bot.send_message(chat_id,
                                 text=text,
                                 parse_mode='html',
                                 disable_notification=disable_notification,
                                 reply_markup=keyboard
                                 )
            except telebot.apihelper.ApiException as e:
                send_error(bot, e)
                continue
            sleep(0.5)
        return bot.send_message(last_id,
                                text=text,
                                parse_mode='html',
                                disable_notification=disable_notification,
                                reply_markup=keyboard
                                )
    else:
        caption = check_msg_entities(msg.entities, msg.html_caption)
        if msg.content_type == 'photo':
            size = msg.photo[-1]
            for chat_id in chat_ids:
                try:
                    bot.send_photo(chat_id,
                                   photo=size.file_id,
                                   caption=caption,
                                   parse_mode='html',
                                   disable_notification=disable_notification,
                                   reply_markup=keyboard)
                except telebot.apihelper.ApiException as e:
                    send_error(bot, e)
                    continue
                sleep(0.5)
            return bot.send_photo(last_id,
                                  photo=size.file_id,
                                  caption=caption,
                                  parse_mode='html',
                                  disable_notification=disable_notification,
                                  reply_markup=keyboard)
        elif msg.content_type == 'audio':
            for chat_id in chat_ids:
                try:
                    bot.send_audio(chat_id,
                                   audio=msg.audio.file_id,
                                   caption=caption,
                                   parse_mode='html',
                                   disable_notification=disable_notification,
                                   reply_markup=keyboard)
                except telebot.apihelper.ApiException as e:
                    send_error(bot, e)
                    continue
                sleep(0.5)
            return bot.send_audio(last_id,
                                  audio=msg.audio.file_id,
                                  caption=caption,
                                  parse_mode='html',
                                  disable_notification=disable_notification,
                                  reply_markup=keyboard)
        elif msg.content_type == 'document':
            for chat_id in chat_ids:
                try:
                    bot.send_document(chat_id,
                                      data=msg.document.file_id,
                                      caption=caption,
                                      parse_mode='html',
                                      disable_notification=disable_notification,
                                      reply_markup=keyboard)
                except telebot.apihelper.ApiException as e:
                    send_error(bot, e)
                    continue
                sleep(0.5)
                return bot.send_document(last_id,
                                         data=msg.document.file_id,
                                         caption=caption,
                                         parse_mode='html',
                                         disable_notification=disable_notification,
                                         reply_markup=keyboard)
        elif msg.content_type == 'sticker':
            for chat_id in chat_ids:
                try:
                    bot.send_sticker(chat_id,
                                     data=msg.sticker.file_id,
                                     disable_notification=disable_notification,
                                     reply_markup=keyboard)
                except telebot.apihelper.ApiException as e:
                    send_error(bot, e)
                    continue
            sleep(0.5)
            return bot.send_sticker(last_id,
                                    data=msg.sticker.file_id,
                                    disable_notification=disable_notification,
                                    reply_markup=keyboard)
        elif msg.content_type == 'video':
            for chat_id in chat_ids:
                try:
                    bot.send_video(chat_id,
                                   data=msg.video.file_id,
                                   caption=caption,
                                   parse_mode='html',
                                   disable_notification=disable_notification,
                                   reply_markup=keyboard)
                except telebot.apihelper.ApiException as e:
                    send_error(bot, e)
                    continue
                sleep(0.5)
            return bot.send_video(last_id,
                                  data=msg.video.file_id,
                                  caption=caption,
                                  parse_mode='html',
                                  disable_notification=disable_notification,
                                  reply_markup=keyboard)
        elif msg.content_type == 'animation':
            for chat_id in chat_ids:
                try:
                    bot.send_animation(chat_id,
                                       animation=msg.animation.file_id,
                                       caption=caption,
                                       parse_mode='html',
                                       disable_notification=disable_notification,
                                       reply_markup=keyboard)
                except telebot.apihelper.ApiException as e:
                    send_error(bot, e)
                    continue
                sleep(0.5)
            return bot.send_animation(last_id,
                                      animation=msg.animation.file_id,
                                      caption=caption,
                                      parse_mode='html',
                                      disable_notification=disable_notification,
                                      reply_markup=keyboard)
        elif msg.content_type == 'voice':
            for chat_id in chat_ids:
                try:
                    bot.send_voice(chat_id,
                                   voice=msg.voice.file_id,
                                   caption=caption,
                                   parse_mode='html',
                                   disable_notification=disable_notification,
                                   reply_markup=keyboard)
                except telebot.apihelper.ApiException as e:
                    send_error(bot, e)
                    continue
                sleep(0.5)
            return bot.send_voice(last_id,
                                  voice=msg.voice.file_id,
                                  caption=caption,
                                  parse_mode='html',
                                  disable_notification=disable_notification,
                                  reply_markup=keyboard)
        elif msg.content_type == 'video_note':
            for chat_id in chat_ids:
                try:
                    bot.send_video_note(chat_id,
                                        data=msg.video_note.file_id,
                                        disable_notification=disable_notification,
                                        reply_markup=keyboard)
                except telebot.apihelper.ApiException as e:
                    send_error(bot, e)
                    continue
                sleep(0.5)
            return bot.send_video_note(last_id,
                                       data=msg.video_note.file_id,
                                       disable_notification=disable_notification,
                                       reply_markup=keyboard)
        elif msg.content_type == 'contact':
            for chat_id in chat_ids:
                try:
                    bot.send_contact(chat_id,
                                     phone_number=msg.contact.phone_number,
                                     first_name=msg.contact.first_name,
                                     last_name=msg.contact.last_name or '',
                                     disable_notification=disable_notification,
                                     reply_markup=keyboard)
                except telebot.apihelper.ApiException as e:
                    send_error(bot, e)
                    continue
                sleep(0.5)
            return bot.send_contact(last_id,
                                    phone_number=msg.contact.phone_number,
                                    first_name=msg.contact.first_name,
                                    last_name=msg.contact.last_name or '',
                                    disable_notification=disable_notification,
                                    reply_markup=keyboard)
        elif msg.content_type == 'location':
            for chat_id in chat_ids:
                try:
                    bot.send_location(chat_id,
                                      latitude=msg.location.latitude,
                                      longitude=msg.location.longitude,
                                      disable_notification=disable_notification,
                                      reply_markup=keyboard)
                except telebot.apihelper.ApiException as e:
                    send_error(bot, e)
                    continue
                sleep(0.5)
            return bot.send_location(last_id,
                                     latitude=msg.location.latitude,
                                     longitude=msg.location.longitude,
                                     disable_notification=disable_notification,
                                     reply_markup=keyboard)
        elif msg.content_type == 'venue':
            for chat_id in chat_ids:
                try:
                    bot.send_venue(chat_id,
                                   latitude=msg.venue.location.latitude,
                                   longitude=msg.venue.location.longitude,
                                   title=msg.venue.title,
                                   address=msg.venue.address,
                                   foursquare_id=msg.venue.foursquare_id,
                                   disable_notification=disable_notification,
                                   reply_markup=keyboard)
                except telebot.apihelper.ApiException as e:
                    send_error(bot, e)
                    continue
                sleep(0.5)
            return bot.send_venue(last_id,
                                  latitude=msg.venue.location.latitude,
                                  longitude=msg.venue.location.longitude,
                                  title=msg.venue.title,
                                  address=msg.venue.address,
                                  foursquare_id=msg.venue.foursquare_id,
                                  disable_notification=disable_notification,
                                  reply_markup=keyboard)
        elif msg.content_type == 'poll':
            for chat_id in chat_ids:
                try:
                    bot.forward_message(chat_id, msg.chat.id, msg.message_id)
                except telebot.apihelper.ApiException as e:
                    send_error(bot, e)
                    continue
                sleep(0.5)
            return bot.forward_message(last_id, msg.chat.id, msg.message_id)
        elif msg.content_type == 'game':
            for chat_id in chat_ids:
                try:
                    bot.forward_message(chat_id, msg.chat.id, msg.message_id)
                except telebot.apihelper.ApiException as e:
                    send_error(bot, e)
                    continue
                sleep(0.5)
            return bot.forward_message(last_id, msg.chat.id, msg.message_id)
    raise ValueError('Can\'t copy this message')
Exemple #17
0
class TelegramBot:
    def __init__(self):
        social_app = SocialApp.objects.last()
        TELEGRAM_TOKEN = social_app.secret
        TELEGRAM_WEBHOOK_HOST = social_app.sites.last().domain
        TELEGRAM_WEBHOOK_PATH = reverse("telegrambot:webhook")
        self.bot = TeleBot(TELEGRAM_TOKEN)
        self.WEBHOOK_URL = f"https://{TELEGRAM_WEBHOOK_HOST}{TELEGRAM_WEBHOOK_PATH}"
        logger.debug("%s: __init__()", self.__class__)

    def send_message(self, chat_id: int, text: str, reply_markup=None):
        try:
            self.bot.send_message(chat_id, text, reply_markup=reply_markup)
        except apihelper.ApiTelegramException as msg:
            logger.exception(msg)
        logger.debug(f"{self.__class__}: send_message({chat_id}, {text})")

    def send_photo(self,
                   chat_id: str,
                   photo_path: str,
                   caption=None,
                   reply_markup=None):
        with open(photo_path, "rb") as photo_file:
            photo = photo_file.read()
        try:
            self.bot.send_photo(chat_id,
                                photo=photo,
                                caption=caption,
                                reply_markup=reply_markup)
        except apihelper.ApiTelegramException as msg:
            logger.exception(msg)
            logger.info(
                f"{self.__class__}: User {chat_id} baned your TelegramBot")
        else:
            logger.debug(
                f"{self.__class__}: send_photo({chat_id}, {photo_path})")

    def answer_callback_query(self,
                              callback_id,
                              text=None,
                              show_alert=None,
                              url=None,
                              cache_time=None):
        self.bot.answer_callback_query(
            callback_id,
            text=text,
            show_alert=show_alert,
            url=url,
            cache_time=cache_time,
        )

    def set_webhook(self):
        logger.debug("%s: set_hook() %s" % (self.__class__, self.WEBHOOK_URL))
        return self.bot.set_webhook(url=self.WEBHOOK_URL)

    def remove_webhook(self):
        logger.debug("%s: remove_webhook()", self.__class__)
        return self.bot.remove_webhook()

    def get_kb_phone(self):
        keyboard = types.ReplyKeyboardMarkup(row_width=1, resize_keyboard=True)
        button_phone = types.KeyboardButton(text="Отправить номер телефона",
                                            request_contact=True)
        button_geo = types.KeyboardButton(text="Отправить местоположение",
                                          request_location=True)
        keyboard.add(button_phone, button_geo)
        return keyboard

    def get_kb_catalog(self):
        keyboard = types.ReplyKeyboardMarkup(row_width=1,
                                             resize_keyboard=True,
                                             one_time_keyboard=True)
        buttons = [
            types.KeyboardButton(text=item.name)
            for item in models.Catalog.objects.all()
        ]
        keyboard.add(*buttons)
        return keyboard

    def get_kb_inline_buy(self, product):
        keyboard = types.InlineKeyboardMarkup()
        buy = _("Buy")
        text = f"{buy}: {product.name}"
        buy_btn = types.InlineKeyboardButton(text,
                                             callback_data=str(product.id))
        keyboard.add(buy_btn)
        return keyboard
def send_canceled_photo(photo, bot: TeleBot, bot_state: BotState,
                        message: Message, ydisk: YandexDisk):
    state_additional = bot_state.get_state(message.from_user.id)["additional"]
    keyboard = state_additional["keyboard"]["normal"]
    photo_url = ydisk.disk.get_download_link(photo["filepath"])
    bot.send_photo(message.chat.id, photo_url, reply_markup=keyboard)