Skip to content

Commit 305196b

Browse files
committed
Add support for thread titles, resolve #2838
1 parent edd7ef2 commit 305196b

File tree

5 files changed

+45
-7
lines changed

5 files changed

+45
-7
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ 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/kyb3r/modmail/issues/319). If you're a plugins developer, note the "BREAKING" section.
88

9-
# v3.7.0-dev7
9+
# v3.7.0-dev8
1010

1111
### Added
1212

@@ -24,6 +24,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s
2424
- Added `cooldown_thread_title`, `cooldown_thread_response` to customise message sent when user is on a creating thread cooldown. ([GH #2865](https://github.com/kyb3r/modmail/issues/2865))
2525
- Added `?selfcontact` to allow users to open a thread. ([GH #2762](https://github.com/kyb3r/modmail/issues/2762))
2626
- Support stickers and reject non-messages (i.e. pin_add)
27+
- Add support for thread titles, `?title` ([GH #2838](https://github.com/kyb3r/modmail/issues/2838))
2728

2829
### Fixed
2930

bot.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "3.7.0-dev7"
1+
__version__ = "3.7.0-dev8"
22

33

44
import asyncio
@@ -32,7 +32,7 @@
3232
from core import checks
3333
from core.clients import ApiClient, PluginDatabaseClient, MongoDBClient
3434
from core.config import ConfigManager
35-
from core.utils import human_join, normalize_alias
35+
from core.utils import human_join, match_title, normalize_alias
3636
from core.models import PermissionLevel, SafeFormatter, getLogger, configure_logging
3737
from core.thread import ThreadManager
3838
from core.time import human_timedelta
@@ -458,6 +458,7 @@ async def on_ready(self):
458458
log["channel_id"],
459459
{
460460
"open": False,
461+
"title": match_title(thread.channel.topic),
461462
"closed_at": str(datetime.utcnow()),
462463
"close_message": "Channel has been deleted, no closer found.",
463464
"closer": {

cogs/modmail.py

+9
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,15 @@ def format_log_embeds(self, logs, avatar_url):
646646
embeds.append(embed)
647647
return embeds
648648

649+
650+
@commands.command()
651+
@checks.thread_only()
652+
async def title(self, ctx, *, name: str):
653+
await ctx.thread.set_title(name)
654+
sent_emoji, _ = await self.bot.retrieve_emoji()
655+
await self.bot.add_reaction(ctx.message, sent_emoji)
656+
657+
649658
@commands.group(invoke_without_command=True)
650659
@checks.has_permissions(PermissionLevel.SUPPORTER)
651660
async def logs(self, ctx, *, user: User = None):

core/thread.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
from core.models import getLogger
1414
from core.time import human_timedelta
15-
from core.utils import is_image_url, days, match_user_id, truncate, format_channel_name
15+
from core.utils import is_image_url, days, match_title, match_user_id, truncate, format_channel_name
1616

1717
logger = getLogger(__name__)
1818

@@ -334,6 +334,7 @@ async def _close(
334334
self.channel.id,
335335
{
336336
"open": False,
337+
"title": match_title(self.channel.topic),
337338
"closed_at": str(datetime.utcnow()),
338339
"nsfw": self.channel.nsfw,
339340
"close_message": message if not silent else None,
@@ -346,14 +347,18 @@ async def _close(
346347
},
347348
},
348349
)
350+
else:
351+
log_data = None
349352

350353
if isinstance(log_data, dict):
351354
prefix = self.bot.config["log_url_prefix"].strip("/")
352355
if prefix == "NONE":
353356
prefix = ""
354357
log_url = f"{self.bot.config['log_url'].strip('/')}{'/' + prefix if prefix else ''}/{log_data['key']}"
355358

356-
if log_data["messages"]:
359+
if log_data["title"]:
360+
sneak_peak = log_data["title"]
361+
elif log_data["messages"]:
357362
content = str(log_data["messages"][0]["content"])
358363
sneak_peak = content.replace("\n", "")
359364
else:
@@ -931,6 +936,9 @@ def get_notifications(self) -> str:
931936

932937
return " ".join(mentions)
933938

939+
async def set_title(self, title) -> None:
940+
user_id = match_user_id(self.channel.topic)
941+
await self.channel.edit(topic=f'Title: {title}\nUser ID: {user_id}')
934942

935943
class ThreadManager:
936944
"""Class that handles storing, finding and creating Modmail threads."""

core/utils.py

+21-2
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,28 @@ def cleanup_code(content: str) -> str:
216216
return content.strip("` \n")
217217

218218

219-
TOPIC_REGEX = re.compile(r"\bUser ID:\s*(\d{17,21})\b", flags=re.IGNORECASE)
219+
TOPIC_TITLE_REGEX = re.compile(r"\bTitle: (.*)\n(?:User ID: )\b", flags=re.IGNORECASE | re.DOTALL)
220+
TOPIC_UID_REGEX = re.compile(r"\bUser ID:\s*(\d{17,21})\b", flags=re.IGNORECASE)
220221

221222

223+
def match_title(text: str) -> int:
224+
"""
225+
Matches a title in the foramt of "Title: XXXX"
226+
227+
Parameters
228+
----------
229+
text : str
230+
The text of the user ID.
231+
232+
Returns
233+
-------
234+
Optional[str]
235+
The title if found
236+
"""
237+
match = TOPIC_TITLE_REGEX.search(text)
238+
if match is not None:
239+
return match.group(1)
240+
222241
def match_user_id(text: str) -> int:
223242
"""
224243
Matches a user ID in the format of "User ID: 12345".
@@ -233,7 +252,7 @@ def match_user_id(text: str) -> int:
233252
int
234253
The user ID if found. Otherwise, -1.
235254
"""
236-
match = TOPIC_REGEX.search(text)
255+
match = TOPIC_UID_REGEX.search(text)
237256
if match is not None:
238257
return int(match.group(1))
239258
return -1

0 commit comments

Comments
 (0)