import configparser import os import sys from pathlib import Path from time import sleep from db import BotDB import telebot import random from datetime import datetime import time from telebot import types from telebot.apihelper import ApiTelegramException #Настройки config_path = os.path.join(sys.path[0], 'settings.ini') config = configparser.ConfigParser() config.read(config_path) #TELEGRAM BOT_TOKEN = config.get('Telegram', 'BOT_TOKEN') GROUP_FOR_POST = config.get('Telegram', 'group_for_posts') GROUP_FOR_MESSAGE = config.get('Telegram', 'group_for_message') MAIN_PUBLIC = config.get('Telegram', 'main_public') GROUP_FOR_LOGS = config.get('Telegram', 'group_for_logs') IMPORTANT_LOGS = config.get('Telegram', 'important_logs') PREVIEW_LINK = config.getboolean('Telegram', 'PREVIEW_LINK') #SETTINGS LOGS = config.getboolean('Settings', 'logs') TEST = config.getboolean('Settings', 'test') #Инициализируем бота и базку bot = telebot.TeleBot(BOT_TOKEN, parse_mode=None) BotDB = BotDB('tg-bot-database') def telegram_bot(): @bot.message_handler(commands=['start']) def send_welcome(message): #TODO: Здесь переписать через randint #TODO: Тексты приветствий вынести в отдельный файл try: name_stick_hello = list(Path('Stick').rglob('Hello_*')) number_stick_hello = random.randint(1, len(name_stick_hello)) random_stick_hello = open(name_stick_hello[number_stick_hello], 'rb') #logging if LOGS: bot.forward_message(chat_id=GROUP_FOR_LOGS, from_chat_id=message.chat.id, message_id=message.message_id) bot.send_sticker(message.chat.id, random_stick_hello) sleep(0.3) except: if LOGS: bot.send_message(IMPORTANT_LOGS, BotDB.get_error_message_from_db(7)) try: user_id = message.from_user.id first_name = message.from_user.first_name full_name = message.from_user.full_name is_bot = message.from_user.is_bot username = message.from_user.username language_code = message.from_user.language_code time_UTC = int(time.time()) date_added = datetime.fromtimestamp(time_UTC) date_changed = datetime.fromtimestamp(time_UTC) markup = types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True) item1 = types.KeyboardButton("📢Предложить свой пост") item2 = types.KeyboardButton("📩Связаться с админами") item3 = types.KeyboardButton("❌Удалить пост") item4 = types.KeyboardButton("🎧Войти в режим стендапа") if BotDB.user_exists(user_id): is_need_sticker = BotDB.get_info_about_stickers(user_id=message.from_user.id) if is_need_sticker == 0: item5 = types.KeyboardButton("🤪Хочу ваши стикеры") BotDB.update_info_about_stickers(user_id=message.from_user.id) markup.add(item1, item2, item3, item4, item5) else: markup.add(item1, item2, item3, item4) else: BotDB.add_new_user_in_db(user_id, first_name, full_name, username, is_bot, language_code, date_added, date_changed) is_need_sticker = BotDB.get_info_about_stickers(user_id=message.from_user.id) if is_need_sticker == 0: item5 = types.KeyboardButton("🤪Хочу ваши стикеры") BotDB.update_info_about_stickers(user_id=message.from_user.id) markup.add(item1, item2, item3, item4, item5) else: markup.add(item1, item2, item3, item4) hello_message = BotDB.get_message_from_db('start_message', first_name) bot.send_message(message.chat.id, hello_message, parse_mode='html', reply_markup=markup, disable_web_page_preview=not PREVIEW_LINK) except: if LOGS: bot.send_message(IMPORTANT_LOGS, BotDB.get_error_message_from_db(8)) bot.register_next_step_handler(message, go_send_messages) @bot.message_handler(commands=['end_command']) def after_post(message): markup = types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True) item1 = types.KeyboardButton("📢Предложить свой пост") item2 = types.KeyboardButton("📩Связаться с админами") item3 = types.KeyboardButton("❌Удалить пост") item4 = types.KeyboardButton("🎧Войти в режим стендапа") item5 = types.KeyboardButton("👋🏼Сказать пока!") markup.add(item1, item2, item3, item4, item5) bot.send_message(message.chat.id, "Выбери нужную кнопку внизу экрана".format( message.from_user, bot.get_me()), parse_mode='html', reply_markup=markup, disable_web_page_preview=not PREVIEW_LINK) bot.register_next_step_handler(message, go_send_messages) def go_send_messages(message): global msg if message.text == '📢Предложить свой пост': try: markup = types.ReplyKeyboardRemove() first_name = message.from_user.first_name suggest_news = BotDB.get_message_from_db('suggest_news', first_name) bot.send_message(message.chat.id, suggest_news, parse_mode='html') sleep(0.3) first_name = message.from_user.first_name suggest_news_2 = BotDB.get_message_from_db('suggest_news_2', first_name) msg = bot.send_message(message.chat.id, suggest_news_2,parse_mode='html', reply_markup=markup) except: if LOGS: bot.send_message(IMPORTANT_LOGS, BotDB.get_error_message_from_db(10)) #logging if LOGS: bot.forward_message(chat_id=GROUP_FOR_LOGS, from_chat_id=message.chat.id, message_id=message.message_id) bot.register_next_step_handler(msg, resend_message_in_group_for_post) elif message.text == "📩Связаться с админами": first_name = message.from_user.first_name connect_with_admin = BotDB.get_message_from_db('connect_with_admin', first_name) msg = bot.send_message(message.chat.id, connect_with_admin, parse_mode="html") #logging if LOGS: bot.forward_message(chat_id=GROUP_FOR_LOGS, from_chat_id=message.chat.id, message_id=message.message_id) bot.register_next_step_handler(msg, resend_message_in_group_for_message) elif message.text == "🎧Войти в режим стендапа": markup = types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True) item1 = types.KeyboardButton("🎤Высказаться") item2 = types.KeyboardButton("🎧Послушать") item3 = types.KeyboardButton("🔙Вернуться в меню") markup.add(item1, item2, item3) first_name = message.from_user.first_name message_for_standup = BotDB.get_message_from_db('message_for_standup', first_name) #logging if LOGS: bot.forward_message(chat_id=GROUP_FOR_LOGS, from_chat_id=message.chat.id, message_id=message.message_id) bot.send_message(message.chat.id, message_for_standup, parse_mode='html', reply_markup=markup, disable_web_page_preview=not PREVIEW_LINK) #функция с отображением сообщения "Последнее сообщение было записано" date_from_db = BotDB.last_date_audio() parse_date = datetime.strptime(date_from_db, "%Y-%m-%d %H:%M:%S") last_voice_time_timestamp = time.mktime(parse_date.timetuple()) time_now_timestamp = time.time() date_difference = time_now_timestamp - last_voice_time_timestamp # считаем минуты, часы, дни much_minutes_ago = round(date_difference / 60, 0) much_hour_ago = round(date_difference / 3600, 0) much_days_ago = int(round(much_hour_ago / 24, 0)) message_with_date = '' if much_minutes_ago <= 60: word_minute = plural_time(1, much_minutes_ago) message_with_date = f'Последнее сообщение было записано {word_minute} назад' elif much_minutes_ago > 60 and much_hour_ago <= 24: word_hour = plural_time(2, much_hour_ago) message_with_date = f'Последнее сообщение было записано {word_hour} назад' elif much_hour_ago > 24: word_day = plural_time(3, much_days_ago) message_with_date = f'Последнее сообщение было записано {word_day} назад' msg = bot.send_message(chat_id=message.chat.id, text=message_with_date, parse_mode="html") bot.register_next_step_handler(msg, standup) elif message.text == "❌Удалить пост": #TODO: требует автоматизации. На входе говорим пришли мне пост, на выходе получаем идентификатор поста, удаляем из ТГ. Насчет удаления из ВК надо подумать first_name = message.from_user.first_name del_message = BotDB.get_message_from_db('del_message', first_name) msg = bot.send_message(message.chat.id, del_message, parse_mode="html") #logging if LOGS: bot.forward_message(chat_id=GROUP_FOR_LOGS, from_chat_id=message.chat.id, message_id=message.message_id) bot.register_next_step_handler(msg, resend_message_in_group_for_message) elif message.text == "👋🏼Сказать пока!": try: name_stick_bye = list(Path('Stick').rglob('Universal_*')) number_stick_bye = random.randint(1, len(name_stick_bye)) random_stick_bye = open(name_stick_bye[number_stick_bye], 'rb') bot.send_sticker(message.chat.id, random_stick_bye) except ApiTelegramException: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=BotDB.get_error_message_from_db(11)) markup = types.ReplyKeyboardRemove() try: first_name = message.from_user.first_name bye_message = BotDB.get_message_from_db('bye_message', first_name) bot.send_message(message.chat.id, bye_message, parse_mode='html', reply_markup=markup, disable_web_page_preview=not PREVIEW_LINK) except: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=BotDB.get_error_message_from_db(6)) if LOGS: #logging bot.forward_message(chat_id=GROUP_FOR_LOGS, from_chat_id=message.chat.id, message_id=message.message_id) elif message.text == "🤪Хочу ваши стикеры": markup = types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True) item1 = types.KeyboardButton("📢Предложить свой пост") item2 = types.KeyboardButton("📩Связаться с админами") item3 = types.KeyboardButton("❌Удалить пост") item4 = types.KeyboardButton("🎧Войти в режим стендапа") item5 = types.KeyboardButton("👋🏼Сказать пока!") markup.add(item1, item2, item3, item4, item5) try: if LOGS: bot.forward_message(chat_id=GROUP_FOR_LOGS, from_chat_id=message.chat.id, message_id=message.message_id) bot.send_message(message.chat.id, text='Хорошо, лови, добавить можно отсюда: https://t.me/addstickers/love_biysk', reply_markup=markup) bot.register_next_step_handler(message, callback=go_send_messages) except ApiTelegramException: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=BotDB.get_error_message_from_db(12)) else: try: first_name = message.from_user.first_name user_error = BotDB.get_message_from_db('user_error', first_name) bot.send_message(message.chat.id, user_error, parse_mode='html', disable_web_page_preview=not PREVIEW_LINK) except: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=BotDB.get_error_message_from_db(9)) #logging if LOGS: bot.forward_message(chat_id=GROUP_FOR_LOGS, from_chat_id=message.chat.id, message_id=message.message_id) bot.register_next_step_handler(message, callback=go_send_messages) def standup(message): # Клавиатуру добавляем markup = types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True) item1 = types.KeyboardButton("🎤Высказаться") item2 = types.KeyboardButton("🎧Послушать") item3 = types.KeyboardButton("🔙Вернуться в меню") markup.add(item1, item2, item3) try: if message.text == '🎤Высказаться' or message.text == '🎤Высказаться еще': markup = types.ReplyKeyboardRemove() if TEST: bot.forward_message(chat_id=GROUP_FOR_LOGS, from_chat_id=message.chat.id, message_id=message.id) msg = bot.send_message(chat_id=message.chat.id, text='Хорошо, теперь пришли мне свое голосовое сообщение', reply_markup=markup) bot.register_next_step_handler(msg, save_voice_message) elif message.text == '🎧Послушать': check_audio = BotDB.check_listen_audio(user_id=message.from_user.id) list_audio = list(check_audio) if TEST: bot.forward_message(chat_id=GROUP_FOR_LOGS, from_chat_id=message.chat.id, message_id=message.id) if list_audio == []: msg = bot.send_message(message.chat.id, 'Прости, ты прослушал все аудио😔. Возвращайся позже, возможно наша база пополнится', reply_markup=markup) bot.register_next_step_handler(msg, standup) else: number_element = random.randint(0, len(list_audio) - 1) audio_for_user = check_audio[number_element] path = Path(f'voice_users/{audio_for_user}.ogg') voice = open(path, 'rb') #Маркируем сообщение как прослушанное BotDB.mark_listened_audio(audio_for_user, user_id=message.from_user.id) msg = bot.send_voice(message.chat.id, voice=voice, reply_markup=markup) bot.register_next_step_handler(msg, standup) elif message.text == '🔙Вернуться в меню': if TEST: bot.forward_message(chat_id=GROUP_FOR_LOGS, from_chat_id=message.chat.id, message_id=message.id) after_post(message=message) else: msg = bot.send_message(chat_id=message.chat.id, text='Я тебя не понял, воспользуйся меню', reply_markup=markup) bot.register_next_step_handler(msg, standup) except: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=BotDB.get_error_message_from_db(4)) def plural_time(type, n): word = [] if type == 1: word = ['минуту', 'минуты', 'минут'] elif type == 2: word = ['час', 'часа', 'часов'] elif type == 3: word = ['день', 'дня', 'дней'] else: pass if n % 10 == 1 and n % 100 != 11: p = 0 elif 2 <= n % 10 <= 4 and (n % 100 < 10 or n % 100 >= 20): p = 1 else: p = 2 return str(n) + ' ' + word[p] def save_voice_message(message): if message.content_type == 'voice': if TEST: bot.forward_message(chat_id=GROUP_FOR_LOGS, from_chat_id=message.chat.id, message_id=message.id) file_name = '' file_id = 1 #Проверяем что запись о файле есть в базе данных is_having_audio_from_user = BotDB.get_last_user_audio_record(user_id=message.from_user.id) if is_having_audio_from_user is False: #Если нет, то генерируем имя файла file_name = f'message_from_{message.from_user.id}_number_{file_id}' else: #Иначе берем последнюю запись из БД, добавляем к ней 1, и создаем новую запись file_name = BotDB.get_path_for_audio_record(user_id=message.from_user.id) file_id = BotDB.get_id_for_audio_record(message.from_user.id) + 1 path = Path(f'voice_users/{file_name}.ogg') if path.exists(): file_name = f'message_from_{message.from_user.id}_number_{file_id}' else: pass #Собираем инфо о сообщении author_id = message.from_user.id time_UTC = int(time.time()) date_added = datetime.fromtimestamp(time_UTC) #Сохраняем в базку BotDB.add_audio_record(file_name, author_id, date_added, 0, file_id) #Сохраняем файл на сервер file_info = bot.get_file(message.voice.file_id) downloaded_file = bot.download_file(file_info.file_path) with open(f'voice_users/{file_name}.ogg', 'wb') as new_file: new_file.write(downloaded_file) #инициализируем кнопки markup = types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True) item1 = types.KeyboardButton("🔙Вернуться в меню") markup.add(item1) bot.send_message(chat_id=message.chat.id, text='Окей, сохранил!👌', reply_markup=markup) #menu_standup(message=message) bot.register_next_step_handler(message, standup) else: #TODO: Если пришлют фото, он не работает if TEST: bot.forward_message(chat_id=GROUP_FOR_LOGS, from_chat_id=message.chat.id, message_id=message.id) markup = types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True) item1 = types.KeyboardButton("🔙Вернуться в меню") markup.add(item1) msg = bot.send_message(chat_id=message.chat.id, text='Я тебя не понимаю🤷‍♀️ запиши голосовое', reply_markup=markup) bot.register_next_step_handler(msg, standup) def resend_message_in_group_for_post(message): markup = types.InlineKeyboardMarkup(row_width=1) item1 = types.InlineKeyboardButton("Опубликовать", callback_data='post_post_post') item2 = types.InlineKeyboardButton("Отклонить", callback_data='decline') markup.add(item1, item2) try: if message.content_type == 'text': post_text = message.text.lower() if post_text.find('неанон') != -1 or post_text.find('не анон') != -1: bot.send_message( #TODO: GROUP_FOR_POST chat_id=GROUP_FOR_POST, text=f'Пост из ТГ:\n{post_text}\n\nАвтор поста: {message.from_user.first_name} @{message.from_user.username}', reply_markup=markup ) elif post_text.find('анон') != -1: bot.send_message( # TODO: GROUP_FOR_POST chat_id=GROUP_FOR_POST, text=f'Пост из ТГ:\n{message.text}\n\nПост опубликован анонимно', reply_markup=markup ) else: bot.send_message( # TODO: GROUP_FOR_POST chat_id=GROUP_FOR_POST, text=f'Пост из ТГ:\n{post_text}\n\nАвтор поста: {message.from_user.first_name} @{message.from_user.username}', reply_markup=markup ) elif message.content_type == 'photo' and message.media_group_id == None: post_text_for_photo = message.caption.lower() bot.send_photo( # TODO: GROUP_FOR_POST chat_id=GROUP_FOR_POST, caption=f'Пост из ТГ:\n{post_text_for_photo}\n\nАвтор поста: {message.from_user.first_name} @{message.from_user.username}', photo=message.photo[-1].file_id, reply_markup=markup ) #TODO: Не понятна реализация с альбомами от слова совсем #elif message.content_type == 'photo' and message.media_group_id != None: # bot.forward_message(chat_id=IMPORTANT_LOGS, from_chat_id=message.chat.id, message_id=message.message_id ) else: pass except: if LOGS: username = message.from_user.first_name error_message = str(BotDB.get_error_message_from_db(5)).replace('username', username) bot.send_message(chat_id=IMPORTANT_LOGS, text=error_message) username = message.from_user.first_name success_send_message = BotDB.get_message_from_db('success_send_message', username) bot.send_message(message.chat.id, success_send_message, parse_mode='html', disable_web_page_preview=not PREVIEW_LINK) after_post(message=message) def resend_message_in_group_for_message(message): bot.forward_message(chat_id=GROUP_FOR_MESSAGE, from_chat_id=message.chat.id, message_id=message.message_id ) username = message.from_user.first_name question = BotDB.get_message_from_db('question', username) bot.send_message(message.chat.id, question, parse_mode='html', disable_web_page_preview=not PREVIEW_LINK) try: pass except: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=BotDB.get_error_message_from_db(4)) after_post(message=message) #Админка @bot.callback_query_handler(func=lambda call: True) def post_for_group(call): if call.data == 'post_post_post' and call.message.content_type == 'text': try: bot.send_message(chat_id=MAIN_PUBLIC, text=call.message.text) bot.delete_message(chat_id=GROUP_FOR_POST, message_id=call.message.message_id) except: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=BotDB.get_error_message_from_db(3)) elif call.data == 'post_post_post' and call.message.content_type == 'photo': try: bot.send_photo( chat_id=MAIN_PUBLIC, caption=call.message.caption, photo=call.message.photo[-1].file_id, ) bot.delete_message(chat_id=GROUP_FOR_POST, message_id=call.message.message_id) except: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=BotDB.get_error_message_from_db(2)) elif call.data == 'decline': try: bot.delete_message(chat_id=GROUP_FOR_POST, message_id=call.message.message_id) except: if LOGS: bot.send_message(IMPORTANT_LOGS, BotDB.get_error_message_from_db(1)) if __name__ == '__main__': telegram_bot() try: bot.polling(none_stop=True) bot.enable_save_next_step_handlers(delay=2) bot.load_next_step_handlers() except ConnectionError as e: if LOGS: bot.send_message(IMPORTANT_LOGS, "Ошибка соединения, потерял связь") except Exception as r: if LOGS: bot.send_message(IMPORTANT_LOGS, "Произошло что-то непредвиденное, хелп") finally: if LOGS: bot.send_message(IMPORTANT_LOGS, 'Я упал, помогите')