Skip to content

Commit cc0d72b

Browse files
authored
Add support for replies to help snippets (#3538)
* Added get_reference_message helper * Implemented get_reference_message in get_command_ctx * Moved the ctx.send variant of get_command_ctx to the else branch * Moved get_reference message from ext/info/tags.py to utils/messages.py * Added functionality from get_reference_message * Added send_or_reply helper * Make send_or_reply return the discord.Message instead of None * Change the use of bare get_reference_message for the send_or_reply helper to avoid repetition * Refactor get_reference_message to avoid fetching messages manually and include else in the try block for clarity. * Add a check for referece.message_id for fetch_message to not complaint, and now referenced_message can be taken from cache or fetched * Reconstruct the reference to avoid HTTPException in case the reply can't succesfuly get the reference * Update the docstring to match current behavior * Fix the send_or_reply indentation
1 parent 7ff00f5 commit cc0d72b

5 files changed

Lines changed: 44 additions & 8 deletions

File tree

bot/exts/info/pep.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from bot.bot import Bot
88
from bot.log import get_logger
9+
from bot.utils.messages import send_or_reply
910

1011
log = get_logger(__name__)
1112

@@ -93,8 +94,7 @@ async def pep_command(self, ctx: Context, pep_number: int) -> None:
9394
colour=Colour.red(),
9495
)
9596

96-
await ctx.send(embed=embed)
97-
97+
await send_or_reply(ctx, embed)
9898

9999
async def setup(bot: Bot) -> None:
100100
"""Load the PEP cog."""

bot/exts/info/resources.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from discord.ext import commands
66

77
from bot.bot import Bot
8+
from bot.utils.messages import send_or_reply
89

910
REGEX_CONSECUTIVE_NON_LETTERS = r"[^A-Za-z0-9]+"
1011
RESOURCE_URL = "https://www.pythondiscord.com/resources/"
@@ -61,7 +62,7 @@ async def resources_command(self, ctx: commands.Context, *, resource_topic: str
6162
f"of hand-selected learning resources that we "
6263
f"regularly recommend to both beginners and experts."
6364
)
64-
await ctx.send(embed=embed)
65+
await send_or_reply(ctx, embed)
6566

6667

6768
async def setup(bot: Bot) -> None:

bot/exts/info/source.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from bot.bot import Bot
1010
from bot.constants import URLs
1111
from bot.exts.info.tags import TagIdentifier
12+
from bot.utils.messages import send_or_reply
1213

1314
SourceObject = commands.HelpCommand | commands.Command | commands.Cog | TagIdentifier | commands.ExtensionNotLoaded
1415

@@ -40,12 +41,14 @@ async def source_command(
4041
embed = Embed(title="Bot's GitHub Repository")
4142
embed.add_field(name="Repository", value=f"[Go to GitHub]({URLs.github_bot_repo})")
4243
embed.set_thumbnail(url="https://avatars1.githubusercontent.com/u/9919")
43-
await ctx.send(embed=embed)
44+
45+
await send_or_reply(ctx, embed)
4446
return
4547

4648
obj, source_type = await self.get_source_object(ctx, source_item)
4749
embed = await self.build_embed(obj, source_type)
48-
await ctx.send(embed=embed)
50+
51+
await send_or_reply(ctx, embed)
4952

5053
@staticmethod
5154
async def get_source_object(ctx: commands.Context, argument: str) -> tuple[SourceObject, SourceType]:

bot/exts/info/tags.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from bot.bot import Bot
1414
from bot.log import get_logger
1515
from bot.pagination import LinePaginator
16-
from bot.utils.messages import wait_for_deletion
16+
from bot.utils.messages import send_or_reply, wait_for_deletion
1717

1818
log = get_logger(__name__)
1919

@@ -305,7 +305,7 @@ async def get_command_ctx(
305305
if embed is not COOLDOWN.obj:
306306

307307
await wait_for_deletion(
308-
await ctx.send(embed=embed),
308+
await send_or_reply(ctx, embed),
309309
(ctx.author.id,)
310310
)
311311
# A valid tag was found and was either sent, or is on cooldown

bot/utils/messages.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from itertools import zip_longest
88

99
import discord
10-
from discord import Message
10+
from discord import DeletedReferencedMessage, Embed, Message
1111
from discord.ext.commands import Context
1212
from pydis_core.site_api import ResponseCodeError
1313
from pydis_core.utils import scheduling
@@ -285,3 +285,35 @@ async def upload_log(
285285
raise
286286

287287
return f"{URLs.site_logs_view}/{response['id']}"
288+
289+
async def get_reference_message(ctx: Context) -> Message | None:
290+
"""Return a message reference if the reference exists and it does not refer to the author of the message."""
291+
if (ctx.message.reference is None
292+
or ctx.message.reference.message_id is None):
293+
return None
294+
try:
295+
referenced_message = (
296+
ctx.message.reference.resolved
297+
or ctx.message.reference.cached_message
298+
or await ctx.fetch_message(ctx.message.reference.message_id)
299+
)
300+
except (discord.Forbidden, discord.NotFound):
301+
return None
302+
else:
303+
if referenced_message is None or isinstance(referenced_message, DeletedReferencedMessage):
304+
return None
305+
if referenced_message.author == ctx.author:
306+
return None
307+
return referenced_message
308+
309+
async def send_or_reply(ctx: Context, embed: Embed) -> Message:
310+
"""
311+
Sends the bot message as a reply if the callers message has a reference.
312+
313+
If the callers message does not have a reference or the reference is deleted,
314+
the bot messsage is sent without replying.
315+
"""
316+
if message_reference := await get_reference_message(ctx):
317+
reference = message_reference.to_reference(fail_if_not_exists=False)
318+
return await ctx.send(embed=embed, reference=reference)
319+
return await ctx.send(embed=embed)

0 commit comments

Comments
 (0)