Skip to content

Update recipient thread close #3364

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<br>

<a href="#">
<img src="https://img.shields.io/badge/Latest%20Version-v4.1.0-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs=">
<img src="https://img.shields.io/badge/Latest%20Version-v4.1.1-7289da?style=for-the-badge&logo=data:image/gif;base64,R0lGODlhGAAYAPcAAAAAADQ+Yj5MdThCaEFOekNQfWt5e1lqfEdVhVpriVx1iVtsnFZpll1xlF1znFx5mGNtjGR7hWNzjGd5iWJunGNslmN0lGl1lGN5lWt7lWR0nGp1nWR5nGt8nHJ9l3J9jFxto1xtqlZqqF5zpF15pV10rVx5q1Z2ql1us150s114sV50uVd1smJupGNurGN0pGp1pGR6o2t7o2F0rml0rGR5rGt8q3J9pGNus2Fvu2Bzs2p2smR5s2t7tGF0u2N6vGp7u2l1uXJ+uGJ1wWV7w2l+xWl+yl5zwHWDiWyCmHODnHiGmHSLkW2CpGuEqnSCpHqMo3ODrHWKrXyMq3iHp3yTqGyEtWqFunKDs3uLtHSGvXSMvHuMu3eItnyTs3yTu3iUuW+RsV+ApmuCxG2Dy22LxnSMxHuMxHGGzXSLzXqLzXWFxXyTw3uSy3WSx26E0W+N2m+L1XKG03SL1XmL1HOL2HmL23WF2XiS1m+QyHOK4XmL4XaH4nGM5ImXm4WOlJSjnoOOq4OOpYSUrImXqJOcqYONt4OUtIybtIOUu4ycvImYt5OcuIyiqZekqYyiupOjvJurvJimtp+yvqKruae2ua23trLCucPHvIOMxoOUxIuaw4eYyJKbyISW1YiW0o2kyJWlxJqpxZWkzJury5aoxp6xxZ2zyZio1Jyy2Yuk0aOsyKOyxKOzzKy8zKq2yLO7xqOr1KSz1Ku706W026y73Ki21bK716u75LS95KSu4Zyx6bPDzLjGx63B2LPD1LTE3LvL3brI17/S2bbKzrTE47rF47zM5L3M67bH577R5L7R67zK8rjM8MLM3MPK1sTT3crU3MjW2dLZ2srUy8PN5MTO68nP68jL48TS5MnT5cbR68jS7M3b7Mva5dTb6MTO8srO8szF8MXR8snS8c3a8cnY+NXb9tDL7dnm6dzk8tro99Pq9uTp6+r17fr77eTr/efr+Oz09OXz/Ov0/e37/uj39fX19fX89fz+9vP1/fX9/f7//vr2/ODl4sK75yH5BAEAAAAALAAAAAAYABgAAAj/AAEAmFOnoMGDCAvGmRNHYMKHEOdIhEgRIcGKGDMeTJVO00WNBj194/frFik5IOvgqdaP371N26xpefORYq57/HI+s7Vtmy0eKCmmapcz575FPXt+SfHmociiRae1SroNWIoVTQ2uxAk15yJg1awl7ZSCaUE82uRxhTpt1TNXq0Ip2pSobIqCc0iVoqsI0ipXr1bhywfVXxYdiA3Sourz2dqc8lbNQJz4bDWqix73E7ZjhgrKOjYmvfWLbZcZqCdTPjjHGLdtibi2U5Q6NWiEqqq64ifvVe3at1nX2tTuWQ/QyIMfxHOGi+rkyeMklPMDuvWaBqlbj469IPUU2ykPCOw+53t4AAEBADs=">
</a>

<br>
Expand All @@ -24,7 +24,7 @@
</a>

<a href="https://patreon.com/kyber">
<img src="https://img.shields.io/badge/patreon-donate-orange.svg?style=for-the-badge&logo=Patreon" alt="Python 3.8">
<img src="https://img.shields.io/badge/patreon-donate-orange.svg?style=for-the-badge&logo=Patreon" alt="Patreon">
</a>

<a href="https://www.python.org/downloads/">
Expand Down Expand Up @@ -159,6 +159,13 @@ Discord Advice Center:
<a href='https://discord.gg/zmwZy5fd9v'>
<img height=100 src='https://i.imgur.com/1hrjcHd.png' style='margin:5px'>
</a>
<br>
<br>
Blacklight Promotions:
<br>
<a href='https://blacklightpromotions.online'>
<img height=100 src='https://i.imgur.com/yLgE6h6.png' style='margin:5px'>
</a>


Become a sponsor on [Patreon](https://patreon.com/kyber).
Expand Down
23 changes: 10 additions & 13 deletions bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,15 @@
)
from core.thread import ThreadManager
from core.time import human_timedelta
from core.utils import extract_block_timestamp, normalize_alias, parse_alias, truncate, tryint, human_join
from core.utils import (
extract_block_timestamp,
normalize_alias,
parse_alias,
truncate,
tryint,
human_join,
ThreadSelfCloseView,
)

logger = getLogger(__name__)

Expand Down Expand Up @@ -617,6 +625,7 @@ async def on_ready(self):
self.post_metadata.start()
self.autoupdate.start()
self.log_expiry.start()
self.add_view(ThreadSelfCloseView(self))
self._started = True

async def convert_emoji(self, name: str) -> str:
Expand Down Expand Up @@ -1248,19 +1257,7 @@ async def handle_reaction_events(self, payload):
return

reaction = payload.emoji
close_emoji = await self.convert_emoji(self.config["close_emoji"])
if from_dm:
if (
payload.event_type == "REACTION_ADD"
and message.embeds
and str(reaction) == str(close_emoji)
and self.config.get("recipient_thread_close")
):
ts = message.embeds[0].timestamp
if ts == thread.channel.created_at:
# the reacted message is the corresponding thread creation embed
# closing thread
return await thread.close(closer=user)
if (
message.author == self.user
and message.embeds
Expand Down
12 changes: 5 additions & 7 deletions core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ class ConfigManager:
# threads
"sent_emoji": "\N{WHITE HEAVY CHECK MARK}",
"blocked_emoji": "\N{NO ENTRY SIGN}",
"close_emoji": "\N{LOCK}",
"close_emoji": None,
"use_user_id_channel_name": False,
"use_timestamp_channel_name": False,
"use_nickname_channel_name": False,
"use_random_channel_name": False,
"recipient_thread_close": False,
"recipient_thread_close_button_label": None,
"recipient_thread_close_button_style": "red",
"thread_show_roles": True,
"thread_show_account_age": True,
"thread_show_join_age": True,
Expand All @@ -65,7 +67,7 @@ class ConfigManager:
"thread_creation_response": "The staff team will get back to you as soon as possible.",
"thread_creation_footer": "Your message has been sent",
"thread_contact_silently": False,
"thread_self_closable_creation_footer": "Click the lock to close the thread",
"thread_self_closable_creation_footer": "Click the button to close the thread",
"thread_creation_contact_title": "New Thread",
"thread_creation_self_contact_response": "You have opened a Modmail thread.",
"thread_creation_contact_response": "{creator.name} has opened a Modmail thread.",
Expand Down Expand Up @@ -230,11 +232,7 @@ class ConfigManager:
"registry_plugins_only",
}

enums = {
"dm_disabled": DMDisabled,
"status": discord.Status,
"activity_type": discord.ActivityType,
}
enums = {"dm_disabled": DMDisabled, "status": discord.Status, "activity_type": discord.ActivityType}

force_str = {"command_permissions", "level_permissions"}

Expand Down
33 changes: 28 additions & 5 deletions core/config_help.json
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,8 @@
]
},
"close_emoji": {
"default": "🔒",
"description": "This is the emoji the recipient can click to close a thread themselves. The emoji is automatically added to the `thread_creation_response` embed.",
"default": "None",
"description": "This is the emoji for the close button the recipient can click to close a thread themselves. The emoji (attached to the button) is automatically added to the `thread_creation_response` embed.",
"examples": [
"`{prefix}config set close_emoji 👍‍`"
],
Expand All @@ -297,14 +297,37 @@
},
"recipient_thread_close": {
"default": "Disabled",
"description": "Setting this configuration will allow recipients to use the `close_emoji` to close the thread themselves.",
"description": "Setting this configuration will allow recipients to close threads by themselves via a button.",
"examples": [
"`{prefix}config set recipient_thread_close yes`",
"`{prefix}config set recipient_thread_close no`"
],
"notes": [
"The close emoji is dictated by the configuration `close_emoji`.",
"See also: `close_emoji`."
"The button attached to the `thread_creation_response` can have set a custom label, emoji or even both.",
"See also: `close_emoji`, `recipient_thread_close_button_label`, `recipient_thread_close_button_style`."
]
},
"recipient_thread_close_button_label": {
"default": "None",
"description": "This configuration changes the label of the button for the `recipient_thread_close` feature.",
"examples": [
"`{prefix}config set recipient_thread_close_button_label Your label`"
],
"notes": [
"The label cannot exceed 80 characters.",
"See also: `recipient_thread_close`, `close_emoji`, `recipient_thread_close_button_style`."
]
},
"recipient_thread_close_button_style": {
"default": "red",
"description": "This configuration changes the style of the button for the `recipient_thread_close` feature.",
"examples": [
"`{prefix}config set recipient_thread_close_button_style green`",
"`{prefix}config set recipient_thread_close_button_style blurple`"
],
"notes": [
"The style is limited by discord to the following colors: blurple, green, red, gray.",
"See also: `recipient_thread_close`, `close_emoji`, `recipient_thread_close_button_label`."
]
},
"thread_show_roles": {
Expand Down
31 changes: 27 additions & 4 deletions core/thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
AcceptButton,
DenyButton,
ConfirmThreadCreationView,
ThreadSelfCloseView,
DummyParam,
)

Expand Down Expand Up @@ -239,11 +240,33 @@ async def send_recipient_genesis_message():

if creator is None or creator == recipient:
msg = await recipient.send(embed=embed)

if recipient_thread_close:
close_emoji = self.bot.config["close_emoji"]
close_label = self.bot.config["recipient_thread_close_button_label"]
if (
recipient_thread_close
and self.bot.config["recipient_thread_close_button_style"].lower()
in ["red", "green", "blurple", "gray"]
and (close_emoji is not None and close_label is not None)
):
close_emoji = self.bot.config["close_emoji"]
close_emoji = await self.bot.convert_emoji(close_emoji)
await self.bot.add_reaction(msg, close_emoji)
if close_emoji:
close_emoji = await self.bot.convert_emoji(close_emoji)

button_style = discord.ButtonStyle(
int(
discord.ButtonStyle[
self.bot.config["recipient_thread_close_button_style"].lower()
]
)
)
view = ThreadSelfCloseView(
button_style,
close_label,
close_emoji,
self.bot,
)
await msg.edit(view=view)
# await self.bot.add_reaction(msg, close_emoji)

async def send_persistent_notes():
notes = await self.bot.api.find_notes(self.recipient)
Expand Down
36 changes: 36 additions & 0 deletions core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"AcceptButton",
"DenyButton",
"ConfirmThreadCreationView",
"ThreadSelfCloseView",
"DummyParam",
]

Expand Down Expand Up @@ -599,6 +600,41 @@ def __init__(self):
self.value = None


class ThreadSelfCloseView(discord.ui.View):
def __init__(
self,
style: typing.Optional[discord.ButtonStyle] = None,
label: typing.Optional[str] = None,
emoji: typing.Optional[str] = None,
bot: typing.Any = None,
):
super().__init__(timeout=None)
self.bot = bot

self.self_close_button.label = label
self.self_close_button.style = style
self.self_close_button.emoji = emoji

@discord.ui.button(label="default", style=discord.ButtonStyle.secondary, custom_id="SelfCloseView")
async def self_close_button(self, interaction: discord.Interaction, button: discord.ui.Button):
await interaction.response.defer(ephemeral=False, thinking=True)
thread = await self.bot.threads.find(recipient=interaction.user)
if not thread:
error_embed = discord.Embed(
description="A thread could not be found.", color=self.bot.config["error_color"]
)
return await interaction.followup.send(embed=error_embed)

message = self.bot.config["thread_self_close_response"]
embed = discord.Embed(
title="Thread closed", description=message, color=self.bot.config["error_color"]
)
await thread.close(closer=interaction.user, silent=True)
self.self_close_button.disabled = True
await interaction.message.edit(view=self)
await interaction.followup.send(embed=embed)


class DummyParam:
"""
A dummy parameter that can be used for MissingRequiredArgument.
Expand Down
Loading