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 import messages import traceback # Настройки 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 Exception as e: if LOGS: bot.send_message(IMPORTANT_LOGS, f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") 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("📩Связаться с админами") # TODO: Выпилил, удалить # item3 = 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, item5) else: markup.add(item1, item2) 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, item5) else: markup.add(item1, item2) hello_message = messages.get_message(__get_first_name(message), 'HELLO_MESSAGE') bot.send_message(message.chat.id, hello_message, parse_mode='html', reply_markup=markup, disable_web_page_preview=not PREVIEW_LINK) except Exception as e: if LOGS: bot.send_message(IMPORTANT_LOGS, f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") 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("📩Связаться с админами") # TODO: Скрыл, удалить обработчик # item3 = types.KeyboardButton("❌Удалить пост") item5 = types.KeyboardButton("👋🏼Сказать пока!") markup.add(item1, item2, 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() suggest_news = messages.get_message(__get_first_name(message), 'SUGGEST_NEWS') bot.send_message(message.chat.id, suggest_news, parse_mode='html') sleep(0.3) suggest_news_2 = messages.get_message(__get_first_name(message), 'SUGGEST_NEWS_2') msg = bot.send_message(message.chat.id, suggest_news_2, parse_mode='html', reply_markup=markup) except Exception as e: if LOGS: bot.send_message(IMPORTANT_LOGS, f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") # 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 == "📩Связаться с админами": connect_with_admin = messages.get_message(__get_first_name(message), 'CONNECT_WITH_ADMIN') 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 == "❌Удалить пост": # TODO: требует автоматизации. На входе говорим пришли мне пост, на выходе получаем идентификатор поста, удаляем из ТГ. Насчет удаления из ВК надо подумать del_message = messages.get_message(__get_first_name(message), 'DEL_MESSAGE') 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 as e: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") markup = types.ReplyKeyboardRemove() try: bye_message = messages.get_message(__get_first_name(message), 'BYE_MESSAGE') bot.send_message(message.chat.id, bye_message, parse_mode='html', reply_markup=markup, disable_web_page_preview=not PREVIEW_LINK) except Exception as e: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") 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("📩Связаться с админами") # TODO: Скрыл кнопку, убрать обработчик позднее # item3 = types.KeyboardButton("❌Удалить пост") item5 = types.KeyboardButton("👋🏼Сказать пока!") markup.add(item1, item2, 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 as e: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") else: try: user_error = messages.get_message(__get_first_name(message), 'USER_ERROR') bot.send_message(message.chat.id, user_error, parse_mode='html', disable_web_page_preview=not PREVIEW_LINK) except Exception as e: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") # 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 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 is None: post_text_for_photo = message.caption.lower() if post_text_for_photo.find('неанон') != -1 or post_text_for_photo.find('не анон') != -1: 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 ) elif post_text_for_photo.find('анон') != -1 or post_text_for_photo.find('анон') != -1: bot.send_photo( # TODO: GROUP_FOR_POST chat_id=GROUP_FOR_POST, caption=f'Пост из ТГ:\n{post_text_for_photo}\n\nПост опубликован анонимно', photo=message.photo[-1].file_id, reply_markup=markup ) else: 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 Exception as e: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") success_send_message = messages.get_message(__get_first_name(message), 'SUCCESS_SEND_MESSAGE') 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 ) question = messages.get_message(__get_first_name(message), 'QUESTION') bot.send_message(message.chat.id, question, parse_mode='html', disable_web_page_preview=not PREVIEW_LINK) try: pass except Exception as e: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") 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 Exception as e: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") 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 Exception as e: if LOGS: bot.send_message(chat_id=IMPORTANT_LOGS, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") elif call.data == 'decline': try: bot.delete_message(chat_id=GROUP_FOR_POST, message_id=call.message.message_id) except Exception as e: if LOGS: bot.send_message(IMPORTANT_LOGS, f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") def __get_first_name(message): return message.from_user.first_name if __name__ == '__main__': telegram_bot() while True: try: bot.polling(none_stop=True) bot.enable_save_next_step_handlers(delay=2) bot.load_next_step_handlers() except (ConnectionError, Exception): print(f"Произошла ошибка: {str(Exception)}\n\nTraceback:\n{traceback.format_exc()}")