Browse Source

Mémoire des membres : message de bienvenue

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Johnounet 3 ngày trước cách đây
mục cha
commit
f7f261abe3
3 tập tin đã thay đổi với 42 bổ sung và 0 xóa
  1. 1 0
      README.md
  2. 33 0
      bot/discord_bot.py
  3. 8 0
      changelog.txt

+ 1 - 0
README.md

@@ -36,6 +36,7 @@ Seul le nom du fichier reste ensuite en mémoire : le bot se souvient qu'il l'a
 
 Avec `MEMORY=on` :
 
+- **Présentation** : à son premier message, chaque membre reçoit une seule fois un message privé qui lui présente la mémoire et `/memoire`. Si ses messages privés sont fermés, le message est posté dans le salon et s'efface au bout d'une minute.
 - **`/memoire`** : chacun voit la fiche que le bot tient sur lui, visible par lui seul. Il peut la modifier dans une fenêtre déjà remplie, tout effacer (après confirmation) ou désactiver la mémoire : sa fiche est alors effacée et plus rien n'est retenu sur lui, jusqu'à ce qu'il la réactive. Les administrateurs voient, modifient et effacent la fiche de n'importe quel membre avec `/memoire membre:@…` ; seul le membre lui-même peut désactiver la mémoire.
 - **`/memoire-serveur`** : le fichier général du serveur, à voir, modifier ou effacer. Réservé aux administrateurs.
 

+ 33 - 0
bot/discord_bot.py

@@ -44,6 +44,12 @@ USER_MESSAGE_TYPES = (discord.MessageType.default, discord.MessageType.reply)
 DEPARTURE_WINDOW = timedelta(minutes=3)
 # Ajoutée au message auquel le bot répond quand il a noté quelque chose dans sa mémoire.
 NOTED_REACTION = "📝"
+# Envoyé une seule fois à chaque membre, à son premier message, avec MEMORY=on.
+WELCOME = ("{name} peut retenir des choses sur toi au fil des conversations (tes goûts, tes projets…) "
+           "pour mieux te connaître. Tape /memoire sur le serveur pour voir ce qui a été retenu, le modifier "
+           "ou désactiver la fonction.")
+# Durée d'affichage, en secondes, de ce message quand il est posté dans le salon.
+WELCOME_PUBLIC_DURATION = 60
 
 
 def looks_like_image(attachment: discord.Attachment) -> bool:
@@ -230,6 +236,7 @@ class ChatBot(commands.Bot):
         mentioned = self.user is not None and self.user in message.mentions
         if (in_main_channel or mentioned) and self.members:
             await self.register_members(message)
+            await self.welcome(message)
 
         if in_main_channel:
             await self.handle_main_channel(message)
@@ -256,6 +263,30 @@ class ChatBot(commands.Bot):
         for user in await self.concerned_members(message):
             await see_user(self.members, user)
 
+    async def welcome(self, message: discord.Message) -> None:
+        """Premier message d'un membre pas encore prévenu : lui présente la mémoire et /memoire, en message
+        privé, ou dans le salon (effacé au bout d'une minute) si ses messages privés sont fermés."""
+        author = message.author
+        entry = self.members.get(author.id)
+        if author.bot or entry is None or entry["notified"] or not entry["memory"]:
+            return
+        # Marqué avant l'envoi : un deuxième message arrivé entre-temps ne le prévient pas une seconde fois.
+        await self.members.set_notified(author.id)
+        name = message.guild.me.display_name if message.guild else self.user.name
+        text = WELCOME.format(name=name)
+        try:
+            await author.send(text)
+            logger.info("Mémoire présentée à %s en message privé", author)
+            return
+        except discord.HTTPException as exc:  # messages privés fermés
+            logger.info("Message privé impossible pour %s (%s) : présentation dans le salon", author, exc)
+        try:
+            # Le nom s'affiche en mention, sans notification : le bot ne pingue jamais personne.
+            await message.channel.send(f"{author.mention} {text} (Ce message s'efface dans une minute.)",
+                                       delete_after=WELCOME_PUBLIC_DURATION)
+        except discord.HTTPException as exc:
+            logger.warning("Présentation de la mémoire impossible pour %s : %s", author, exc)
+
     async def on_raw_message_edit(self, payload: discord.RawMessageUpdateEvent) -> None:
         """Message modifié : la mémoire, ou le message s'il attend encore sa réponse, prend le nouveau texte."""
         message = payload.message
@@ -898,6 +929,8 @@ async def memory_command(interaction: discord.Interaction, membre: discord.Membe
             "Seuls les administrateurs peuvent voir la fiche d'un autre membre.", ephemeral=True)
         return
     await see_user(bot.members, target)  # un membre qui n'a encore jamais écrit peut déjà désactiver la mémoire
+    if target.id == interaction.user.id:
+        await bot.members.set_notified(target.id)  # il connaît /memoire : inutile de le lui présenter
     card = MemoryCard(bot.memory, member_target(bot.memory, target, interaction.user.id),
                       interaction.user.id, bot_name(interaction))
     await card.send(interaction)

+ 8 - 0
changelog.txt

@@ -47,6 +47,14 @@ Nouveautés
   pour le fichier général. Avec MEMORY=off, les deux commandes le
   signalent. MEMORY_MEMBER_LIMIT et MEMORY_SERVER_LIMIT ne peuvent pas
   dépasser 20000 (taille maximale de la fenêtre de modification).
+- Présentation de la mémoire : au premier message d'un membre, le bot
+  lui envoie une seule fois un message privé qui explique ce qu'il peut
+  retenir et comment le voir, le modifier ou le désactiver avec
+  /memoire. Si ses messages privés sont fermés, le message est posté
+  dans le salon, avec son nom en mention mais sans notification, et
+  s'efface au bout d'une minute. Les membres déjà actifs sont prévenus
+  à leur premier message après le passage à la 5.10 ; un membre qui a
+  déjà utilisé /memoire ne l'est pas.
 
 Divers
 - /reset et /skip sont réservés aux membres qui ont la permission