Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "DiscordBot"
version = "3.0.4"
version = "3.0.5"
description = "A simple Discord bot with OpenAI support and server administration tools"
urls.Repository = "https://github.com/ddc/DiscordBot"
urls.Homepage = "https://github.com/ddc/DiscordBot"
Expand Down Expand Up @@ -36,7 +36,7 @@ dependencies = [
"ddcdatabases[postgres]>=3.0.10",
"discord-py>=2.6.4",
"gTTS>=2.5.4",
"openai>=2.23.0",
"openai>=2.24.0",
"PyNaCl>=1.6.2",
"pythonLogs>=6.0.2",
]
Expand Down
4 changes: 2 additions & 2 deletions src/bot/constants/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class CommandError:
DM_CANNOT_EXECUTE = "Cannot execute action on a DM channel"
PRIVILEGE_LOW = "Your Privilege is too low."
DIRECT_MESSAGES_DISABLED = (
"Direct messages are disable in your configuration.\n"
"Direct messages are disabled in your configuration.\n"
"If you want to receive messages from Bots, "
"you need to enable this option under Privacy & Safety:"
'"Allow direct messages from server members."'
Expand Down Expand Up @@ -169,7 +169,7 @@ class BotUtils:
LOADING_EXTENSIONS = "Loading Bot Extensions..."
LOADING_EXTENSION_FAILED = "ERROR: FAILED to load extension"
DISABLED_DM = (
"Direct messages are disable in your configuration.\n"
"Direct messages are disabled in your configuration.\n"
"If you want to receive messages from Bots, "
"you need to enable this option under Privacy & Safety:\n"
'"Allow direct messages from server members."\n'
Expand Down
24 changes: 15 additions & 9 deletions src/bot/tools/bot_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,20 +127,26 @@ async def send_embed(ctx, embed, dm=False):
await ctx.author.send(embed=embed)
elif dm:
# Send to DM and notify in channel
await ctx.author.send(embed=embed)
notification_embed = discord.Embed(description="📬 Response sent to your DM", color=discord.Color.green())
notification_embed.set_author(
name=ctx.author.display_name,
icon_url=ctx.author.avatar.url if ctx.author.avatar else ctx.author.default_avatar.url,
)
await ctx.send(embed=notification_embed)
try:
await ctx.author.send(embed=embed)
notification_embed = discord.Embed(
description="📬 Response sent to your DM", color=discord.Color.green()
)
notification_embed.set_author(
name=ctx.author.display_name,
icon_url=ctx.author.avatar.url if ctx.author.avatar else ctx.author.default_avatar.url,
)
await ctx.send(embed=notification_embed)
except (discord.Forbidden, discord.HTTPException):
# DM failed, fall back to sending in the channel
await ctx.send(embed=embed)
else:
# Send to channel
await ctx.send(embed=embed)
except discord.Forbidden, discord.HTTPException:
except (discord.Forbidden, discord.HTTPException):
await send_error_msg(ctx, messages.DISABLED_DM)
except Exception as e:
ctx.bot.logger.error(e)
ctx.bot.log.error(e)


async def delete_message(ctx, warning=False):
Expand Down
4 changes: 2 additions & 2 deletions src/gw2/cogs/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ async def _keep_typing_alive(ctx, stop_event):
await asyncio.sleep(4) # Renew every 4 seconds (Discord typing lasts ~5s)
except asyncio.CancelledError:
raise # Re-raise CancelledError
except discord.HTTPException, discord.Forbidden:
except (discord.HTTPException, discord.Forbidden):
# Handle Discord API errors gracefully and stop the loop
break
except asyncio.CancelledError:
Expand Down Expand Up @@ -265,7 +265,7 @@ async def limited_guild_fetch(task):
try:
stop_typing.set()
typing_task.cancel()
except AttributeError, RuntimeError:
except (AttributeError, RuntimeError):
# Handle cases where task is already done or event is invalid
pass
await bot_utils.send_error_msg(ctx, e)
Expand Down
4 changes: 2 additions & 2 deletions src/gw2/cogs/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ async def session(ctx):
gw2_session_dal = Gw2SessionsDal(ctx.bot.db_session, ctx.bot.log)
rs_session = await gw2_session_dal.get_user_last_session(user_id)
if not rs_session:
return await bot_utils.send_error_msg(ctx, gw2_messages.USER_NO_SESSION_FOUND, True)
return await bot_utils.send_error_msg(ctx, gw2_messages.USER_NO_SESSION_FOUND)

rs_start = rs_session[0]["start"]
rs_end = rs_session[0]["end"]

if rs_end is None or rs_end.get("date") is None:
return await bot_utils.send_error_msg(ctx, gw2_messages.SESSION_SAVE_ERROR, True)
return await bot_utils.send_error_msg(ctx, gw2_messages.SESSION_SAVE_ERROR)

await ctx.message.channel.typing()
color = ctx.bot.settings["gw2"]["EmbedColor"]
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/bot/tools/test_bot_utils_extra.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,8 @@ async def test_send_embed_generic_exception(self, mock_ctx):

await bot_utils.send_embed(mock_ctx, embed, dm=False)

mock_ctx.bot.logger.error.assert_called_once()
error_arg = mock_ctx.bot.logger.error.call_args[0][0]
mock_ctx.bot.log.error.assert_called_once()
error_arg = mock_ctx.bot.log.error.call_args[0][0]
assert isinstance(error_arg, ValueError)
assert str(error_arg) == "Some unexpected error"

Expand Down
6 changes: 4 additions & 2 deletions tests/unit/gw2/cogs/test_sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,8 @@ async def test_session_no_session_found(self, mock_ctx, sample_api_key_data):
with patch("src.gw2.cogs.sessions.bot_utils.send_error_msg") as mock_error:
await session(mock_ctx)
mock_error.assert_called_once()
assert mock_error.call_args[0][2] is True
# Error sent to channel (not via DM)
assert len(mock_error.call_args[0]) == 2

@pytest.mark.asyncio
async def test_session_end_date_is_none(self, mock_ctx, sample_api_key_data):
Expand All @@ -282,7 +283,8 @@ async def test_session_end_date_is_none(self, mock_ctx, sample_api_key_data):
with patch("src.gw2.cogs.sessions.bot_utils.send_error_msg") as mock_error:
await session(mock_ctx)
mock_error.assert_called_once()
assert mock_error.call_args[0][2] is True
# Error sent to channel (not via DM)
assert len(mock_error.call_args[0]) == 2

@pytest.mark.asyncio
async def test_session_time_passed_less_than_one_minute(self, mock_ctx, sample_api_key_data):
Expand Down
10 changes: 5 additions & 5 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.