From 125baec43915a473cf178bd33216984e6d87a289 Mon Sep 17 00:00:00 2001 From: Kylmakalle Date: Sun, 25 Jun 2017 02:00:56 +0300 Subject: [PATCH] Support for message forwarding and handling forwared messages --- bot.py | 99 ++++++++++++++++++++++++++++++++++---------------- vk_messages.py | 86 +++++++++++++++++++++++++++---------------- 2 files changed, 121 insertions(+), 64 deletions(-) diff --git a/bot.py b/bot.py index 48cd866..d2beec1 100644 --- a/bot.py +++ b/bot.py @@ -96,6 +96,7 @@ def stop_command(message): @bot.message_handler(commands=['start']) def start_command(message): + # TODO: Dialogs Menu if check_thread(message.from_user.id): bot.send_message(message.chat.id, 'Привет, этот бот поможет тебе общаться ВКонтакте, войди по кнопке ниже' @@ -105,15 +106,35 @@ def start_command(message): bot.send_message(message.chat.id, 'Вход уже выполнен!\n/stop для выхода.').wait() +def form_request(message, method, info): + if int(info[2]): + if message.text.startswith('!'): + if len(message.text) - 1: + message.text = message.text[1:] + if info[1] != 'None': + method(message, info[1], group=True, forward_messages=info[1]) + else: + method(message, info[1], group=True) + else: + method(message, info[1], group=True) + else: + if message.text.startswith('!'): + if len(message.text) - 1: + message.text = message.text[1:] + if info[1] != 'None': + method(message, info[0], group=False, forward_messages=info[1]) + else: + method(message, info[1], group=True) + else: + method(message, info[0], group=False) + + def vk_sender(message, method): if message.reply_to_message: if vk_tokens.get(str(message.from_user.id)): info = info_extractor(message.reply_to_message.entities) if info is not None: - if int(info[1]): - method(message, info[1], group=True) - else: - method(message, info[0], group=False) + form_request(message, method, info) else: bot.send_message(message.chat.id, 'Вход не выполнен! /start для входа').wait() @@ -125,15 +146,15 @@ def audio_title_creator(message, performer=None, title=None): return '{} - {}'.format(performer, title) -def send_text(message, userid, group): +def send_text(message, userid, group, forward_messages=None): session = VkMessage(vk_tokens.get(str(message.from_user.id))).session if group: - vk.API(session).messages.send(chat_id=userid, message=message.text) + vk.API(session).messages.send(chat_id=userid, message=message.text, forward_messages=forward_messages) else: - vk.API(session).messages.send(user_id=userid, message=message.text) + vk.API(session).messages.send(user_id=userid, message=message.text, forward_messages=forward_messages) -def send_doc(message, userid, group): +def send_doc(message, userid, group, forward_messages=None): filetype = message.content_type session = VkMessage(vk_tokens.get(str(message.from_user.id))).session file = wget.download( @@ -177,23 +198,27 @@ def send_doc(message, userid, group): vk.API(session).messages.send(chat_id=userid, message=message.caption, attachment='doc{}_{}'.format(attachment[0]['owner_id'], - attachment[0]['did'])) + attachment[0]['did']), + forward_messages=forward_messages) else: vk.API(session).messages.send(chat_id=userid, attachment='doc{}_{}'.format(attachment[0]['owner_id'], - attachment[0]['did'])) + attachment[0]['did']), + forward_messages=forward_messages) else: if message.caption: vk.API(session).messages.send(user_id=userid, message=message.caption, attachment='doc{}_{}'.format(attachment[0]['owner_id'], - attachment[0]['did'])) + attachment[0]['did']), + forward_messages=forward_messages) else: vk.API(session).messages.send(user_id=userid, attachment='doc{}_{}'.format(attachment[0]['owner_id'], - attachment[0]['did'])) + attachment[0]['did']), + forward_messages=forward_messages) -def send_photo(message, userid, group): +def send_photo(message, userid, group, forward_messages=None): filetype = message.content_type session = VkMessage(vk_tokens.get(str(message.from_user.id))).session file = wget.download( @@ -206,19 +231,23 @@ def send_photo(message, userid, group): hash=fileonserver['hash']) if group: if message.caption: - vk.API(session).messages.send(chat_id=userid, message=message.caption, attachment=attachment[0]['id']) + vk.API(session).messages.send(chat_id=userid, message=message.caption, attachment=attachment[0]['id'], + forward_messages=forward_messages) else: - vk.API(session).messages.send(chat_id=userid, attachment=attachment[0]['id']) + vk.API(session).messages.send(chat_id=userid, attachment=attachment[0]['id'], + forward_messages=forward_messages) else: if message.caption: - vk.API(session).messages.send(user_id=userid, message=message.caption, attachment=attachment[0]['id']) + vk.API(session).messages.send(user_id=userid, message=message.caption, attachment=attachment[0]['id'], + forward_messages=forward_messages) else: - vk.API(session).messages.send(user_id=userid, attachment=attachment[0]['id']) + vk.API(session).messages.send(user_id=userid, attachment=attachment[0]['id'], + forward_messages=forward_messages) openedfile.close() os.remove(file) -def send_sticker(message, userid, group): +def send_sticker(message, userid, group, forward_messages=None): filetype = message.content_type session = VkMessage(vk_tokens.get(str(message.from_user.id))).session file = wget.download( @@ -232,20 +261,24 @@ def send_sticker(message, userid, group): hash=fileonserver['hash']) if group: if message.caption: - vk.API(session).messages.send(chat_id=userid, message=message.caption, attachment=attachment[0]['id']) + vk.API(session).messages.send(chat_id=userid, message=message.caption, attachment=attachment[0]['id'], + forward_messages=forward_messages) else: - vk.API(session).messages.send(chat_id=userid, attachment=attachment[0]['id']) + vk.API(session).messages.send(chat_id=userid, attachment=attachment[0]['id'], + forward_messages=forward_messages) else: if message.caption: - vk.API(session).messages.send(user_id=userid, message=message.caption, attachment=attachment[0]['id']) + vk.API(session).messages.send(user_id=userid, message=message.caption, attachment=attachment[0]['id'], + forward_messages=forward_messages) else: - vk.API(session).messages.send(user_id=userid, attachment=attachment[0]['id']) + vk.API(session).messages.send(user_id=userid, attachment=attachment[0]['id'], + forward_messages=forward_messages) openedfile.close() os.remove('{}.png'.format(file)) os.remove(file) -def send_video(message, userid, group): +def send_video(message, userid, group, forward_messages=None): filetype = message.content_type session = VkMessage(vk_tokens.get(str(message.from_user.id))).session @@ -260,34 +293,36 @@ def send_video(message, userid, group): files=files).text) video = 'video{}_{}'.format(attachment['owner_id'], attachment['owner_id']['video_id']) if message.caption: - vk.API(session).messages.send(chat_id=userid, message=message.caption, attachment=video) + vk.API(session).messages.send(chat_id=userid, message=message.caption, attachment=video, + forward_messages=forward_messages) else: - vk.API(session).messages.send(chat_id=userid, attachment=video) + vk.API(session).messages.send(chat_id=userid, attachment=video, forward_messages=forward_messages) else: attachment = vk.API(session).video.save(is_private=1) fileonserver = ujson.loads(requests.post(attachment['upload_url'], files=files).text) video = 'video{}_{}'.format(attachment['owner_id'], attachment['vid']) if message.caption: - vk.API(session).messages.send(user_id=userid, message=message.caption, attachment=video) + vk.API(session).messages.send(user_id=userid, message=message.caption, attachment=video, + forward_messages=forward_messages) else: - vk.API(session).messages.send(user_id=userid, attachment=video) + vk.API(session).messages.send(user_id=userid, attachment=video, forward_messages=forward_messages) openedfile.close() os.remove(file) -def send_contact(message, userid, group): +def send_contact(message, userid, group, forward_messages=None): session = VkMessage(vk_tokens.get(str(message.from_user.id))).session if message.contact.last_name: text = 'Контакт: {} {}'.format(message.contact.first_name, message.contact.last_name) else: text = 'Контакт: {}'.format(message.contact.first_name) if group: - vk.API(session).messages.send(chat_id=userid, message=text) - vk.API(session).messages.send(chat_id=userid, message=message.contact) + vk.API(session).messages.send(chat_id=userid, message=text, forward_messages=forward_messages) + vk.API(session).messages.send(chat_id=userid, message=message.contact, forward_messages=forward_messages) else: - vk.API(session).messages.send(user_id=userid, message=text) - vk.API(session).messages.send(chat_id=userid, message=message.contact) + vk.API(session).messages.send(user_id=userid, message=text, forward_messages=forward_messages) + vk.API(session).messages.send(chat_id=userid, message=message.contact, forward_messages=forward_messages) @bot.message_handler(content_types=['document', 'voice', 'audio']) diff --git a/vk_messages.py b/vk_messages.py index aa8d7f6..39285f8 100644 --- a/vk_messages.py +++ b/vk_messages.py @@ -3,6 +3,7 @@ import time import requests import wget import os +import ujson class VkPolling: @@ -28,22 +29,29 @@ class VkPolling: break -def handle_messages(m, vk_user, bot, chat_id): +def handle_messages(m, vk_user, bot, chat_id, mainmessage=None): user = vk.API(vk_user.session).users.get(user_ids=m["uid"], fields=[])[0] - if 'body' in m and not 'attachment' in m and not 'geo' in m: + if 'body' in m and not 'attachment' in m and not 'geo' in m and not 'fwd_messages' in m: data = add_reply_info(m, user["first_name"], user["last_name"]) bot.send_message(chat_id, data, parse_mode='HTML', - disable_notification=check_notification(m)).wait() + disable_notification=check_notification(m), reply_to_message_id=mainmessage).wait() if 'attachment' in m: - attachment_handler(m, user, bot, chat_id) + attachment_handler(m, user, bot, chat_id, mainmessage) if 'geo' in m: data = add_reply_info(m, user["first_name"], user["last_name"]) geo = bot.send_message(chat_id, data, parse_mode='HTML', - disable_notification=check_notification(m)).wait() + disable_notification=check_notification(m), reply_to_message_id=mainmessage).wait() bot.send_venue(chat_id, m['geo']['coordinates'].split(' ')[0], m['geo']['coordinates'].split(' ')[1], m['geo']['place']['title'], m['geo']['place']['city'], disable_notification=check_notification(m), reply_to_message_id=geo.message_id).wait() + if 'fwd_messages' in m: + data = add_reply_info(m, user["first_name"], user["last_name"]) + 'Пересланные сообщения' + reply = bot.send_message(chat_id, data, parse_mode='HTML', + disable_notification=check_notification(m), + reply_to_message_id=mainmessage).wait().message_id + for forwared in m['fwd_messages']: + handle_messages(forwared, vk_user, bot, chat_id, reply) def handle_updates(vk_user, bot, chat_id, updates): @@ -52,27 +60,27 @@ def handle_updates(vk_user, bot, chat_id, updates): handle_messages(m, vk_user, bot, chat_id) -def attachment_handler(m, user, bot, chat_id): +def attachment_handler(m, user, bot, chat_id, mainmessage=None): if m['attachment']['type'] == 'photo': for photo in m['attachments']: data = add_reply_info(m, user['first_name'], user['last_name']) + 'Фото'.format( get_max_src(photo['photo'])) bot.send_message(chat_id, data, parse_mode='HTML', - disable_notification=check_notification(m)).wait() + disable_notification=check_notification(m), reply_to_message_id=mainmessage).wait() if m['attachment']['type'] == 'video': for vid in m['attachments']: link = 'https://vk.com/video{}_{}'.format(vid['video']['owner_id'], vid['video']['vid']) data = add_reply_info(m, user['first_name'], user['last_name']) + 'Видео'.format(link) bot.send_message(chat_id, data, parse_mode='HTML', - disable_notification=check_notification(m)).wait() + disable_notification=check_notification(m), reply_to_message_id=mainmessage).wait() if m['attachment']['type'] == 'audio': for audio in m['attachments']: data = add_reply_info(m, user['first_name'], user['last_name']) + '🎵 {} - {}'.format( audio['audio']['artist'], audio['audio']['title']) bot.send_message(chat_id, data, parse_mode='HTML', - disable_notification=check_notification(m)).wait() + disable_notification=check_notification(m), reply_to_message_id=mainmessage).wait() if m['attachment']['type'] == 'doc': for doc in m['attachments']: if doc['doc']['ext'] == 'gif': @@ -81,9 +89,9 @@ def attachment_handler(m, user, bot, chat_id): data = add_reply_info(m, user["first_name"], user["last_name"]) + 'GIF'.format( link) bot.send_message(chat_id, data, parse_mode='HTML', - disable_notification=check_notification(m)).wait() + disable_notification=check_notification(m), reply_to_message_id=mainmessage).wait() except: - send_doc_link(doc, m, user, bot, chat_id) + send_doc_link(doc, m, user, bot, chat_id, mainmessage) elif doc['doc']['ext'] == 'pdf' or doc['doc']['ext'] == 'zip': try: @@ -92,22 +100,23 @@ def attachment_handler(m, user, bot, chat_id): user["last_name"], ) + 'Документ'.format( link) bot.send_message(chat_id, data, parse_mode='HTML', - disable_notification=check_notification(m)).wait() + disable_notification=check_notification(m), reply_to_message_id=mainmessage).wait() except: - send_doc_link(doc, m, user, bot, chat_id) + send_doc_link(doc, m, user, bot, chat_id, mainmessage) elif doc['doc']['ext'] == 'jpg' or doc['doc']['ext'] == 'png': try: link = doc['doc']['url'] data = add_reply_info(m, user["first_name"], user["last_name"], ) + 'Документ' notification = bot.send_message(chat_id, data, parse_mode='HTML', - disable_notification=check_notification(m)).wait() + disable_notification=check_notification(m), + reply_to_message_id=mainmessage).wait() uploading = bot.send_chat_action(chat_id, 'upload_document') bot.send_document(chat_id, link, reply_to_message_id=notification.message_id, disable_notification=check_notification(m)).wait() uploading.wait() except: - send_doc_link(doc, m, user, bot, chat_id) + send_doc_link(doc, m, user, bot, chat_id, mainmessage) elif doc['doc']['ext'] == 'ogg': try: @@ -115,15 +124,16 @@ def attachment_handler(m, user, bot, chat_id): data = add_reply_info(m, user["first_name"], user["last_name"], ) + \ 'Аудио'.format(link) bot.send_message(chat_id, data, parse_mode='HTML', - disable_notification=check_notification(m)).wait() + disable_notification=check_notification(m), reply_to_message_id=mainmessage).wait() except: - send_doc_link(doc, m, user, bot, chat_id) + send_doc_link(doc, m, user, bot, chat_id, mainmessage) elif doc['doc']['ext'] == 'doc' or doc['doc']['ext'] == 'docx': try: data = add_reply_info(m, user["first_name"], user["last_name"], ) + 'Документ' notification = bot.send_message(chat_id, data, parse_mode='HTML', - disable_notification=check_notification(m)).wait() + disable_notification=check_notification(m), + reply_to_message_id=mainmessage).wait() uploading = bot.send_chat_action(chat_id, 'upload_document') file = wget.download(requests.get(doc['doc']['url']).url) bot.send_document(chat_id, open(file, 'rb'), @@ -133,44 +143,56 @@ def attachment_handler(m, user, bot, chat_id): file.close() os.remove(file) except: - send_doc_link(doc, m, user, bot, chat_id) + send_doc_link(doc, m, user, bot, chat_id, mainmessage) else: - send_doc_link(doc, m, user, bot, chat_id) + send_doc_link(doc, m, user, bot, chat_id, mainmessage) if m['attachment']['type'] == 'sticker': link = m['attachment']['sticker']['photo_512'] data = add_reply_info(m, user["first_name"], user["last_name"], ) + 'Стикер'.format(link) bot.send_message(chat_id, data, parse_mode='HTML', - disable_notification=check_notification(m)).wait() + disable_notification=check_notification(m), reply_to_message_id=mainmessage).wait() # TODO: Wall Posts and comments -def send_doc_link(doc, m, user, bot, chat_id): +def send_doc_link(doc, m, user, bot, chat_id, mainmessage=None): link = doc['doc']['url'] data = add_reply_info(m, user["first_name"], user["last_name"]) + \ 'Документ\n{}'.format(link, doc['doc']['title'] + '.' + doc['doc']['ext']) bot.send_message(chat_id, data, parse_mode='HTML', - disable_notification=check_notification(m)).wait() + disable_notification=check_notification(m), reply_to_message_id=mainmessage).wait() + + +def check_forward_id(msg): + if 'mid' in msg: + return msg['mid'] + else: + return None def add_reply_info(m, first_name, last_name): if m['body']: if 'chat_id' in m: - # TODO: Handle forwared messages - return '{} {} @ {}:\n{}\n'.format(m['uid'], m['chat_id'], first_name, - last_name, m['title'], - m['body'].replace('
', '\n')) + return '{} {} @ {}:\n{}\n'.format(m['uid'], m['chat_id'], + check_forward_id(m), + first_name, + last_name, m['title'], + m['body'].replace('
', '\n')) else: - return '{} {}:\n{}\n'.format(m['uid'], first_name, last_name, - m['body'].replace('
', '\n')) + return '{} {}:\n{}\n'.format(m['uid'], check_forward_id(m), first_name, + last_name, + m['body'].replace('
', '\n')) else: if 'chat_id' in m: - return '{} {} @ {}:\n'.format(m['uid'], m['chat_id'], first_name, - last_name, m['title']) + return '{} {} @ {}:\n'.format(m['uid'], m['chat_id'], + check_forward_id(m), + first_name, + last_name, m['title']) else: - return '{} {}:\n'.format(m['uid'], first_name, last_name) + return '{} {}:\n'.format(m['uid'], check_forward_id(m), first_name, + last_name) def check_notification(value):