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
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)
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, "Фотографии закончились :(")
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
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
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
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
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()
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.")
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()
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')
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)