Skip to content

Commit c5c3e7c

Browse files
committed
feat: thread_min_characters config.
Added - Config option `thread_min_characters` to require a minimum number of characters in the initial message to create a thread. - Configurable error message options: `thread_min_characters_title`, `thread_min_characters_response`, and `thread_min_characters_footer`.
1 parent a794ebd commit c5c3e7c

File tree

4 files changed

+79
-9
lines changed

4 files changed

+79
-9
lines changed

cogs/modmail.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,7 @@ async def contact(
16371637
creator=creator,
16381638
category=category,
16391639
manual_trigger=manual_trigger,
1640+
# The minimum character check is enforced in ThreadManager.create
16401641
)
16411642

16421643
if thread.cancelled:

core/config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ class ConfigManager:
129129
# regex
130130
"use_regex_autotrigger": False,
131131
"use_hoisted_top_role": True,
132+
# Minimum characters for thread creation
133+
"thread_min_characters": 0,
134+
"thread_min_characters_title": "Message too short",
135+
"thread_min_characters_response": "Your message is too short to create a thread. Please provide more details.",
136+
"thread_min_characters_footer": "Minimum {min_characters} characters required.",
132137
}
133138

134139
private_keys = {

core/config_help.json

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
},
1313
"main_category_id": {
1414
"default": "`Modmail` (created with `{prefix}setup`)",
15-
"description": "This is the category where all new threads will be created.\n\nTo change the Modmail category, you will need to find the [categorys ID](https://support.discordapp.com/hc/en-us/articles/206346498).",
15+
"description": "This is the category where all new threads will be created.\n\nTo change the Modmail category, you will need to find the [category's ID](https://support.discordapp.com/hc/en-us/articles/206346498).",
1616
"examples": [
1717
"`{prefix}config set main_category_id 9234932582312` (`9234932582312` is the category ID)"
1818
],
@@ -24,7 +24,7 @@
2424
},
2525
"fallback_category_id": {
2626
"default": "`Fallback Modmail` (created when the main category is full)",
27-
"description": "This is the category that will hold the threads when the main category is full.\n\nTo change the Fallback category, you will need to find the [categorys ID](https://support.discordapp.com/hc/en-us/articles/206346498).",
27+
"description": "This is the category that will hold the threads when the main category is full.\n\nTo change the Fallback category, you will need to find the [category's ID](https://support.discordapp.com/hc/en-us/articles/206346498).",
2828
"examples": [
2929
"`{prefix}config set fallback_category_id 9234932582312` (`9234932582312` is the category ID)"
3030
],
@@ -88,7 +88,7 @@
8888
},
8989
"user_typing": {
9090
"default": "Enabled",
91-
"description": "When this is set to `yes`, whenever the recipient user starts to type in their DM channel, the moderator will see {bot.user.display_name} is typing…” in the thread channel.",
91+
"description": "When this is set to `yes`, whenever the recipient user starts to type in their DM channel, the moderator will see "{bot.user.display_name} is typing..." in the thread channel.",
9292
"examples": [
9393
"`{prefix}config set user_typing yes`",
9494
"`{prefix}config set user_typing no`"
@@ -151,7 +151,7 @@
151151
},
152152
"mod_typing": {
153153
"default": "Disabled",
154-
"description": "When this is set to `yes`, whenever a moderator starts to type in the thread channel, the recipient user will see \"{bot.user.display_name} is typing\" in their DM channel.",
154+
"description": "When this is set to `yes`, whenever a moderator starts to type in the thread channel, the recipient user will see "{bot.user.display_name} is typing..." in their DM channel.",
155155
"examples": [
156156
"`{prefix}config set mod_typing yes`",
157157
"`{prefix}config set mod_typing no`"
@@ -219,7 +219,7 @@
219219
},
220220
"log_channel_id": {
221221
"default": "`#bot-logs` (created with `{prefix}setup`)",
222-
"description": "This is the channel where all log messages will be sent (ie. thread close message, update message, etc.).\n\nTo change the log channel, you will need to find the [channels ID](https://support.discordapp.com/hc/en-us/articles/206346498). The channel doesnt necessary have to be under the `main_category`.",
222+
"description": "This is the channel where all log messages will be sent (ie. thread close message, update message, etc.).\n\nTo change the log channel, you will need to find the [channel's ID](https://support.discordapp.com/hc/en-us/articles/206346498). The channel doesn't necessary have to be under the `main_category`.",
223223
"examples": [
224224
"`{prefix}config set log_channel_id 9234932582312` (9234932582312 is the channel ID)"
225225
],
@@ -704,7 +704,7 @@
704704
},
705705
"mod_tag": {
706706
"default": "The moderator's highest role",
707-
"description": "This is the name tag in the footer section of the embeds sent by moderators in the recipient DM and thread channel.",
707+
"description": "This is the name tag in the "footer" section of the embeds sent by moderators in the recipient DM and thread channel.",
708708
"examples": [
709709
"`{prefix}config set mod_tag Moderator`"
710710
],
@@ -715,7 +715,7 @@
715715
},
716716
"anon_username": {
717717
"default": "Fallback on `mod_tag`",
718-
"description": "This is the name in the author section of the embeds sent by anonymous moderators in the recipient DM.",
718+
"description": "This is the name in the "author" section of the embeds sent by anonymous moderators in the recipient DM.",
719719
"examples": [
720720
"`{prefix}config set anon_username Incognito Mod`"
721721
],
@@ -737,7 +737,7 @@
737737
},
738738
"anon_tag": {
739739
"default": "\"Response\"",
740-
"description": "This is the name tag in the footer section of the embeds sent by anonymous moderators in the recipient DM.",
740+
"description": "This is the name tag in the "footer" section of the embeds sent by anonymous moderators in the recipient DM.",
741741
"examples": [
742742
"`{prefix}config set anon_tag Support Agent`"
743743
],
@@ -976,7 +976,7 @@
976976
],
977977
"notes": [
978978
"The private_ variant is used when sending to the new user.",
979-
"See also: `private_removed_from_group_title`, `private_removed_from_group_title`"
979+
"See also: `private_removed_from_group_title`, `private_removed_from_group_title`
980980
]
981981
},
982982
"public_removed_from_group_response": {
@@ -1222,5 +1222,48 @@
12221222
"If this configuration is enabled, only roles that are hoisted (displayed seperately in member list) will be used. If a user has no hoisted roles, it will return 'None'.",
12231223
"If you would like to display the top role of a user regardless of if it's hoisted or not, disable `use_hoisted_top_role`."
12241224
]
1225+
},
1226+
"thread_min_characters": {
1227+
"default": "0",
1228+
"description": "The minimum number of characters required in the initial message to create a thread. Set to 0 to disable.",
1229+
"examples": [
1230+
"`{prefix}config set thread_min_characters 20`"
1231+
],
1232+
"notes": [
1233+
"If a user tries to create a thread with a message shorter than this, an error will be shown.",
1234+
"See also: `thread_min_characters_title`, `thread_min_characters_response`, `thread_min_characters_footer`."
1235+
]
1236+
},
1237+
"thread_min_characters_title": {
1238+
"default": "Message too short",
1239+
"description": "The title of the error embed when a user tries to create a thread with too few characters.",
1240+
"examples": [
1241+
"`{prefix}config set thread_min_characters_title Too short!`"
1242+
],
1243+
"notes": [
1244+
"See also: `thread_min_characters`, `thread_min_characters_response`, `thread_min_characters_footer`."
1245+
]
1246+
},
1247+
"thread_min_characters_response": {
1248+
"default": "Your message is too short to create a thread. Please provide more details.",
1249+
"description": "The description of the error embed when a user tries to create a thread with too few characters.",
1250+
"examples": [
1251+
"`{prefix}config set thread_min_characters_response Please write a longer message.`"
1252+
],
1253+
"notes": [
1254+
"You can use `{min_characters}` as a placeholder for the minimum required characters.",
1255+
"See also: `thread_min_characters`, `thread_min_characters_title`, `thread_min_characters_footer`."
1256+
]
1257+
},
1258+
"thread_min_characters_footer": {
1259+
"default": "Minimum {min_characters} characters required.",
1260+
"description": "The footer of the error embed when a user tries to create a thread with too few characters.",
1261+
"examples": [
1262+
"`{prefix}config set thread_min_characters_footer At least {min_characters} characters needed.`"
1263+
],
1264+
"notes": [
1265+
"You can use `{min_characters}` as a placeholder for the minimum required characters.",
1266+
"See also: `thread_min_characters`, `thread_min_characters_title`, `thread_min_characters_response`."
1267+
]
12251268
}
12261269
}

core/thread.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,27 @@ async def create(
14061406
) -> Thread:
14071407
"""Creates a Modmail thread"""
14081408

1409+
# Minimum character check
1410+
min_chars = self.bot.config.get("thread_min_characters")
1411+
if min_chars is None:
1412+
min_chars = 0
1413+
try:
1414+
min_chars = int(min_chars)
1415+
except Exception:
1416+
min_chars = 0
1417+
if min_chars > 0 and message is not None and message.content is not None:
1418+
if len(message.content.strip()) < min_chars:
1419+
embed = discord.Embed(
1420+
title=self.bot.config.get("thread_min_characters_title", "Message too short"),
1421+
description=self.bot.config.get("thread_min_characters_response", "Your message is too short to create a thread. Please provide more details.").replace("{min_characters}", str(min_chars)),
1422+
color=self.bot.error_color,
1423+
)
1424+
embed.set_footer(text=self.bot.config.get("thread_min_characters_footer", "Minimum {min_characters} characters required.").replace("{min_characters}", str(min_chars)))
1425+
await message.channel.send(embed=embed)
1426+
thread = Thread(self, recipient)
1427+
thread.cancelled = True
1428+
return thread
1429+
14091430
# checks for existing thread in cache
14101431
thread = self.cache.get(recipient.id)
14111432
if thread:

0 commit comments

Comments
 (0)