Skip to content

Commit 614cffb

Browse files
authored
Use MongoDB to store pinned message IDs (#126)
1 parent 0904840 commit 614cffb

File tree

5 files changed

+46
-3
lines changed

5 files changed

+46
-3
lines changed

.github/workflows/lint.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ jobs:
2424
run: |
2525
python -m pip install --upgrade pip
2626
pip install click discord.py python-dotenv
27-
pip install prometheus_client
28-
pip install requests sentry_sdk python-logging-loki aiohttp systemd-python
27+
pip install prometheus_client sentry_sdk python-logging-loki
28+
pip install requests aiohttp systemd-python
29+
pip install pymongo
2930
- name: Install linters
3031
run: |
3132
pip install flake8 mypy pylint

cogs/base_cog.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import collections
44
from typing import Any, Callable
55

6+
import pymongo.mongo_client # type: ignore
67
from discord.ext import commands
78

89

@@ -15,10 +16,12 @@ def __init__(
1516
self,
1617
bot: commands.Bot,
1718
exercism_guild_id: int,
19+
mongodb: None | pymongo.mongo_client.MongoClient = None,
1820
) -> None:
1921
self.bot = bot
2022
self.exercism_guild_id = exercism_guild_id
2123
self.usage_stats: dict[str, Any] = collections.defaultdict(self.STATS_TYPE)
24+
self.mongodb = mongodb
2225

2326
def details(self) -> str:
2427
"""Return cog details."""

cogs/pinned_message.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import logging
44

55
import discord
6+
import pymongo.mongo_client
67
from discord.ext import commands
78

89
from cogs import base_cog
@@ -25,6 +26,11 @@ def __init__(
2526
self.bot = bot
2627
self.messages: dict[int, str] = messages
2728
self.last_message: dict[int, discord.Message] = {}
29+
self.mongo: pymongo.mongo_client.database.Collection | None
30+
if isinstance(self.mongodb, pymongo.mongo_client.database.Database):
31+
self.mongo = self.mongodb.get_collection("pinned_messages")
32+
else:
33+
self.mongo = None
2834

2935
@commands.Cog.listener()
3036
async def on_ready(self) -> None:
@@ -41,6 +47,15 @@ async def find_prior_message(self, channel_id: int, content: str) -> None | disc
4147
for guild in self.bot.guilds:
4248
channel = guild.get_channel(channel_id)
4349
if isinstance(channel, discord.TextChannel):
50+
if self.mongo is not None:
51+
try:
52+
got = self.mongo.find_one({"channel": channel_id})
53+
if got is not None:
54+
message_id = got["message"]
55+
return await channel.get_partial_message(message_id).fetch()
56+
except Exception as e: # pylint: disable=broad-exception-caught
57+
logger.error("Failed to get message via MongoDB: %s", e)
58+
4459
async for message in channel.history(limit=50, oldest_first=None):
4560
if message.author.id == self.bot.user.id and message.content == content:
4661
return message
@@ -52,6 +67,16 @@ async def bump_message(self, channel: discord.TextChannel) -> None:
5267
await last.delete()
5368

5469
msg = await channel.send(self.messages[channel.id], silent=True)
70+
if self.mongo is not None:
71+
try:
72+
self.mongo.replace_one(
73+
{"channel": channel.id},
74+
{"channel": channel.id, "message": msg.id},
75+
True,
76+
)
77+
except Exception as e: # pylint: disable=broad-exception-caught
78+
logger.error("Failed to save message to MongoDB: %s", e)
79+
5580
self.last_message[channel.id] = msg
5681

5782
@commands.Cog.listener()

conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
# PinnedMessage
153153
PINNED_MESSAGES = {
154154
# Test channel in test server.
155-
1091223069407842306: "This is a pinned message.",
155+
CHANNEL_ID["test"]: "This is a pinned message.",
156156
# Exercism #photo channel
157157
CHANNEL_ID["Exercism #photos"]: """\
158158
> **📸 Pinned Reminder 📸**

exercism_discord_bot.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import dotenv
1515
import logging_loki # type: ignore
1616
import prometheus_client # type: ignore
17+
import pymongo.mongo_client # type: ignore
18+
import pymongo.server_api # type: ignore
1719
import sentry_sdk # type: ignore
1820
import systemd.journal # type: ignore
1921
from discord.ext import commands
@@ -73,11 +75,23 @@ async def setup_hook(self):
7375
dsn=find_setting("SENTRY_URI"),
7476
traces_sample_rate=1.0,
7577
)
78+
7679
guild = discord.Object(id=self.exercism_guild_id)
7780
standard_args = {
7881
"bot": self,
7982
"exercism_guild_id": self.exercism_guild_id,
8083
}
84+
85+
if has_setting("MONGODB_URL"):
86+
try:
87+
mongo_uri = find_setting("MONGODB_URL")
88+
mongo_api = pymongo.server_api.ServerApi("1")
89+
client = pymongo.mongo_client.MongoClient(mongo_uri, server_api=mongo_api)
90+
standard_args["mongodb"] = client.get_database("exercism_discord")
91+
logger.debug("Connected to MongoDB.")
92+
except Exception as e: # pylint: disable=broad-exception-caught
93+
logger.error("Failed to connect to MongoDB: %s", e)
94+
8195
for cog, kwargs in self.get_cogs().items():
8296
combined = standard_args | kwargs
8397
logger.info("Loading cog %s", cog.__name__)

0 commit comments

Comments
 (0)