diff --git a/bot.py b/bot.py
index 1bb6d32..ea1e68e 100644
--- a/bot.py
+++ b/bot.py
@@ -59,11 +59,9 @@ async def get_vk_chat(cid):
return VkChat.objects.get_or_create(cid=cid)
-max_photo_re = re.compile('photo_([0-9]*)')
-
-
-async def get_max_photo(obj, keyword='photo'):
+def get_max_photo(obj, keyword='photo'):
maxarr = []
+ max_photo_re = re.compile(f'{keyword}_([0-9]*)')
for k, v in obj.items():
m = max_photo_re.match(k)
if m:
diff --git a/telegram.py b/telegram.py
index 6fd5013..1406130 100644
--- a/telegram.py
+++ b/telegram.py
@@ -104,8 +104,13 @@ async def vk_sender(token, tg_message, **kwargs):
reply_to_message_id=tg_message.message_id)
return
except VkAPIError:
- log.exception(msg='Error in vk sender', exc_info=True)
- return None
+ await asyncio.sleep(5)
+ if kwargs.get('retries') > 4:
+ log.exception(msg='Error in vk sender', exc_info=True)
+ return None
+ else:
+ kwargs['retries'] = kwargs.get('retries', 0) + 1
+ await vk_sender(token, tg_message, **kwargs)
except Exception:
log.exception(msg='Error in vk sender', exc_info=True)
return None
@@ -357,7 +362,7 @@ async def get_dialog_info(api, vk_chat_id, name_case='nom'):
if vk_chat_id >= 2000000000:
dialog_info = await api('messages.getChat', chat_id=vk_chat_id - 2000000000)
title = dialog_info['title']
- max_photo = await get_max_photo(dialog_info)
+ max_photo = get_max_photo(dialog_info)
if max_photo:
photo = dialog_info[max_photo]
else:
@@ -373,7 +378,7 @@ async def get_dialog_info(api, vk_chat_id, name_case='nom'):
elif vk_chat_id < 0:
dialog_info = await api('groups.getById', group_ids=abs(vk_chat_id))
title = dialog_info[0]['name']
- max_photo = await get_max_photo(dialog_info[0])
+ max_photo = get_max_photo(dialog_info[0])
if max_photo:
photo = dialog_info[0][max_photo]
else:
diff --git a/vk_messages.py b/vk_messages.py
index 3a1a5fa..dae2008 100644
--- a/vk_messages.py
+++ b/vk_messages.py
@@ -560,6 +560,7 @@ async def process_message(msg, token=None, is_multichat=None, vk_chat_id=None, u
full_chat = await msg.api('messages.getChat', chat_id=vk_chat_id - 2000000000)
if full_msg.get('items'):
for vk_msg in full_msg['items']:
+ vk_msg_url = f'https://vk.com/im?msgid={vk_msg["id"]}&sel=c{vk_msg["peer_id"]}'
disable_notify = force_disable_notify or bool(vk_msg.get('push_settings', False))
attaches_scheme = []
if vk_msg.get('attachments'):
@@ -675,12 +676,14 @@ async def process_message(msg, token=None, is_multichat=None, vk_chat_id=None, u
header_message = tg_message = await bot.send_message(to_tg_chat, header + body,
parse_mode=ParseMode.HTML,
reply_to_message_id=main_message,
- disable_notification=disable_notify)
+ disable_notification=disable_notify,
+ vk_msg_url=vk_msg_url)
except MessageError: # Надо бы обновить aiogram, чтобы можно было ловить MessageToReplyNotFound
header_message = tg_message = await bot.send_message(to_tg_chat, header + body,
parse_mode=ParseMode.HTML,
reply_to_message_id=None,
- disable_notification=disable_notify)
+ disable_notification=disable_notify,
+ vk_msg_url=vk_msg_url)
if forwarded:
main_message = header_message.message_id
Message.objects.create(
@@ -697,7 +700,7 @@ async def process_message(msg, token=None, is_multichat=None, vk_chat_id=None, u
for photo in photo_attachments:
media.attach_photo(photo['content'])
tg_messages = await tgsend(bot.send_media_group, to_tg_chat, media, reply_to_message_id=main_message,
- disable_notification=disable_notify)
+ disable_notification=disable_notify, vk_msg_url=vk_msg_url)
for tg_message in tg_messages:
Message.objects.create(
vk_chat=vk_chat_id,
@@ -708,21 +711,23 @@ async def process_message(msg, token=None, is_multichat=None, vk_chat_id=None, u
for attachment in attaches_scheme:
if attachment:
+ tg_message = None
if attachment['type'] == 'text':
await bot.send_chat_action(to_tg_chat, ChatActions.TYPING)
tg_message = await tgsend(bot.send_message, to_tg_chat, attachment['content'],
parse_mode=ParseMode.HTML, reply_to_message_id=main_message,
- disable_notification=disable_notify)
+ disable_notification=disable_notify, vk_msg_url=vk_msg_url)
elif attachment['type'] == 'photo' and len(photo_attachments) == 1:
await bot.send_chat_action(to_tg_chat, ChatActions.UPLOAD_PHOTO)
- tg_message = await tgsend(bot.send_photo, to_tg_chat, attachment['content'],
- reply_to_message_id=main_message,
- disable_notification=disable_notify)
+ tg_message = await tgsend(bot.send_photo, to_tg_chat, attachment['content'],
+ reply_to_message_id=main_message,
+ disable_notification=disable_notify, vk_msg_url=vk_msg_url)
elif attachment['type'] == 'document':
await bot.send_chat_action(to_tg_chat, ChatActions.UPLOAD_DOCUMENT)
tg_message = await tgsend(bot.send_document, to_tg_chat,
attachment.get('content', '') or attachment.get('url'),
- reply_to_message_id=main_message, disable_notification=disable_notify)
+ reply_to_message_id=main_message, disable_notification=disable_notify,
+ vk_msg_url=vk_msg_url)
if 'content' in attachment:
try:
# Иногда тут появляется url, лень проверять откуда растут ноги
@@ -738,19 +743,23 @@ async def process_message(msg, token=None, is_multichat=None, vk_chat_id=None, u
elif attachment['type'] == 'video':
await bot.send_chat_action(to_tg_chat, ChatActions.UPLOAD_VIDEO)
tg_message = await tgsend(bot.send_video, to_tg_chat, attachment['content'],
- reply_to_message_id=main_message, disable_notification=disable_notify)
+ reply_to_message_id=main_message, disable_notification=disable_notify,
+ vk_msg_url=vk_msg_url)
elif attachment['type'] == 'sticker':
await bot.send_chat_action(to_tg_chat, ChatActions.TYPING)
tg_message = await tgsend(bot.send_sticker, to_tg_chat, attachment['content'],
- reply_to_message_id=main_message, disable_notification=disable_notify)
+ reply_to_message_id=main_message, disable_notification=disable_notify,
+ vk_msg_url=vk_msg_url)
elif attachment['type'] == 'location':
await bot.send_chat_action(to_tg_chat, ChatActions.FIND_LOCATION)
tg_message = await tgsend(bot.send_location, to_tg_chat, *attachment['content'],
- reply_to_message_id=main_message, disable_notification=disable_notify)
+ reply_to_message_id=main_message, disable_notification=disable_notify,
+ vk_msg_url=vk_msg_url)
elif attachment['type'] == 'venue':
await bot.send_chat_action(to_tg_chat, ChatActions.FIND_LOCATION)
tg_message = await tgsend(bot.send_venue, to_tg_chat, *attachment['content'],
- reply_to_message_id=main_message, disable_notification=disable_notify)
+ reply_to_message_id=main_message, disable_notification=disable_notify,
+ vk_msg_url=vk_msg_url)
elif attachment['type'] == 'audio':
await bot.send_chat_action(to_tg_chat, ChatActions.UPLOAD_DOCUMENT)
tg_message = await tgsend(bot.send_audio, to_tg_chat, audio=attachment['content'],
@@ -758,6 +767,7 @@ async def process_message(msg, token=None, is_multichat=None, vk_chat_id=None, u
performer=attachment.get('artist', None),
title=attachment.get('title', None),
reply_to_message_id=main_message, disable_notification=disable_notify,
+ vk_msg_url=vk_msg_url,
parse_mode='HTML')
elif attachment['type'] == 'audio_message':
await bot.send_chat_action(to_tg_chat, ChatActions.RECORD_AUDIO)
@@ -775,26 +785,31 @@ async def process_message(msg, token=None, is_multichat=None, vk_chat_id=None, u
# tg_chat=transcript_message.chat.id,
# tg_id=transcript_message.message_id
# )
-
- Message.objects.create(
- vk_chat=vk_chat_id,
- vk_id=vk_msg_id,
- tg_chat=tg_message.chat.id,
- tg_id=tg_message.message_id
- )
+ if tg_message:
+ Message.objects.create(
+ vk_chat=vk_chat_id,
+ vk_id=vk_msg_id,
+ tg_chat=tg_message.chat.id,
+ tg_id=tg_message.message_id
+ )
if vk_msg.get('fwd_messages'):
await bot.send_chat_action(to_tg_chat, ChatActions.TYPING)
for fwd_message in vk_msg['fwd_messages']:
- fwd_msgs_in_db = Message.objects.filter(
- vk_chat=vk_chat_id,
- vk_id=fwd_message['id'],
- tg_chat=to_tg_chat
- )
+ # Не у всех сообщений есть уникальный id, похоже надо сохранять conversation_message_id в том числе
+ # И делать миграции
+ if fwd_message['id']:
+ fwd_msgs_in_db = Message.objects.filter(
+ vk_chat=vk_chat_id,
+ vk_id=fwd_message['id'],
+ tg_chat=to_tg_chat
+ )
+ else:
+ fwd_msg_in_db = None
if fwd_msgs_in_db:
for fwd_msg_in_db in fwd_msgs_in_db:
try:
await bot.forward_message(to_tg_chat, to_tg_chat, fwd_msg_in_db.tg_id,
- disable_notification=disable_notify)
+ disable_notification=disable_notify, vk_msg_url=vk_msg_url)
except:
await process_message(msg, token=token, is_multichat=is_multichat,
vk_chat_id=vk_chat_id,
@@ -827,6 +842,7 @@ async def get_name(identifier, api):
async def tgsend(method, *args, **kwargs):
+ vk_msg_url = kwargs.pop('vk_msg_url', 0)
try:
tg_message = await method(*args, **kwargs)
return tg_message
@@ -836,6 +852,15 @@ async def tgsend(method, *args, **kwargs):
except Exception:
log.exception(msg='Error in message sending', exc_info=True)
+ try:
+ text = 'Ошибка отправки вложения VK → Telegram'
+ if vk_msg_url:
+ text += '\n' + f'Сообщение'
+ await bot.send_message(args[0], text=text, parse_mode='HTML')
+ except Exception:
+ log.exception(msg='Error in message sending report', exc_info=True)
+ pass
+
async def process_event(msg):
pass
@@ -876,7 +901,7 @@ async def process_attachment(attachment, token=None):
res = {'content': voice_url, 'type': 'audio_message'}
if attachment[atype].get('transcript'):
- return {'content': f'Войс:{atype[atype]["transcript"]}', 'type': 'text'}
+ return {'content': f'Войс:{attachment[atype]["transcript"]}', 'type': 'text'}
return res
elif atype == 'audio':
@@ -969,8 +994,8 @@ async def process_attachment(attachment, token=None):
elif atype == 'doc':
ext = attachment[atype]['ext']
if ext == 'gif':
- size = attachment[atype]['file_size']
- gif_url = attachment[atype]['url'] + '&mp4=1'
+ size = int(attachment[atype]['preview']['video']['file_size'])
+ gif_url = attachment[atype]['preview']['video']['src']
if size > MAX_FILE_SIZE:
return {'content': f'GIF', 'type': 'text'}
return {'content': gif_url, 'type': 'document'}
@@ -1018,7 +1043,7 @@ async def process_attachment(attachment, token=None):
return {'content': file_bytes, 'type': 'sticker'}
elif atype == 'gift':
- gift_url = attachment[atype][await get_max_photo(attachment[atype], 'thumb')]
+ gift_url = attachment[atype][get_max_photo(attachment[atype], 'thumb')]
return {'content': f'Подарок', 'type': 'text'}
elif atype == 'link':
link_url = attachment[atype]['url']