Skip to content

Commit

Permalink
Revert "Revert "?contact accepts multiple users, or role modmail-dev#…
Browse files Browse the repository at this point in the history
…3082""

This reverts commit 8c4d413.
  • Loading branch information
Erisa authored Oct 1, 2022
1 parent c148a77 commit e2a0e44
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 63 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ v3.10 adds group conversations while resolving other bugs and QOL changes. It is
### Breaking

- `Thread.recipient` (`str`) is now `Thread.recipients` (`List[str]`).
- `Thread.reply` now returns mod_message, user_message1, user_message2... It is no longer limited at a size 2 tuple.
- `Thread.reply` now returns `mod_message, user_message1, user_message2`... It is no longer limited at a size 2 tuple.

### Added

- Ability to have group conversations. ([GH #143](https://github.com/kyb3r/modmail/issues/143))
- Ability to have group conversations with up to 5 users. ([GH #143](https://github.com/kyb3r/modmail/issues/143))
- Snippets are invoked case insensitively. ([GH #3077](https://github.com/kyb3r/modmail/issues/3077), [PR #3080](https://github.com/kyb3r/modmail/pull/3080))
- Default tags now use top hoisted role. ([GH #3014](https://github.com/kyb3r/modmail/issues/3014))
- New thread-related config - `thread_show_roles`, `thread_show_account_age`, `thread_show_join_age`, `thread_cancelled`, `thread_creation_contact_title`, `thread_creation_self_contact_response`, `thread_creation_contact_response`. ([GH #3072](https://github.com/kyb3r/modmail/issues/3072))
Expand Down
150 changes: 92 additions & 58 deletions cogs/modmail.py
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,16 @@ async def adduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, str
ctx.command.reset_cooldown(ctx)
return

if len(users + ctx.thread.recipients) > 5:
em = discord.Embed(
title="Error",
description="Only 5 users are allowed in a group conversation",
color=self.bot.error_color,
)
await ctx.send(embed=em)
ctx.command.reset_cooldown(ctx)
return

if not silent:
description = self.bot.formatter.format(
self.bot.config["private_added_to_group_response"], moderator=ctx.author
Expand Down Expand Up @@ -1327,14 +1337,14 @@ async def edit(self, ctx, message_id: Optional[int] = None, *, message: str):
@checks.has_permissions(PermissionLevel.REGULAR)
async def selfcontact(self, ctx):
"""Creates a thread with yourself"""
await ctx.invoke(self.contact, user=ctx.author)
await ctx.invoke(self.contact, users=[ctx.author])

@commands.command(usage="<user> [category] [options]")
@checks.has_permissions(PermissionLevel.SUPPORTER)
async def contact(
self,
ctx,
user: Union[discord.Member, discord.User],
users: commands.Greedy[Union[discord.Member, discord.User, discord.Role]],
*,
category: Union[SimilarCategoryConverter, str] = None,
manual_trigger=True,
Expand All @@ -1346,7 +1356,8 @@ async def contact(
will be created in that specified category.
`category`, if specified, may be a category ID, mention, or name.
`user` may be a user ID, mention, or name.
`users` may be a user ID, mention, or name. If multiple users are specified, a group thread will start.
A maximum of 5 users are allowed.
`options` can be `silent` or `silently`.
"""
silent = False
Expand All @@ -1371,74 +1382,97 @@ async def contact(
if isinstance(category, str):
category = None

if user.bot:
embed = discord.Embed(color=self.bot.error_color, description="Cannot start a thread with a bot.")
return await ctx.send(embed=embed, delete_after=3)
errors = []
for u in list(users):
if isinstance(u, discord.Role):
users += u.members
users.remove(u)

for u in list(users):
exists = await self.bot.threads.find(recipient=u)
if exists:
errors.append(f"A thread for {u} already exists.")
if exists.channel:
errors[-1] += f" in {exists.channel.mention}"
errors[-1] += "."
users.remove(u)
elif u.bot:
errors.append(f"{u} is a bot, cannot add to thread.")
users.remove(u)
elif await self.bot.is_blocked(u):
ref = f"{u.mention} is" if ctx.author != u else "You are"
errors.append(f"{ref} currently blocked from contacting {self.bot.user.name}.")
users.remove(u)

exists = await self.bot.threads.find(recipient=user)
if exists:
desc = "A thread for this user already exists"
if exists.channel:
desc += f" in {exists.channel.mention}"
desc += "."
embed = discord.Embed(color=self.bot.error_color, description=desc)
await ctx.channel.send(embed=embed, delete_after=3)
if len(users) > 5:
errors.append("Group conversations only support 5 users.")
users = []

else:
creator = ctx.author if manual_trigger else user
if await self.bot.is_blocked(user):
if not manual_trigger: # react to contact
return
if errors or not users:
if not users:
# no users left
title = "Thread not created"
else:
title = None

ref = f"{user.mention} is" if creator != user else "You are"
embed = discord.Embed(
color=self.bot.error_color,
description=f"{ref} currently blocked from contacting {self.bot.user.name}.",
)
return await ctx.send(embed=embed)
if manual_trigger: # not react to contact
embed = discord.Embed(title=title, color=self.bot.error_color, description="\n".join(errors))
await ctx.send(embed=embed, delete_after=10)

thread = await self.bot.threads.create(
recipient=user,
creator=creator,
category=category,
manual_trigger=manual_trigger,
)
if thread.cancelled:
if not users:
# end
return

if self.bot.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS):
logger.info("Contacting user %s when Modmail DM is disabled.", user)
creator = ctx.author if manual_trigger else users[0]

if not silent and not self.bot.config.get("thread_contact_silently"):
if creator.id == user.id:
description = self.bot.config["thread_creation_self_contact_response"]
else:
description = self.bot.formatter.format(
self.bot.config["thread_creation_contact_response"], creator=creator
)
thread = await self.bot.threads.create(
recipient=users[0],
creator=creator,
category=category,
manual_trigger=manual_trigger,
)

em = discord.Embed(
title=self.bot.config["thread_creation_contact_title"],
description=description,
color=self.bot.main_color,
if thread.cancelled:
return

if self.bot.config["dm_disabled"] in (DMDisabled.NEW_THREADS, DMDisabled.ALL_THREADS):
logger.info("Contacting user %s when Modmail DM is disabled.", users[0])

if not silent and not self.bot.config.get("thread_contact_silently"):
if creator.id == users[0].id:
description = self.bot.config["thread_creation_self_contact_response"]
else:
description = self.bot.formatter.format(
self.bot.config["thread_creation_contact_response"], creator=creator
)
if self.bot.config["show_timestamp"]:
em.timestamp = datetime.utcnow()
em.set_footer(text=f"{creator}", icon_url=creator.avatar_url)
await user.send(embed=em)

embed = discord.Embed(
title="Created Thread",
description=f"Thread started by {creator.mention} for {user.mention}.",
em = discord.Embed(
title=self.bot.config["thread_creation_contact_title"],
description=description,
color=self.bot.main_color,
)
await thread.wait_until_ready()
await thread.channel.send(embed=embed)
if self.bot.config["show_timestamp"]:
em.timestamp = datetime.utcnow()
em.set_footer(text=f"{creator}", icon_url=creator.avatar_url)

for u in users:
await u.send(embed=em)

embed = discord.Embed(
title="Created Thread",
description=f"Thread started by {creator.mention} for {', '.join(u.mention for u in users)}.",
color=self.bot.main_color,
)
await thread.wait_until_ready()

if users[1:]:
await thread.add_users(users[1:])

await thread.channel.send(embed=embed)

if manual_trigger:
sent_emoji, _ = await self.bot.retrieve_emoji()
await self.bot.add_reaction(ctx.message, sent_emoji)
await asyncio.sleep(5)
if manual_trigger:
sent_emoji, _ = await self.bot.retrieve_emoji()
await self.bot.add_reaction(ctx.message, sent_emoji)

@commands.group(invoke_without_command=True)
@checks.has_permissions(PermissionLevel.MODERATOR)
Expand Down
6 changes: 3 additions & 3 deletions cogs/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ async def mention(self, ctx, *user_or_role: Union[discord.Role, discord.Member,
option = user_or_role[0].lower()
if option == "disable":
embed = discord.Embed(
description=f"Disabled mention on thread creation.",
description="Disabled mention on thread creation.",
color=self.bot.main_color,
)
self.bot.config["mention"] = None
Expand Down Expand Up @@ -892,7 +892,7 @@ async def config_help(self, ctx, key: str.lower = None):
description=f"`{key}` is an invalid key.",
)
if closest:
embed.add_field(name=f"Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest))
embed.add_field(name="Perhaps you meant:", value="\n".join(f"`{x}`" for x in closest))
return await ctx.send(embed=embed)

config_help = self.bot.config.config_help
Expand Down Expand Up @@ -1861,7 +1861,7 @@ async def autotrigger_test(self, ctx, *, text):
embed = discord.Embed(
title="Keyword Not Found",
color=self.bot.error_color,
description=f"No autotrigger keyword found.",
description="No autotrigger keyword found.",
)
return await ctx.send(embed=embed)

Expand Down

0 comments on commit e2a0e44

Please sign in to comment.