Skip to content

Commit e44fb12

Browse files
committed
plain_snippets, ?fpareply and ?fpreply, resolves #3083
1 parent 13a22cf commit e44fb12

File tree

5 files changed

+85
-26
lines changed

5 files changed

+85
-26
lines changed

CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ however, insignificant breaking changes do not guarantee a major version bump, s
1616
### Added
1717

1818
- `use_hoisted_top_role` config to use change how default mod tags work, see `v3.10.0#Added` for details. ([PR #3093](https://github.com/kyb3r/modmail/pull/3093))
19-
- `require_close_reason` to require a reason to close a thread. ([GH #3107](https://github.com/kyb3r/modmail/issues/3107))
19+
- `require_close_reason` config to require a reason to close a thread. ([GH #3107](https://github.com/kyb3r/modmail/issues/3107))
20+
- `plain_snippets` config to force all snippets to be plain. ([GH #3083](https://github.com/kyb3r/modmail/issues/3083))
21+
- `?fpareply` and `?fpreply` to reply to messages with variables plainly.
2022

2123
### Improved
2224

bot.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -1144,10 +1144,12 @@ async def process_commands(self, message):
11441144
cmd = cmd.lower()
11451145
if cmd in self.snippets:
11461146
snippet = self.snippets[cmd]
1147+
modifiers = "f"
1148+
if self.config["plain_snippets"]:
1149+
modifiers += "p"
11471150
if self.config["anonymous_snippets"]:
1148-
message.content = f"{self.prefix}fareply {snippet}"
1149-
else:
1150-
message.content = f"{self.prefix}freply {snippet}"
1151+
modifiers += "a"
1152+
message.content = f"{self.prefix}{modifiers}reply {snippet}"
11511153

11521154
ctxs = await self.get_contexts(message)
11531155
for ctx in ctxs:

cogs/modmail.py

+64-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import asyncio
2-
from asyncio import tasks
32
import re
43
from datetime import datetime
54
from itertools import zip_longest
@@ -739,7 +738,7 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str
739738
ctx.command.reset_cooldown(ctx)
740739
return
741740

742-
tasks = []
741+
to_exec = []
743742
if not silent:
744743
description = self.bot.formatter.format(
745744
self.bot.config["private_added_to_group_response"], moderator=ctx.author
@@ -753,7 +752,7 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str
753752
em.timestamp = discord.utils.utcnow()
754753
em.set_footer(text=str(ctx.author), icon_url=ctx.author.display_avatar.url)
755754
for u in users:
756-
tasks.append(u.send(embed=em))
755+
to_exec.append(u.send(embed=em))
757756

758757
description = self.bot.formatter.format(
759758
self.bot.config["public_added_to_group_response"],
@@ -771,11 +770,11 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str
771770

772771
for i in ctx.thread.recipients:
773772
if i not in users:
774-
tasks.append(i.send(embed=em))
773+
to_exec.append(i.send(embed=em))
775774

776775
await ctx.thread.add_users(users)
777-
if tasks:
778-
await asyncio.gather(*tasks)
776+
if to_exec:
777+
await asyncio.gather(*to_exec)
779778

780779
sent_emoji, _ = await self.bot.retrieve_emoji()
781780
await self.bot.add_reaction(ctx.message, sent_emoji)
@@ -832,7 +831,7 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role,
832831
ctx.command.reset_cooldown(ctx)
833832
return
834833

835-
tasks = []
834+
to_exec = []
836835
if not silent:
837836
description = self.bot.formatter.format(
838837
self.bot.config["private_removed_from_group_response"], moderator=ctx.author
@@ -846,7 +845,7 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role,
846845
em.timestamp = discord.utils.utcnow()
847846
em.set_footer(text=str(ctx.author), icon_url=ctx.author.display_avatar.url)
848847
for u in users:
849-
tasks.append(u.send(embed=em))
848+
to_exec.append(u.send(embed=em))
850849

851850
description = self.bot.formatter.format(
852851
self.bot.config["public_removed_from_group_response"],
@@ -864,11 +863,11 @@ async def removeuser(self, ctx, *users_arg: Union[discord.Member, discord.Role,
864863

865864
for i in ctx.thread.recipients:
866865
if i not in users:
867-
tasks.append(i.send(embed=em))
866+
to_exec.append(i.send(embed=em))
868867

869868
await ctx.thread.remove_users(users)
870-
if tasks:
871-
await asyncio.gather(*tasks)
869+
if to_exec:
870+
await asyncio.gather(*to_exec)
872871

873872
sent_emoji, _ = await self.bot.retrieve_emoji()
874873
await self.bot.add_reaction(ctx.message, sent_emoji)
@@ -919,7 +918,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role,
919918
ctx.command.reset_cooldown(ctx)
920919
return
921920

922-
tasks = []
921+
to_exec = []
923922
if not silent:
924923
em = discord.Embed(
925924
title=self.bot.config["private_added_to_group_title"],
@@ -941,7 +940,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role,
941940
em.set_footer(text=name, icon_url=avatar_url)
942941

943942
for u in users:
944-
tasks.append(u.send(embed=em))
943+
to_exec.append(u.send(embed=em))
945944

946945
description = self.bot.formatter.format(
947946
self.bot.config["public_added_to_group_description_anon"],
@@ -958,11 +957,11 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role,
958957

959958
for i in ctx.thread.recipients:
960959
if i not in users:
961-
tasks.append(i.send(embed=em))
960+
to_exec.append(i.send(embed=em))
962961

963962
await ctx.thread.add_users(users)
964-
if tasks:
965-
await asyncio.gather(*tasks)
963+
if to_exec:
964+
await asyncio.gather(*to_exec)
966965

967966
sent_emoji, _ = await self.bot.retrieve_emoji()
968967
await self.bot.add_reaction(ctx.message, sent_emoji)
@@ -1008,7 +1007,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro
10081007
ctx.command.reset_cooldown(ctx)
10091008
return
10101009

1011-
tasks = []
1010+
to_exec = []
10121011
if not silent:
10131012
em = discord.Embed(
10141013
title=self.bot.config["private_removed_from_group_title"],
@@ -1030,7 +1029,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro
10301029
em.set_footer(text=name, icon_url=avatar_url)
10311030

10321031
for u in users:
1033-
tasks.append(u.send(embed=em))
1032+
to_exec.append(u.send(embed=em))
10341033

10351034
description = self.bot.formatter.format(
10361035
self.bot.config["public_removed_from_group_description_anon"],
@@ -1047,11 +1046,11 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro
10471046

10481047
for i in ctx.thread.recipients:
10491048
if i not in users:
1050-
tasks.append(i.send(embed=em))
1049+
to_exec.append(i.send(embed=em))
10511050

10521051
await ctx.thread.remove_users(users)
1053-
if tasks:
1054-
await asyncio.gather(*tasks)
1052+
if to_exec:
1053+
await asyncio.gather(*to_exec)
10551054

10561055
sent_emoji, _ = await self.bot.retrieve_emoji()
10571056
await self.bot.add_reaction(ctx.message, sent_emoji)
@@ -1253,6 +1252,50 @@ async def fareply(self, ctx, *, msg: str = ""):
12531252
async with ctx.typing():
12541253
await ctx.thread.reply(ctx.message, anonymous=True)
12551254

1255+
@commands.command(aliases=["formatplainreply"])
1256+
@checks.has_permissions(PermissionLevel.SUPPORTER)
1257+
@checks.thread_only()
1258+
async def fpreply(self, ctx, *, msg: str = ""):
1259+
"""
1260+
Reply to a Modmail thread with variables and a plain message.
1261+
1262+
Works just like `{prefix}areply`, however with the addition of three variables:
1263+
- `{{channel}}` - the `discord.TextChannel` object
1264+
- `{{recipient}}` - the `discord.User` object of the recipient
1265+
- `{{author}}` - the `discord.User` object of the author
1266+
1267+
Supports attachments and images as well as
1268+
automatically embedding image URLs.
1269+
"""
1270+
msg = self.bot.formatter.format(
1271+
msg, channel=ctx.channel, recipient=ctx.thread.recipient, author=ctx.message.author
1272+
)
1273+
ctx.message.content = msg
1274+
async with ctx.typing():
1275+
await ctx.thread.reply(ctx.message, plain=True)
1276+
1277+
@commands.command(aliases=["formatplainanonreply"])
1278+
@checks.has_permissions(PermissionLevel.SUPPORTER)
1279+
@checks.thread_only()
1280+
async def fpareply(self, ctx, *, msg: str = ""):
1281+
"""
1282+
Anonymously reply to a Modmail thread with variables and a plain message.
1283+
1284+
Works just like `{prefix}areply`, however with the addition of three variables:
1285+
- `{{channel}}` - the `discord.TextChannel` object
1286+
- `{{recipient}}` - the `discord.User` object of the recipient
1287+
- `{{author}}` - the `discord.User` object of the author
1288+
1289+
Supports attachments and images as well as
1290+
automatically embedding image URLs.
1291+
"""
1292+
msg = self.bot.formatter.format(
1293+
msg, channel=ctx.channel, recipient=ctx.thread.recipient, author=ctx.message.author
1294+
)
1295+
ctx.message.content = msg
1296+
async with ctx.typing():
1297+
await ctx.thread.reply(ctx.message, anonymous=True, plain=True)
1298+
12561299
@commands.command(aliases=["anonreply", "anonymousreply"])
12571300
@checks.has_permissions(PermissionLevel.SUPPORTER)
12581301
@checks.thread_only()

core/config.py

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class ConfigManager:
9191
"silent_alert_on_mention": False,
9292
"show_timestamp": True,
9393
"anonymous_snippets": False,
94+
"plain_snippets": False,
9495
"require_close_reason": False,
9596
# group conversations
9697
"private_added_to_group_title": "New Thread (Group)",
@@ -207,6 +208,7 @@ class ConfigManager:
207208
"update_notifications",
208209
"thread_contact_silently",
209210
"anonymous_snippets",
211+
"plain_snippets",
210212
"require_close_reason",
211213
"recipient_thread_close",
212214
"thread_show_roles",

core/config_help.json

+11-1
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,17 @@
794794
"`{prefix}config set anonymous_snippets yes`"
795795
],
796796
"notes": [
797-
"See also: `anon_avatar_url`, `anon_tag`."
797+
"See also: `anon_avatar_url`, `anon_tag`, `plain_snippets`."
798+
]
799+
},
800+
"plain_snippets": {
801+
"default": "No",
802+
"description": "Sends snippets with a plain interface.",
803+
"examples":[
804+
"`{prefix}config set plain_snippets yes`"
805+
],
806+
"notes": [
807+
"See also: `anonymous_snippets`."
798808
]
799809
},
800810
"require_close_reason": {

0 commit comments

Comments
 (0)