def send_message(id, text): try: bot.send_message(id, text) except Exception as e: err_text = "{} Send Error (tid: {}): {} : {}".format( datetime.datetime.now().strftime('%x %X'), id, e.__class__, e) save_to_log('system', comment_text=err_text)
def handle_start_help(message): """Обработка /start /help команд Необходимо менять help_str - приветсвие бота. При желании можно отделить help. Незарегистрированные пользователи перенаправлются регистрироваться. Текущий вариант предусматривает автоматическое заполнение admin_id. Логика: первый отправивший /start (/help) и становиться админом : ) Алгоритм: если admin_id пустой, то id написавшего пользователя и становиться admin_id ВНИМАНИЕ! После автозаполнения admin_id требуется перезапуск бота. Чтобы считать admin_id заново. @! пофиксить """ global admin_id db_connector.save_to_log('user', message) help_str = '''Добро пожаловать. Здесь можн проходить квесты - приключения в реальности. Выбирите себе квест и наслаждайтесь.''' #Ниже заполнение пустого admin_id if not admin_id: admin_id = str(message.from_user.id) config['BASE']['Admin_id'] = admin_id with open(config_file, 'w') as configfile: config.write(configfile) bot.send_message(message.chat.id, help_str) #Редирект незарегенного пользователя на регистрацию. if not (db_connector.is_user_registered(message.from_user.id)): register_flow(bot, message)
def give_quest(): """Отправка квеста. @Написано, тестируется Предполагается с кнопкой "начать" - нуно чтобы дать пользователь возможность выйти на исходную позицию, если надо. Можно заменить пока на выдачу первого вопроса сразу. """ global status, additional_info quest_id = additional_info.get('buttons-quest_id', {}).get(message.text, None) additional_info.pop('buttons-quest_id', None) if not quest_id: #@обработка ошибки. Сообщение об ошибке и редирект на show_quest_list db_connector.save_to_log( 'system', message=message, comment_text='Не удалось найти код квеста по кнопке') bot.send_message(message.chat.id, 'Нужно выбрать квест кнопкой', reply_markup=types.ReplyKeyboardHide()) show_quest_list() else: additional_info['quest_id'] = quest_id bot.send_message(message.chat.id, 'Ваш квест начинается. Удачи!', reply_markup=types.ReplyKeyboardHide()) give_question(next_q=True)
def handle_admin_com(message): """Функции админской "панели управления". Детали смотри в admin_functions.py Для правильной работы необходим заполненный admin_id в config По умолчанию менть не надо. """ db_connector.save_to_log('user', message) admin_functions.admin_flow(bot, message)
def give_question(next_q=True): """Выслать вопрос @Написано, тестируется Типы вопросов text dig geo - выслать кнопку запроса координат. """ global status, additional_info quest_id = additional_info.get('quest_id') last_question_id = additional_info.get('question_id') if not quest_id: db_connector.save_to_log( 'system', message=message, comment_text='Не удалось найти код квеста в additional_info') bot.send_message(message.chat.id, 'Что-то пошло не так...', reply_markup=types.ReplyKeyboardHide()) show_quest_list() else: if next_q: next_quest = db_connector.get_next_question( quest_id=quest_id, question_id=last_question_id) else: next_quest = db_connector.get_question( question_id=last_question_id) if next_quest: #Структура ID, description, answer_type, correct_answer (question_id, description, photo, answer_type, correct_answer) = next_quest if answer_type == 'geo': markup = types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True) markup.add( types.KeyboardButton(text=r'Вышел на точку!', request_location=True)) else: markup = types.ReplyKeyboardHide() additional_info['question_id'] = question_id status = 'need_answer' put_operations() bot.send_message(message.chat.id, description, reply_markup=markup) if photo: bot.send_photo(message.chat.id, photo, reply_markup=markup) elif next_q: finish_quest() else: db_connector.save_to_log('system', message=message, comment_text='Вопрос где-то потерялся') bot.send_message(message.chat.id, 'Что-то пошло не так...', reply_markup=types.ReplyKeyboardHide()) show_quest_list()
def handle_register(message): """Обработка регистарции пользователя. Ссылается на модуль, в котором реализована регистрация пользователя. Перехватывает все сообщения незарегистрированного пользователя. По результатам в таблице users у пользователя должна быть RegistrationDone==1 По умолчанию менять не надо, детали смотри в registration.py """ db_connector.save_to_log('user', message) register_flow(bot, message)
def msg(message): """Обработка всего, что не попало под остальные обработчики. В идеале сюда ничего не должно попадать. Предполагается изменение. Можно использовать как шаблон. """ db_connector.save_to_log( 'user', message) #Сохранение входящего сообщения в БД. Для статистики. bot.send_message(message.chat.id, 'Рад с тобой пообщаться.', reply_markup=types.ReplyKeyboardHide())
def start_shuffle(): random.seed() session = DBSession() groups = session.query(Group).filter( Group.date_shuffle <= datetime.datetime.now().date(), Group.shuffle_done == False, Group.active == True).all() for group in groups: if len(group.members) == 0: group.shuffle_done = True session.commit() send_message( group.owner.telegramid, 'К сожалению, в вашей группе "{}" нет ни одного участника. Некому высылать подарки' .format(group.name)) elif len(group.members) == 1: group.shuffle_done = True session.commit() send_message( group.owner.telegramid, 'К сожалению в вашей группе "{}" всего один учатник. Некому высылать подарки.' .format(group.name)) send_message( group.members[0].user.telegramid, 'Вы единственный участник группы {}. Подарите себе что-нибудь приятное' .format(group.name)) elif len(group.members) > 1: member_list = group.members[:] random.shuffle(member_list) member_list[-1].send_to = member_list[0].user for i in range(len(member_list) - 1): member_list[i].send_to = member_list[i + 1].user group.shuffle_done = True session.commit() for member in group.members: to_member = session.query(Member).filter( Member.group == group, Member.user == member.send_to).first() text = '''Распределение получателей для группу {} завершено!\nВы Санта для {}. Пожелания к подарку: {} подарок высылать по следующему адресу: {} {}. На имя {}'''.format( group.name, to_member.user.name, to_member.suggestions, to_member.user.index, to_member.user.address, to_member.user.fio) send_message(member.user.telegramid, text) send_message( group.owner.telegramid, 'Распределение получателей для группу {} завершено! Участников: {}.\ Всем участникам разосланы их получатели.'.format( group.name, len(group.members))) session.close() save_to_log('system', comment_text="Shuffle done")
def routing(message): session = DBSession() try: user = session.query(User).filter_by( telegramid=message.from_user.id).first() if not user: user = User(telegramid=message.from_user.id) session.add(user) user.operation = Operation() session.commit() if user.operation is None: user.operation = Operation() session.commit() db_connector.save_to_log( from_who='user', message=message) # Сохранение входящего сообщения в БД. text = utils.text_lower_wo_command(message) if not user.active: bot.send_message(message.chat.id, 'Вы заблокированы.') elif text in ('start', 'help'): handle_start_help(message, session, user) elif not user.registrationDone or user.operation.current_operation == opRegister: register_flow(bot, message, session) elif text in admin_functions.admin_commands: #Для правильной работы необходим заполненный admin_id в config admin_functions.admin_flow(bot, message, session) elif text in standard.create_group or user.operation.current_operation == create_group.opGroup: create_group.route_flow(bot, message, session) elif text in standard.find_group or user.operation.current_operation == join_group.opGroup: join_group.route_flow(bot, message, session) else: not_found(message) session.commit() except Exception as e: session.rollback() raise e finally: session.close()
def run_bot(): """Функция для запуска прослушки телеграм сервера""" if admin_id: bot.send_message(admin_id, "Started") print("Bot started") db_connector.save_to_log('system', comment_text="Bot started") bot.polling(none_stop=True)
if __name__ == '__main__': """Запуск бота По умолчанию ничего менять не надо. """ def run_bot(): """Функция для запуска прослушки телеграм сервера""" if admin_id: bot.send_message(admin_id, "Started") print("Bot started") db_connector.save_to_log('system', comment_text="Bot started") bot.polling(none_stop=True) #Для продуктива удобнее когда бот автоматически рестартится. #Для разработки удобнее получать вылет с ошибкой. if config['BASE']['Debug'] == '1': run_bot() else: while True: try: run_bot() break except Exception as e: err_text = "{} Error: {} : {}".format( datetime.datetime.now().strftime('%x %X'), e.__class__, e) print(err_text) print("Restarted after 20 sec") db_connector.save_to_log('system', comment_text=err_text) time.sleep(20)
def handle_do_quest(message): #Тут перенаправление на корневую функцию файла do_quest.py db_connector.save_to_log('user', message) do_quest.quest_flow(bot, message)
def check_answer(): """Проверка правильности ответа на вопрос. @Добавить проверку на тип ответа. Всюду. Типы вопросов и как хранятся в БД text 'да' dig '4' geo {'lat': 55.809913, 'long': 37.462587, 'accur': 50, 'hint_meters': True} """ global status, additional_info question = db_connector.get_question( question_id=additional_info.get('question_id')) if question: is_answer_correct = False add_answer_text = '' # Структура ID, description, answer_type, correct_answer (question_id, description, photo, answer_type, correct_answer) = question if answer_type == 'geo': if message.content_type == 'location': correct_answer = json.loads(correct_answer) dist = utils.Distance(correct_answer['lat'], correct_answer['long'], message.location.latitude, message.location.longitude) if dist > correct_answer['accur']: is_answer_correct = False if correct_answer.get('hint_meters', False): add_answer_text = '\nРасстояние до точки ' + str( dist) + ' метров.' else: is_answer_correct = True else: is_answer_correct = False add_answer_text = '\nОтвет нужно отправить кнопкой!.' else: if message.content_type == 'text': if correct_answer.lower() == message.text.lower(): is_answer_correct = True else: is_answer_correct = False else: is_answer_correct = False add_answer_text = '\nОтвет нужно отправить текстом-сообщением.' if is_answer_correct: bot.send_message(message.chat.id, 'Верно!', reply_markup=types.ReplyKeyboardHide()) give_question(next_q=True) else: bot.send_message(message.chat.id, 'Нет! Не верно!' + add_answer_text, reply_markup=types.ReplyKeyboardHide()) give_question(next_q=False) else: db_connector.save_to_log('system', message=message, comment_text='Вопрос где-то потерялся') bot.send_message(message.chat.id, 'Что-то пошло не так...', reply_markup=types.ReplyKeyboardHide()) show_quest_list()