Skip to content

Commit 124669d

Browse files
lorenzo132sebkuipZallommartinbndrTaaku18
authored
modmail update QOL (#3392)
* Add (truncated) preview to snippets command (#3342) * Add (truncated) preview to snippets command * Add old view as option with "compact" * Fix black formatting * Fix: Image url regex in thread send method (#3378) * feat minimum character requirement for thread creation. (#3380) * update: dpy, snoozing. This pull request updated discord.py to 2.5.2. This also brings a new few features. - snooze - snoozed - unsnooze - clearsnoozed Aswell as a few new config options. - max_snooze_time - snooze_title - snooze_text - unsnooze_tex - unsnooze_notify_channel Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * remove: unneeded import Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Formatting black Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix?: internal messages on restoration Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * formatting Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: internal messages. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: internals Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update thread.py Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: use same logkey after restoration Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Add files via upload Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update thread.py Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update thread.py Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update thread.py Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: show who send which internal message. * Black formatting. * Update Pipfile Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update Pipfile.lock Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * fix: unsnooze bug * feat: CV2 * update: black * fix: duplicates in logs, notes. * feat: dpy 2.6.3, forwarded messages, bug fixes. * Fix jump_url not being displayed * Update pipfile for new dpy version * fix: bug in note title/color * Update snooze arg * Update Pipfile to include tomli package Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * auto detect dpy version Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Remove crlf terminators * fix: ignore typing failures Make Modmail keep working when typing is disabled/outage * fix: only surpress failures * chore: sync local edits before push * fix: ignore typing failures (#3389) * fix: ignore typing failures Make Modmail keep working when typing is disabled/outage * fix: only surpress failures * chore: sync local edits before push * Lock pipenv * Fix: closing with timed words/ command in reply. * Fix: typing in changelog command. * Fix: closing with timed words (additional)) * Fix changelog entry for command reply issue Corrected wording in the changelog entry regarding command inclusion in replies. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update CHANGELOG for v4.2.0 enhancements Forwarded messages now display correctly in threads. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Fix: closing with timed words/ command in reply. (#3391) * fix: ignore typing failures Make Modmail keep working when typing is disabled/outage * fix: only surpress failures * chore: sync local edits before push * Fix: closing with timed words/ command in reply. * Fix: typing in changelog command. * Fix: closing with timed words (additional)) * Fix changelog entry for command reply issue Corrected wording in the changelog entry regarding command inclusion in replies. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Update CHANGELOG for v4.2.0 enhancements Forwarded messages now display correctly in threads. Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> --------- Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * Remove disutil, undo lowercasing escape seq * Add back uvloop * Add config help for snooze configs Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> * fix; raceconditions, thread duplication on unsnooze, message queue for accurasy on high load * Update package versions in requirements.txt Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> * snooze(move): auto-unsnooze on reply/any mod message; enforce hidden permissions on auto-created Snoozed Threads and sync perms on move; restore original overwrites on unsnooze; add capacity guard and config docs * unsnooze: suppress mentions during restore (AllowedMentions.none on replay and notifications) * Remove base64 snooze/unsnooze logic, fix notification crash, clean up replay logic * fix: escape mentions on unsnooze * Fix: Only create log URL button if valid, and robust channel restore for snooze * black formatting * Unsnooze: prefix username (user_id) for plain-text replay messages * feat: command queue during unsnooze process. feat(config): `unsnooze_history_limit`: Limits the number of messages replayed when unsnoozing (genesis message and notes are always shown). * fix: contact while snooze returned as invalid channel * Update thread.py * fix: snooze timing * change: rename default snooze time config * fix: parsing * fix: cache for snooze timer * fix: Properly accessing nested data * rename: default_snooze_time -> snooze_default_duration * improve unsnooze notify * fix: id extraction for clean database. * improve: support for user-friendly time input for snooze_default_duration * reflect config help snooze_default_duration for userfriendly time * fix: anonreply showing None This fixes a bug where, if no `anon_username` is set and the moderator has no roles, the `anon_username` is not showing as `None` anymore, and will show as intended. The logic now works as follows: - If a config anon_username is set → use it - Else, if a mod_tag is set → use it - Else, if the moderator has a top role → use that - Else → use "Anonymous" * black formatting * feat: thread creation menu Credits to Sebkuip(https://github.com/sebkuip) for the original idea and populair plugin.(advanced-menu) This now is a core feature. * Update requirements.txt * fixes This solves: - `config get`: invalid form body - restores functionality after menu timeout. * feat: thread_creation_menu_precreate_channel adds a new: thread_creation_menu_precreate_channel to create the threads, even when nothing is selected yet. * core Fully merged `threadmenu config` into the main bot’s config system. Added threadmenu embed customization capability. * Change thread_creation_menu config Moves thread_creation_menu_options, thread_creation_menu_submenus and thread_creation_menu_enabled to the private config keys to avoid changes via ?config set as they can be changed via ?threadmenu * Change Option Description/Emoji Changes the description and emoji making it possible to be None (optional) * fix: disable menu after closure * feats/fixes configs added: thread_creation_send_dm_embed fix: snooze while no option was selected, after snoozing selecting option first errored. This is now solved * forgot to add help * rely on config for precreating. fix error with unknown channels * feat: large images in threadmenu embed * feat: threadmenu reset * cleanup * codereviews response. Formatting (ruff) * log instead of pass on exception * format * higher delays * black formatting, smoothen menu closure * smoothen which selecetion was made * solves the command from showing in the replies in rare cases * Update CHANGELOG.md * Update sponsors and bmac links * fix: typeerror * fix: Remove thread-only restriction from logs command The logs command can be used anywhere again. * Remove commands from being saved in DB. * fix: correct guildpfp with sepserver setup - made by martin This PR fixes displaying the wrong guild icon in the thread_creation_response embed. When servers having a seperate server setup, the guild icon from the main guild should be displayed instead of the inbox guild. * fix: robust channel deletion handling, skip audit log attribution if permission is missing * update: use current reqs.txt as masterbranch * sync: pip&pip lock with master * Patch Thread Menu Editing Crash * bump version * Missing a newline Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> * Missing a newline Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> --------- Signed-off-by: lorenzo132 <50767078+lorenzo132@users.noreply.github.com> Signed-off-by: Taku <45324516+Taaku18@users.noreply.github.com> Co-authored-by: Sebastian <61157793+sebkuip@users.noreply.github.com> Co-authored-by: Zallom <Yg75nWkHX7jBHcqRPUbb783c54xSa9+github63384893@gmail.com> Co-authored-by: Martin <box152535@gmail.com> Co-authored-by: Taku <45324516+Taaku18@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 829a364 commit 124669d

File tree

15 files changed

+3765
-347
lines changed

15 files changed

+3765
-347
lines changed

CHANGELOG.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,32 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66
This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html);
77
however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/modmail-dev/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section.
88

9+
# v4.2.1
10+
11+
### Added
12+
* `unsnooze_history_limit`: Limits the number of messages replayed when unsnoozing (genesis message and notes are always shown).
13+
* `snooze_behavior`: Choose between `delete` (legacy) or `move` behavior for snoozing.
14+
* `snoozed_category_id`: Target category for `move` snoozing; required when `snooze_behavior` is `move`.
15+
* Thread-creation menu: Adds an interactive select step before a thread channel is created.
16+
* Commands:
17+
* `threadmenu toggle`: Enable/disable the menu.
18+
* `threadmenu show`: List current top-level options.
19+
* `threadmenu option add`: Interactive wizard to create an option.
20+
* `threadmenu option edit/remove/show`: Manage or inspect an existing option.
21+
* `threadmenu submenu create/delete/list/show`: Manage submenus.
22+
* `threadmenu submenu option add/edit/remove`: Manage options inside a submenu.
23+
* Configuration / Behavior:
24+
* Per-option `category` targeting when creating a thread; falls back to `main_category_id` if invalid/missing.
25+
* Optional selection logging (`thread_creation_menu_selection_log`) posts the chosen option in the new thread.
26+
* Anonymous prompt support (`thread_creation_menu_anonymous_menu`).
27+
28+
### Changed
29+
- Renamed `max_snooze_time` to `snooze_default_duration`. The old config will be invalidated.
30+
- When `snooze_behavior` is set to `move`, the snoozed category now has a hard limit of 49 channels. New snoozes are blocked once it’s full until space is freed.
31+
- When switching `snooze_behavior` to `move` via `?config set`, the bot reminds admins to set `snoozed_category_id` if it’s missing.
32+
- Thread-creation menu options & submenu options now support an optional per-option `category` target. The interactive wizards (`threadmenu option add` / `threadmenu submenu option add`) and edit commands allow specifying or updating a category. If the stored category is missing or invalid at selection time, channel creation automatically falls back to `main_category_id`.
33+
34+
935
# v4.2.0
1036

1137
Upgraded discord.py to version 2.6.3, added support for CV2.

bot.py

Lines changed: 268 additions & 39 deletions
Large diffs are not rendered by default.

cogs/modmail.py

Lines changed: 351 additions & 72 deletions
Large diffs are not rendered by default.

cogs/plugins.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,11 @@ async def load_plugin(self, plugin):
251251

252252
if stderr:
253253
logger.debug("[stderr]\n%s.", stderr.decode())
254-
logger.error("Failed to download requirements for %s.", plugin.ext_string, exc_info=True)
254+
logger.error(
255+
"Failed to download requirements for %s.",
256+
plugin.ext_string,
257+
exc_info=True,
258+
)
255259
raise InvalidPluginError(f"Unable to download requirements: ```\n{stderr.decode()}\n```")
256260

257261
if os.path.exists(USER_SITE):
@@ -361,7 +365,10 @@ async def plugins_add(self, ctx, *, plugin_name: str):
361365
return
362366

363367
if str(plugin) in self.bot.config["plugins"]:
364-
embed = discord.Embed(description="This plugin is already installed.", color=self.bot.error_color)
368+
embed = discord.Embed(
369+
description="This plugin is already installed.",
370+
color=self.bot.error_color,
371+
)
365372
return await ctx.send(embed=embed)
366373

367374
if plugin.name in self.bot.cogs:
@@ -470,7 +477,8 @@ async def plugins_remove(self, ctx, *, plugin_name: str):
470477
pass # dir not empty
471478

472479
embed = discord.Embed(
473-
description="The plugin is successfully uninstalled.", color=self.bot.main_color
480+
description="The plugin is successfully uninstalled.",
481+
color=self.bot.main_color,
474482
)
475483
await ctx.send(embed=embed)
476484

@@ -486,7 +494,8 @@ async def update_plugin(self, ctx, plugin_name):
486494

487495
async with safe_typing(ctx):
488496
embed = discord.Embed(
489-
description=f"Successfully updated {plugin.name}.", color=self.bot.main_color
497+
description=f"Successfully updated {plugin.name}.",
498+
color=self.bot.main_color,
490499
)
491500
await self.download_plugin(plugin, force=True)
492501
if self.bot.config.get("enable_plugins"):
@@ -570,7 +579,8 @@ async def plugins_reset(self, ctx):
570579
logger.warning("Removing %s.", entry.name)
571580

572581
embed = discord.Embed(
573-
description="Successfully purged all plugins from the bot.", color=self.bot.main_color
582+
description="Successfully purged all plugins from the bot.",
583+
color=self.bot.main_color,
574584
)
575585
return await ctx.send(embed=embed)
576586

@@ -598,7 +608,8 @@ async def plugins_loaded(self, ctx):
598608

599609
if not self.loaded_plugins:
600610
embed = discord.Embed(
601-
description="There are no plugins currently loaded.", color=self.bot.error_color
611+
description="There are no plugins currently loaded.",
612+
color=self.bot.error_color,
602613
)
603614
return await ctx.send(embed=embed)
604615

@@ -666,7 +677,10 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N
666677
matches = get_close_matches(plugin_name, self.registry.keys())
667678

668679
if matches:
669-
embed.add_field(name="Perhaps you meant:", value="\n".join(f"`{m}`" for m in matches))
680+
embed.add_field(
681+
name="Perhaps you meant:",
682+
value="\n".join(f"`{m}`" for m in matches),
683+
)
670684

671685
return await ctx.send(embed=embed)
672686

0 commit comments

Comments
 (0)