deev.space/main/signals.py
2025-12-03 04:39:24 +03:00

109 lines
No EOL
3.7 KiB
Python

from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
import requests
import logging
from .models import Article
logger = logging.getLogger(__name__)
@receiver(post_save, sender=Article)
def publish_to_social_media(sender, instance, created, **kwargs):
"""Автоматическая публикация новой статьи в социальные сети."""
if not created:
return
if not instance.is_published:
return
if instance.is_achievement:
return
# Telegram
if settings.TELEGRAM_BOT_TOKEN and settings.TELEGRAM_CHANNEL_ID:
try:
publish_to_telegram(instance)
logger.info(f'Статья "{instance.title}" опубликована в Telegram')
except Exception as e:
logger.error(f'Ошибка публикации в Telegram: {e}')
# VK
if settings.VK_ACCESS_TOKEN and settings.VK_GROUP_ID:
try:
publish_to_vk(instance)
logger.info(f'Статья "{instance.title}" опубликована в VK')
except Exception as e:
logger.error(f'Ошибка публикации в VK: {e}')
def publish_to_telegram(article):
"""Публикация статьи в Telegram-канал."""
bot_token = settings.TELEGRAM_BOT_TOKEN
channel_id = settings.TELEGRAM_CHANNEL_ID
article_url = f"https://deev.space{article.get_absolute_url()}"
text = f"📝 *{escape_markdown(article.title)}*\n\n"
if article.excerpt:
excerpt = article.excerpt[:200] + '...' if len(article.excerpt) > 200 else article.excerpt
text += f"{escape_markdown(excerpt)}\n\n"
text += f"[Читать полностью]({article_url})"
if article.img:
url = f"https://api.telegram.org/bot{bot_token}/sendPhoto"
data = {
'chat_id': channel_id,
'photo': f"https://deev.space{article.img.url}",
'caption': text,
'parse_mode': 'Markdown'
}
else:
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
data = {
'chat_id': channel_id,
'text': text,
'parse_mode': 'Markdown',
'disable_web_page_preview': False
}
response = requests.post(url, data=data, timeout=10)
response.raise_for_status()
def publish_to_vk(article):
"""Публикация статьи в группу VKontakte."""
access_token = settings.VK_ACCESS_TOKEN
group_id = settings.VK_GROUP_ID
article_url = f"https://deev.space{article.get_absolute_url()}"
message = f"📝 {article.title}\n\n"
if article.excerpt:
excerpt = article.excerpt[:300] + '...' if len(article.excerpt) > 300 else article.excerpt
message += f"{excerpt}\n\n"
message += f"🔗 Читать: {article_url}"
url = "https://api.vk.com/method/wall.post"
params = {
'owner_id': f'-{group_id}',
'message': message,
'from_group': 1,
'access_token': access_token,
'v': '5.131'
}
if article.img:
params['attachments'] = f"https://deev.space{article.img.url}"
response = requests.post(url, params=params, timeout=10)
response.raise_for_status()
def escape_markdown(text):
"""Экранирование специальных символов Markdown."""
escape_chars = ['_', '*', '[', ']', '(', ')', '~', '`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!']
for char in escape_chars:
text = text.replace(char, f'\\{char}')
return text