def handle_reply_to_vk_message(message): global waiting_for_reply_text, waiting_for_send_text, waiting_for_key if waiting_for_reply_text or waiting_for_send_text: database = sqliteutil.SQLUtil('vk_data.db', 'data') vk_data = database.select_single(message.chat.id) access_token_encrypted = vk_data[2] cipher = cryptoutil.get_cipher(exchange_key) access_token = cryptoutil.decode_aes(cipher, access_token_encrypted) vk_api = vkapi.VkApiClient(access_token) if waiting_for_reply_text: vk_api.reply_to_message(reply_send_peer_id, reply_send_peer_type, reply_send_message_id, message.text.encode('utf-8')) waiting_for_reply_text = False bot.send_message(message.chat.id, 'Ответ на сообщение отправлен!') elif waiting_for_send_text: vk_api.send_message(reply_send_peer_id, reply_send_peer_type, message.text.encode('utf-8')) waiting_for_send_text = False bot.send_message(message.chat.id, 'Сообщение отправлено!') elif waiting_for_key: database = sqliteutil.SQLUtil('vk_data.db', 'data') vk_data = database.select_single(message.chat.id) access_token_encrypted = vk_data[2] if not validate_key(message.text, access_token_encrypted, message.chat.id): return global exchange_key exchange_key = message.text waiting_for_key = False process_current_call()
def auth_user_in_vk(message): parts = message.text.split(' ') if len(parts) is 2: regex = r'https://oauth\.vk\.com/blank\.html\#access_token=([a-z0-9]{85})&expires_in=0&user_id=(\d{0,11})' result = re.search(regex, parts[1]) if not result: bot.send_message(message.chat.id, 'Неправильная ссылка, удостоверься, что все сделано правильно.') return token = result.groups()[0].encode('utf-8') user_id = result.groups()[1].encode('utf-8') # noinspection PyShadowingNames secret = cryptoutil.generate_secret() global exchange_key exchange_key = secret cipher = cryptoutil.get_cipher(secret) bot.send_message(message.chat.id, secret) bot.send_message(message.chat.id, 'Это Твой ключ, которым зашифрованы данные, отправленные только что. Обязательно сохрани его, он необходим для выполнения ' 'действий с ботом. Для подробностей о шифровании отправь мне команду /privacy') database = sqliteutil.SQLUtil('vk_data.db', 'data') database.edit_user(message.chat.id, user_id, cryptoutil.encode_aes(cipher, token)) bot.send_message(message.chat.id, 'Спасибо! Теперь Ты можешь пользоваться всеми функциями бота! Нажми /help для списка всех команд.') else: bot.send_message(message.chat.id, '*Внимание!* Так как Вконтакте не представляет удобной работы с API для приложений вроде этого, Тебе придется скопировать ' 'ссылку в адресной строке браузера после авторизации и отправить ее мне вот так:\n\t /auth ссылка\n Без этого бот работать ' 'не будет. ВКонтакте предупредит тебя, что это делать нежелательно, но другого способа нет.\n\nПожалуйста, перейди по этой ' 'ссылке и нажми "Разрешить":\n https://oauth.vk.com/authorize?client\_id={0}&display=page&redirect\_uri=https://oauth' '.vk.com&scope=offline,messages&response\_type=token&v=5.63'.format(config.client_id), parse_mode='Markdown')
def send_dialogs(message): database = sqliteutil.SQLUtil('vk_data.db', 'data') vk_data = database.select_single(message.chat.id) access_token_encrypted = vk_data[2].encode('utf-8') if len(access_token_encrypted) > 0: parts = message.text.split(' ') if len(parts) is not 3: bot.send_message(message.chat.id, 'Неправильный формат запроса. Смотри /help для инструкций.') return count = parts[1] key = parts[2] if not validate_key(key, access_token_encrypted, message.chat.id): return global exchange_key exchange_key = key if not validate_count(count, message): return cipher = cryptoutil.get_cipher(key) access_token = cryptoutil.decode_aes(cipher, access_token_encrypted) vk_api = vkapi.VkApiClient(access_token) bot.send_message(message.chat.id, 'Получаю диалоги...') response = vk_api.get_dialogs(count, str(vk_data[1])) for dialog in response: keyboard = types.InlineKeyboardMarkup() view_messages_callback = 'peer_{}'.format(str(dialog.peer_id)) view_messages_button = types.InlineKeyboardButton(text='Просмотреть сообщения', callback_data=view_messages_callback) send_message_callback = 'send_{}_{}'.format(dialog.get_peer_type(), str(dialog.get_peer_id())) send_button = types.InlineKeyboardButton(text='Написать сообщение', callback_data=send_message_callback) has_name = len(dialog.get_sender_name()) is 0 # or not dialog.get_sender_url().endswith(str(vk_data[2])) if has_name: view_name_callback = 'link_{}_{}_{}_{}'.format(str(dialog.get_sender_url()), str(dialog.get_peer_id()), dialog.get_peer_type(), 'd') view_name_button = types.InlineKeyboardButton(text='Показать имя', callback_data=view_name_callback) keyboard.add(view_messages_button, view_name_button) keyboard.add(send_button) else: keyboard.add(view_messages_button, send_button) bot.send_message(message.chat.id, str(dialog), has_name, reply_markup=keyboard, parse_mode='Markdown') else: bot.send_message(message.chat.id, "Ты еще не авторизирован(а). Нажми /auth, чтобы это сделать.")
def validate_key(key, encrypted_token, chat_id): if len(key) is not 16: bot.send_message(chat_id, 'Неверный ключ! Если Ты его забыл(а), то пройди процедуру аутентификации повторно -> /auth') return False cipher = cryptoutil.get_cipher(key) try: cryptoutil.decode_aes(cipher, encrypted_token).encode('utf-8') except UnicodeDecodeError: bot.send_message(chat_id, 'Неверный ключ! Если Ты его забыл(а), то пройди процедуру аутентификации повторно -> /auth') return False return True
def send_last_messages(message): database = sqliteutil.SQLUtil('vk_data.db', 'data') vk_data = database.select_single(message.chat.id) access_token_encrypted = vk_data[2].encode('utf-8') if len(access_token_encrypted) > 0: parts = message.text.split(' ') if len(parts) is not 5: bot.send_message(message.chat.id, 'Неправильный формат запроса. Смотри /help для инструкций.') return key = parts[4] if not validate_key(key, access_token_encrypted, message.chat.id): return global exchange_key exchange_key = key count = parts[1] if not validate_count(count, message): return cipher = cryptoutil.get_cipher(key) access_token = cryptoutil.decode_aes(cipher, access_token_encrypted) vk_api = vkapi.VkApiClient(access_token) peer_id = parts[3] try: int(parts[3]) except ValueError: bot.send_message(message.chat.id, 'ID диалога должен быть числом!') return send_messages(message.chat.id, vk_api, vk_data[1], peer_id, count) else: bot.send_message(message.chat.id, "Ты еще не авторизирован(а). Нажми /auth, чтобы это сделать.")
def process_current_call(): call = current_call parts = call.data.split('_') call_action = parts[0] if call_action == 'peer': peer_id = parts[1] database = sqliteutil.SQLUtil('vk_data.db', 'data') vk_data = database.select_single(call.message.chat.id) access_token_encrypted = vk_data[2].encode('utf-8') global exchange_key cipher = cryptoutil.get_cipher(exchange_key) access_token = cryptoutil.decode_aes(cipher, access_token_encrypted) vk_api = vkapi.VkApiClient(access_token) send_messages(call.message.chat.id, vk_api, vk_data[1], peer_id, 15) elif call_action == 'link': link = parts[1].encode('utf-8') vk_api = vkapi.VkApiClient('') name = vk_api.link_to_name(link) prev_text = call.message.text.encode('utf-8') if len(parts) in [5, 6]: keyboard = types.InlineKeyboardMarkup() if parts[4] == 'd': view_messages_callback = 'peer_' + parts[2] view_messages_button = types.InlineKeyboardButton(text='Просмотреть сообщения', callback_data=view_messages_callback) send_message_callback = 'send_{}_{}'.format(parts[3], parts[2]) send_button = types.InlineKeyboardButton(text='Написать сообщение', callback_data=send_message_callback) keyboard.add(view_messages_button, send_button) elif parts[5] == 'm': callback_data = 'reply_{}_{}_{}'.format(parts[4], parts[3], parts[2]) reply_button = types.InlineKeyboardButton(text='Ответить', callback_data=callback_data) keyboard.add(reply_button) bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text=prev_text.replace(link, name), reply_markup=keyboard) else: bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text=prev_text.replace(link, name)) elif call_action == 'reply': global reply_send_message_id, reply_send_peer_type, reply_send_peer_id, waiting_for_reply_text reply_send_message_id = parts[1] reply_send_peer_type = parts[2] reply_send_peer_id = parts[3] bot.send_message(chat_id=call.message.chat.id, text='Теперь отправь мне текст ответа. Для отмены отправь /cancel_reply') waiting_for_reply_text = True elif call_action == 'send': global reply_send_peer_type, reply_send_peer_id, waiting_for_send_text reply_send_peer_type = parts[1] reply_send_peer_id = parts[2] bot.send_message(chat_id=call.message.chat.id, text='Теперь отправь мне текст сообщения. Для отмены отправь /cancel_send') waiting_for_send_text = True