Skip to content

Commit

Permalink
Add a new Cog for Pinned Messages which keeps reminders as the latest…
Browse files Browse the repository at this point in the history
… message in a channel (#113)
  • Loading branch information
IsaacG authored Jan 7, 2025
1 parent e2c4ced commit d59373e
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 0 deletions.
2 changes: 2 additions & 0 deletions cogs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
from . import inclusive_language
from . import mentor_requests
from . import mod_message
from . import pinned_message
from . import streaming_events
from . import track_react

CloseSupportThread = close_support.CloseSupportThread
InclusiveLanguage = inclusive_language.InclusiveLanguage
RequestNotifier = mentor_requests.RequestNotifier
ModMessage = mod_message.ModMessage
PinnedMessage = pinned_message.PinnedMessage
StreamingEvents = streaming_events.StreamingEvents
TrackReact = track_react.TrackReact
66 changes: 66 additions & 0 deletions cogs/pinned_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""Discord Cog to keep a message "pinned" at the end of a discussion."""

import logging

import discord
from discord.ext import commands

from cogs import base_cog

logger = logging.getLogger(__name__)


class PinnedMessage(base_cog.BaseCog):
"""Keep a message pinned to the end of a channel."""

qualified_name = "Pinned Message"

def __init__(
self,
bot: commands.Bot,
messages: dict[int, str],
**kwargs,
) -> None:
super().__init__(bot=bot, **kwargs)
self.bot = bot
self.messages: dict[int, str] = messages
self.last_message: dict[int, discord.Message] = {}

@commands.Cog.listener()
async def on_ready(self) -> None:
"""Popular prior messages from channel histories."""
if self.bot.user:
for channel_id, content in self.messages.items():
message = await self.find_prior_message(channel_id, content)
if message:
self.last_message[channel_id] = message

async def find_prior_message(self, channel_id: int, content: str) -> None | discord.Message:
"""Return a prior message from a channel history."""
assert self.bot.user is not None
for guild in self.bot.guilds:
channel = guild.get_channel(channel_id)
if isinstance(channel, discord.TextChannel):
async for message in channel.history(limit=50, oldest_first=None):
if message.author.id == self.bot.user.id and message.content == content:
return message
return None

async def bump_message(self, channel: discord.TextChannel) -> None:
"""Bump a pinned message in a channel."""
if last := self.last_message.get(channel.id):
await last.delete()

msg = await channel.send(self.messages[channel.id], silent=True)
self.last_message[channel.id] = msg

@commands.Cog.listener()
async def on_message(self, message: discord.Message) -> None:
"""Move message to the end of the channel."""
if message.author.bot:
return
if not isinstance(message.channel, discord.TextChannel):
return
if message.channel.id not in self.messages:
return
await self.bump_message(message.channel)
14 changes: 14 additions & 0 deletions conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"CloseSupportThread",
"InclusiveLanguage",
"ModMessage",
"PinnedMessage",
"RequestNotifier",
"StreamingEvents",
"TrackReact",
Expand Down Expand Up @@ -129,3 +130,16 @@

# CloseSupportThread
SUPPORT_RESOLVED = "✅"


# PinnedMessage
PINNED_MESSAGES = {
# Test channel in test server.
1091223069407842306: "This is a pinned message.",
# Exercism photo channel
1203795616594010192: """\
This is the photos channel. It is for sharing _your photographs_, not images.
If you did not take the photo yourself with a camera, please do not post it!
If it is not a photograph (an image captured by a camera), it will be deleted.
When responding to messages, please remember to use a thread. Thank you!""",
}
1 change: 1 addition & 0 deletions exercism_discord_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ def get_cogs(self) -> dict[commands.CogMeta, dict[str, Any]]:
"pattern_response": conf.EXCLUSIVE_LANGUAGE
},
cogs.ModMessage: {"canned_messages": conf.CANNED_MESSAGES},
cogs.PinnedMessage: {"messages": conf.PINNED_MESSAGES},
cogs.RequestNotifier: {
"channel_id": int(find_setting("MENTOR_REQUEST_CHANNEL")),
"sqlite_db": find_setting("SQLITE_DB"),
Expand Down

0 comments on commit d59373e

Please sign in to comment.