Conversation
|
💩 Code linting failed, use |
Summary
|
|
|
||
| @event( | ||
| type="wall_post_new", | ||
| group_id=lambda i: int(i) == settings.VK_MONITORED_GROUP_ID if settings.VK_MONITORED_GROUP_ID else False, |
There was a problem hiding this comment.
Изначально предполагалось, что такие штуки прямо в коде будешь задавать. Не нужно их в настройки вносить
По факту эти @event и есть конфиг, хоть и с кодом
| async def send_to_telegram(message: str, photos: list = None): | ||
| """Отправляет сообщение и фотографии в Telegram канал""" | ||
| if not settings.TELEGRAM_BOT_TOKEN or not settings.TELEGRAM_TARGET_CHANNEL_ID: | ||
| logger.warning("Telegram bot token or channel ID not configured") | ||
| return | ||
|
|
||
| bot = Bot(token=settings.TELEGRAM_BOT_TOKEN) | ||
|
|
||
| try: | ||
| if not photos: | ||
| # Если нет фотографий, отправляем только текст | ||
| await bot.send_message( | ||
| chat_id=settings.TELEGRAM_TARGET_CHANNEL_ID, | ||
| text=message, | ||
| parse_mode='HTML', | ||
| disable_web_page_preview=False | ||
| ) | ||
| elif len(photos) == 1: | ||
| # Если только одна фотография, отправляем ее с подписью | ||
| await bot.send_photo( | ||
| chat_id=settings.TELEGRAM_TARGET_CHANNEL_ID, | ||
| photo=photos[0], | ||
| caption=message, | ||
| parse_mode='HTML' | ||
| ) | ||
| else: | ||
| # Если несколько фотографий, отправляем их как медиагруппу | ||
| media_group = [] | ||
|
|
||
| # Первая фотография с подписью (текстом сообщения) | ||
| media_group.append(InputMediaPhoto( | ||
| media=photos[0], | ||
| caption=message, | ||
| parse_mode='HTML' | ||
| )) | ||
|
|
||
| # Все остальные фотографии без подписи | ||
| for photo_url in photos[1:]: | ||
| media_group.append(InputMediaPhoto( | ||
| media=photo_url | ||
| )) | ||
|
|
||
| await bot.send_media_group( | ||
| chat_id=settings.TELEGRAM_TARGET_CHANNEL_ID, | ||
| media=media_group | ||
| ) | ||
|
|
||
| logger.info(f"Message successfully sent to Telegram channel {settings.TELEGRAM_TARGET_CHANNEL_ID}") | ||
| except Exception as e: | ||
| logger.error(f"Failed to send message to Telegram: {e}") |
There was a problem hiding this comment.
Этот код я бы унес в утилиты работы с телеграммом. Возможно, такой файл уже есть. Куда-нибудь в utils/telegram.py
И задавал бы Telegram channel id через параметр, а не через настройку. Из настроек убрал бы вообще это параметр. Просто захардкодить внутри @event функции
| for attachment in attachments: | ||
| attachment_type = attachment.get("type") | ||
|
|
||
| # Обрабатываем видео | ||
| if attachment_type == "video": | ||
| video_data = attachment.get("video", {}) | ||
| video_id = video_data.get("id") | ||
| video_owner_id = video_data.get("owner_id") | ||
| video_title = video_data.get("title", "Видео") | ||
|
|
||
| if video_id and video_owner_id: | ||
| attachment_texts.append( | ||
| f"\n\n<b>📹 {video_title}</b>: " | ||
| f"<a href='https://vk.com/video{video_owner_id}_{video_id}'>Смотреть видео</a>" | ||
| ) | ||
|
|
||
| # Обрабатываем ссылки | ||
| elif attachment_type == "link": | ||
| link_data = attachment.get("link", {}) | ||
| link_url = link_data.get("url") | ||
| link_title = link_data.get("title", "Ссылка") | ||
|
|
||
| if link_url: | ||
| attachment_texts.append( | ||
| f"\n\n<b>🔗 {link_title}</b>: <a href='{link_url}'>Открыть ссылку</a>" | ||
| ) | ||
|
|
||
| # Обрабатываем документы | ||
| elif attachment_type == "doc": | ||
| doc_data = attachment.get("doc", {}) | ||
| doc_url = doc_data.get("url") | ||
| doc_title = doc_data.get("title", "Документ") | ||
|
|
||
| if doc_url: | ||
| attachment_texts.append( | ||
| f"\n\n<b>📄 {doc_title}</b>: <a href='{doc_url}'>Скачать документ</a>" | ||
| ) | ||
|
|
||
| # Обрабатываем аудио | ||
| elif attachment_type == "audio": | ||
| audio_data = attachment.get("audio", {}) | ||
| audio_id = audio_data.get("id") | ||
| audio_owner_id = audio_data.get("owner_id") | ||
| audio_artist = audio_data.get("artist", "") | ||
| audio_title = audio_data.get("title", "Аудиозапись") | ||
|
|
||
| if audio_id and audio_owner_id: | ||
| attachment_texts.append( | ||
| f"\n\n<b>🎵 {audio_artist} - {audio_title}</b>: " | ||
| f"<a href='https://vk.com/audio{audio_owner_id}_{audio_id}'>Слушать</a>" | ||
| ) | ||
|
|
There was a problem hiding this comment.
Очень большая вложенность. +Проверить это не могу (нужно читать документацию ВК)
По первому пункту: лучше создать файл utils/vk.py и вынести туда отдельными функциями для каждого типа сложений + общую функцию для обработки одного типа сложений. Тогда тут будет for a in attachments: обработай вложение
| photos.append(photo_url) | ||
|
|
||
| # Отправляем в Telegram | ||
| import asyncio |
There was a problem hiding this comment.
Импорты лучше делать в начале файла
|
|
||
| # Отправляем в Telegram | ||
| import asyncio | ||
| asyncio.run(send_to_telegram(message, photos)) |
There was a problem hiding this comment.
Вызывать асинхронный код отсюда не надо точно
| except Exception as e: | ||
| logger.exception(f"Error processing new VK post: {e}") |
There was a problem hiding this comment.
Внутри обработчика событий и так должен быть большой try/except. Не нужно делать ещё один
| WebhookStorage( | ||
| system=WebhookSystems.VK, | ||
| message=request_data, | ||
| try: |
There was a problem hiding this comment.
Внутри router.post и так есть обработчик исключений, тут не нужен
| db.session.commit() | ||
|
|
||
| # Проверяем, это ли событие создания записи на стене | ||
| is_wall_post = event_type == "wall_post_new" | ||
| if is_wall_post: | ||
| logger.info(f"Received new wall post event for group_id: {group_id}") | ||
|
|
||
| # Запускаем обработку в фоновом режиме | ||
| background_tasks.add_task(create_vk_chat, request_data) | ||
| background_tasks.add_task(process_event, request_data) | ||
|
|
||
| return PlainTextResponse('ok') | ||
| except Exception as e: | ||
| logger.exception(f"Error processing VK webhook: {e}") | ||
| return PlainTextResponse('ok') # Всегда возвращаем ok, чтобы VK не повторял запрос |
There was a problem hiding this comment.
Это не нужно. Для этого есть обработчик событий через @event
| @router.post('/monitoring/configure') | ||
| def configure_monitoring( | ||
| config: MonitoringConfig, | ||
| user: dict[str] = Depends(UnionAuth(["social.monitoring.configure"])), | ||
| ) -> dict: | ||
| """Настраивает мониторинг группы ВК и пересылку постов в Telegram канал""" | ||
| # Здесь мы обновляем настройки приложения | ||
| # В реальном приложении нужно будет сохранять эти настройки в базу данных | ||
| # и загружать их при старте, а не менять глобальный объект | ||
|
|
||
| settings = get_settings() | ||
|
|
||
| # В данном примере мы напрямую изменяем настройки | ||
| # Но лучше будет сохранить их в базу и обновлять при перезапуске | ||
| # Для этого потребуется создать соответствующую модель БД | ||
| settings.VK_MONITORED_GROUP_ID = config.vk_group_id | ||
| settings.TELEGRAM_TARGET_CHANNEL_ID = config.telegram_channel_id | ||
|
|
||
| logger.info(f"Monitoring configured for VK group {config.vk_group_id} with Telegram channel {config.telegram_channel_id}") | ||
|
|
||
| return { | ||
| "status": "success", | ||
| "message": "Мониторинг настроен успешно", | ||
| "vk_group_id": config.vk_group_id, | ||
| "telegram_channel_id": config.telegram_channel_id | ||
| } |
There was a problem hiding this comment.
Так это та же ручка, что уже есть.....
Добавлен функционал, позволяющий:
Для работы функционала необходимо добавить две переменные окружения:
TELEGRAM_TARGET_CHANNEL_ID- ID канала Telegram для пересылки постовVK_MONITORED_GROUP_ID- ID группы ВК для мониторингаИзменения просты в использовании и не нарушают существующий функционал.
Check-List
blackиisortдля Back-End илиPrettierдля Front-End?