mirror of
https://github.com/EDeev/deev.space.git
synced 2026-06-15 11:01:10 +03:00
109 lines
No EOL
3.7 KiB
Python
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 |