partirdezero/discord_integration/core/announces_logic.py

58 lines
2 KiB
Python

from asgiref.sync import sync_to_async
import discord
from discord.ext import tasks
from discord_integration.models import DiscordNotification
def get_pending_notifications():
return list(DiscordNotification.objects.filter(is_announced=False))
def mark_as_done(notif):
notif.is_announced = True
notif.save()
def process_notifications():
# Cette fonction fait tout le travail SQL "interdit" en mode async
notifs = list(DiscordNotification.objects.filter(is_announced=False))
results = []
for n in notifs:
# Ici, on peut toucher à content_object car on est en mode "sync" !
obj = n.content_object
if obj:
# 1. On cherche la description, sinon le contenu, sinon rien
teaser = getattr(obj, 'description', getattr(obj, 'content', ""))
# 2. Sécurité : On coupe à 3000 caractères pour éviter les erreurs Discord
if len(teaser) > 3000:
teaser = teaser[:2997] + "..."
results.append({
'notif_model': n,
'title': getattr(obj, 'title', getattr(obj, 'name', str(obj))),
'url': obj.get_absolute_url() if hasattr(obj, 'get_absolute_url') else "#",
'summary': teaser
})
return results
@tasks.loop(seconds=5.0)
async def check_announcements(client, channel_id):
print("Checking announcements...")
announcements = await sync_to_async(process_notifications)()
for data in announcements:
title = data['title']
link = data['url']
notif = data['notif_model']
summary = data['summary']
embed = discord.Embed(
title = f"📣 Nouveau contenu : {title}",
url = f"https://partirdezero.com{link}",
description = summary,
color=discord.Color.blue()
)
channel_id = client.get_channel(channel_id)
if channel_id:
await channel_id.send(embed=embed)
await sync_to_async(mark_as_done)(notif)