def send_emails_telegram(bot: TeleBot, chat_id: str): os.chdir("INBOX") # Переход в папку с сохраненными письмами for mail in os.listdir("."): # Получаем список папок, в которых лежит само письмо и его влложения os.chdir(mail) # Переходим в папку с письмом if os.path.exists("text_plain.txt"): # Если существует текстовая версия письма with open("text_plain.txt") as f: message = split(f.read()) bot.send_message(chat_id, message[0]) # Отправляем ее первые 4092 символа if len(message) >= 2: # И высылаем файл письма целиком (если письмо содержит более 4092 символов) bot.send_document(chat_id, open("text_plain.txt", "rb"), caption="Продолжение письма") os.remove("text_plain.txt") # Удаляем отправленный файл if os.path.exists("text_html.html"): # Если существует веб версия версия письма, то отправляем ее файлом bot.send_document(chat_id, open("text_html.html", "rb"), caption="{} (веб версия письма)".format(mail)) os.remove("text_html.html") # Удаляем отправленный файл if os.path.exists("attachments"): # Если есть вложения в письме, то отправляем и их. for file in os.listdir("attachments"): bot.send_document(chat_id, open(file, "rb")) os.remove(file) # Удаляем отправленный файл os.rmdir("attachments") # Удаляем пустую папку os.chdir("../") # Выходим из папки с письмом os.rmdir(mail) # И удаляем ее, так как она пуста os.chdir("../") # Выходим из папки с сохраннеными письмами
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
def form_and_send_new_cv_archive(bot: TeleBot, user: User): UPDATE_INTERVAL = 1 # minutes ejf = JobFair.objects.first() chat_id = user.chat_id # update archive only once in 10 min archive_last_update = ejf.cv_archive_last_update if archive_last_update: date_diff = (user.last_interaction_date - archive_last_update).total_seconds() / 60.0 if date_diff < UPDATE_INTERVAL: bot.send_message( chat_id, text=f"Почекай ще {UPDATE_INTERVAL-date_diff:.2f} хвилин...", ) return # clear archives list ejf.cv_archive_file_id_list = list() for temp_archive_path in _form_max_size_archive(bot): # show sending document bot.send_chat_action(chat_id, action="upload_document") # send archive with open(temp_archive_path, "rb") as archive: message = bot.send_document(chat_id, archive) # update db info ejf.cv_archive_file_id_list += [message.document.file_id] # delete archive os.remove(temp_archive_path) # update db info ejf.cv_archive_size = User.objects.filter(cv_file_id__ne=None).count() ejf.cv_archive_last_update = user.last_interaction_date ejf.save()
def send_email_telegram(bot: TeleBot, chat_id: str, mail: mailparser.MailParser): subject = mail.subject from_ = " ".join(mail.from_[0]) mail_name = "{} от {}".format(subject, from_) if mail.text_plain: # Если существует текстовая версия письма message = "\n".join(mail.text_plain) bot.send_message( chat_id, split(message)[0]) # Отправляем ее первые 4092 символа # И высылаем файл письма целиком (если письмо содержит более 4092 символов) if len(message) >= 2: f = io.BytesIO("{}\n\n{}".format(mail_name, message).encode()) f.name = mail_name + ".txt" bot.send_document(chat_id, f, caption="Полный текст письма") if mail.text_html: # Если существует веб версия письма, то отправляем ее файлом text_html = "\n".join(mail.text_html) f = io.BytesIO(text_html.encode()) f.name = mail_name + ".html" bot.send_document( chat_id, f, caption="{} (веб версия письма)".format("{} от {}".format( subject, from_)), ) if mail.attachments: # Если есть вложения в письме, то отправляем и их. with tempfile.TemporaryDirectory( ) as tmp_dir: # Создание временной директории для хранения вложений mail.write_attachments(tmp_dir) # Сохраняем вложения for file in os.listdir(tmp_dir): bot.send_document(chat_id, open(os.path.join(tmp_dir, file), "rb")) # Отправляем вложения
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()
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 ColorCodeBot: def __init__(self, api_key: str, lang: Mapping[str, str], theme_image_ids: tuple[str], keyboards: Mapping[str, InlineKeyboardMarkup], guesslang_syntaxes: Mapping[str, str], *args: Any, admin_chat_id: Optional[str] = None, db_path: str = str( local.path(__file__).up() / 'user_themes.sqlite'), **kwargs: Any): self.lang = lang self.theme_image_ids = theme_image_ids self.kb = keyboards self.guesslang_syntaxes = guesslang_syntaxes self.admin_chat_id = admin_chat_id self.db_path = db_path self.user_themes = KeyValue(key_field=IntegerField(primary_key=True), value_field=CharField(), database=APSWDatabase(db_path)) self.log = mk_logger() self.bot = TeleBot(api_key, *args, **kwargs) self.register_handlers() self.guesser = Guess() def register_handlers(self): self.welcome = self.bot.message_handler(commands=['start', 'help'])( self.welcome) self.browse_themes = self.bot.message_handler( commands=['theme', 'themes'])(self.browse_themes) self.mk_theme_previews = self.bot.message_handler( commands=['previews'])(self.mk_theme_previews) self.intake_snippet = self.bot.message_handler( func=lambda m: m.content_type == 'text')(self.intake_snippet) self.recv_photo = self.bot.message_handler(content_types=['photo'])( self.recv_photo) self.restore_kb = self.bot.callback_query_handler( lambda q: yload(q.data)['action'] == 'restore')(self.restore_kb) self.set_snippet_filetype = self.bot.callback_query_handler( lambda q: yload(q.data)['action'] == 'set ext')( self.set_snippet_filetype) self.set_theme = self.bot.callback_query_handler( lambda q: yload(q.data)['action'] == 'set theme')(self.set_theme) self.send_photo_elsewhere = self.bot.inline_handler( lambda q: q.query.startswith("img "))(self.send_photo_elsewhere) self.switch_from_inline = self.bot.inline_handler(lambda q: True)( self.switch_from_inline) @retry def switch_from_inline(self, inline_query: InlineQuery): self.log.msg("receiving inline query", user_id=inline_query.from_user.id, user_first_name=inline_query.from_user.first_name, query=inline_query.query) self.bot.answer_inline_query( inline_query.id, [], switch_pm_text=self.lang['switch to direct'], switch_pm_parameter='x') @retry def welcome(self, message: Message): self.log.msg("introducing myself", user_id=message.from_user.id, user_first_name=message.from_user.first_name, chat_id=message.chat.id) self.bot.reply_to( message, self.lang['welcome'], reply_markup=ForceReply( input_field_placeholder=self.lang['input field placeholder'])) @retry def mk_theme_previews(self, message: Message): if not self.admin_chat_id or str( message.chat.id) != self.admin_chat_id: self.log.msg("naughty preview attempt", user_id=message.from_user.id, user_first_name=message.from_user.first_name, chat_id=message.chat.id, admin_chat_id=self.admin_chat_id) return sample_code = dedent(""" # palinDay :: Int -> [ISO Date] def palinDay(y): '''A possibly empty list containing the palindromic date for the given year, if such a date exists. ''' s = str(y) r = s[::-1] iso = '-'.join([s, r[0:2], r[2:]]) try: datetime.strptime(iso, '%Y-%m-%d') return [iso] except ValueError: return [] """) for button in chain.from_iterable(self.kb['theme'].keyboard): theme = button.text html = mk_html(f"# {theme}{sample_code}", 'py', theme) with local.tempdir() as folder: png_path = mk_png(html, folder=folder) send_image(bot=self.bot, chat_id=message.chat.id, png_path=png_path, reply_msg_id=message.message_id) @retry def browse_themes(self, message: Message): self.log.msg("browsing themes", user_id=message.from_user.id, user_first_name=message.from_user.first_name, chat_id=message.chat.id) albums = [ self.theme_image_ids[i:i + 10] for i in range(0, len(self.theme_image_ids), 10) ] for album in albums: self.bot.send_media_group(message.chat.id, map(InputMediaPhoto, album), reply_to_message_id=message.message_id) self.bot.reply_to(message, self.lang['select theme'], reply_markup=self.kb['theme']) @retry def set_theme(self, cb_query: CallbackQuery): data = yload(cb_query.data) user = cb_query.message.reply_to_message.from_user self.log.msg("setting theme", user_id=user.id, user_first_name=user.first_name, theme=data['theme'], chat_id=cb_query.message.chat.id) self.bot.edit_message_reply_markup(cb_query.message.chat.id, cb_query.message.message_id, reply_markup=minikb('theme')) self.user_themes[user.id] = data['theme'] self.bot.answer_callback_query( cb_query.id, text=self.lang['acknowledge theme'].format(data['theme'])) if self.admin_chat_id: with open(self.db_path, 'rb') as doc: self.bot.send_document(self.admin_chat_id, doc) def guess_ext(self, code: str, probability_min: float = .12) -> Optional[str]: syntax, probability = self.guesser.probabilities(code)[0] ext = self.guesslang_syntaxes.get(syntax) self.log.msg("guessed syntax", probability_min=probability_min, probability=probability, syntax=syntax, ext=ext) if probability >= probability_min: return ext for start, ext in { '{': 'json', '---\n': 'yaml', '[[': 'toml', '[': 'ini', '<?php': 'php', '<': 'xml', '-- ': 'lua' }.items(): if code.startswith(start): return ext @retry def intake_snippet(self, message: Message): self.log.msg("receiving code", user_id=message.from_user.id, user_first_name=message.from_user.first_name, chat_id=message.chat.id) ext = self.guess_ext(message.text) if ext: kb_msg = self.bot.reply_to( message, f"{self.lang['query ext']}\n\n{self.lang['guessed syntax'].format(ext)}", reply_markup=minikb('syntax', self.lang['syntax picker']), parse_mode='Markdown', disable_web_page_preview=True) self.set_snippet_filetype(cb_query=None, query_message=kb_msg, ext=ext) else: self.bot.reply_to(message, self.lang['query ext'], reply_markup=self.kb['syntax'], parse_mode='Markdown', disable_web_page_preview=True) @retry def send_photo_elsewhere(self, inline_query: InlineQuery): file_id = inline_query.query.split('img ', 1)[-1] self.log.msg("creating inline query result", file_id=file_id, file_info=self.bot.get_file(file_id)) self.bot.answer_inline_query(inline_query.id, [ InlineQueryResultCachedPhoto( id=str(uuid4()), photo_file_id=file_id, title="Send Image") ], is_personal=True) @retry def restore_kb(self, cb_query: CallbackQuery): data = yload(cb_query.data) self.bot.edit_message_reply_markup( cb_query.message.chat.id, cb_query.message.message_id, reply_markup=self.kb[data['kb_name']]) self.bot.answer_callback_query(cb_query.id) @retry def set_snippet_filetype(self, cb_query: Optional[CallbackQuery] = None, query_message: Optional[Message] = None, ext: Optional[str] = None): if cb_query: query_message = cb_query.message ext = yload(cb_query.data)['ext'] elif not (query_message and ext): raise Exception( "Either cb_query or both query_message and ext are required") self.log.msg("colorizing code", user_id=query_message.reply_to_message.from_user.id, user_first_name=query_message.reply_to_message.from_user. first_name, syntax=ext, chat_id=query_message.chat.id) if cb_query: self.bot.edit_message_reply_markup(query_message.chat.id, query_message.message_id, reply_markup=minikb( 'syntax', self.lang['syntax picker'])) snippet = query_message.reply_to_message theme = self.user_themes.get(snippet.from_user.id, 'base16/gruvbox-dark-hard') html = mk_html(snippet.text, ext, theme) send_html(bot=self.bot, chat_id=snippet.chat.id, html=html, reply_msg_id=snippet.message_id) with local.tempdir() as folder: png_path = mk_png(html, folder=folder) did_send = False if len(snippet.text.splitlines()) <= 30: try: photo_msg = send_image(bot=self.bot, chat_id=snippet.chat.id, png_path=png_path, reply_msg_id=snippet.message_id) except ApiException as e: self.log.error("failed to send compressed image", exc_info=e, chat_id=snippet.chat.id) else: did_send = True kb_to_chat = InlineKeyboardMarkup() kb_to_chat.add( InlineKeyboardButton( self.lang['send to chat'], switch_inline_query= f"img {photo_msg.photo[-1].file_id}")) self.bot.edit_message_reply_markup(photo_msg.chat.id, photo_msg.message_id, reply_markup=kb_to_chat) if not did_send: send_image(bot=self.bot, chat_id=snippet.chat.id, png_path=png_path, reply_msg_id=snippet.message_id, compress=False) if cb_query: self.bot.answer_callback_query(cb_query.id) def recv_photo(self, message: Message): self.log.msg('received photo', file_id=message.photo[0].file_id, user_id=message.from_user.id, user_first_name=message.from_user.first_name, chat_id=message.chat.id)