-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmessage_edit.py
More file actions
202 lines (164 loc) · 9.26 KB
/
message_edit.py
File metadata and controls
202 lines (164 loc) · 9.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
import discord
import helpers
import database
from header_state import header_state
from logger_config import get_logger
logger = get_logger(__name__)
async def handle_message_edit(bot, before: discord.Message, after: discord.Message):
"""Handles edited messages and updates all linked messages."""
# Ignore edits from the bot itself
if after.author == bot.user:
return
# Ignore edits from webhooks
if after.webhook_id:
return
# Only handle edits if the content actually changed
if before.content == after.content:
return
# Ignore if the edited message has no content (e.g., only embeds)
if not after.content and not before.content:
return
logger.info(f"Handling message edit from {after.author} in {after.guild.name}#{after.channel.name}")
# Check if the edited message is in a thread
if isinstance(after.channel, discord.Thread):
if _is_forum_thread(after.channel):
await handle_forum_thread_message_edit(bot, before, after)
else:
await handle_thread_message_edit(bot, before, after)
else:
await handle_channel_message_edit(bot, before, after)
def _is_forum_thread(thread: discord.Thread) -> bool:
parent = thread.parent
if parent is None:
return False
if isinstance(parent, discord.ForumChannel):
return True
return getattr(parent, "type", None) == discord.ChannelType.forum
async def handle_channel_message_edit(bot, before: discord.Message, after: discord.Message):
"""Handles edited messages in regular channels and updates all linked messages."""
channel_id = str(after.channel.id)
target_channel_ids = helpers.find_linked_channels(channel_id)
if target_channel_ids is None:
logger.debug(f"No linked channels found for channel {channel_id}")
return
# Find the message group entry for the edited message
group_name = helpers.get_group_name(channel_id)
message_entry = database.get_message_group_entry_by_message_id(after.id, group_name)
if not message_entry:
logger.warning(f"No message group entry found for edited message {after.id}")
return
logger.info(f"Updating edited message in {len(target_channel_ids)} linked channels")
# Prepare shared header parts; whether to include a header is decided per linked message.
guild_name = after.guild.name if after.guild else "Unknown Guild"
channel_group_len = len(target_channel_ids)
edited_count = 0
# Update the message in each linked channel
for entry in message_entry:
# Skip the original message entry
if entry["guild_id"] == helpers.get_guild_id_from_channel_id(channel_id) and entry["channel_id"] == channel_id:
continue
target_channel = bot.get_channel(int(entry["channel_id"]))
if target_channel:
try:
# Fetch the linked message and edit it
linked_message = await target_channel.fetch_message(int(entry["message_id"]))
include_header = header_state.content_has_header(linked_message.content or "")
header = helpers.form_header(after, guild_name, channel_group_len) if include_header else ""
new_msg = helpers.form_message_text(header, after.content)
await linked_message.edit(content=new_msg)
edited_count += 1
logger.debug(f"Updated message in {target_channel.guild.name}#{target_channel.name}")
except discord.NotFound:
logger.warning(f"Linked message {entry['message_id']} not found in {target_channel.guild.name}#{target_channel.name}")
except discord.Forbidden:
logger.error(f"No permission to edit message in {target_channel.guild.name}#{target_channel.name}")
except Exception as e:
logger.error(f"Failed to edit message in {target_channel.guild.name}#{target_channel.name}: {e}")
else:
logger.error(f"Target channel with ID {entry['channel_id']} not found")
logger.info(f"Successfully updated {edited_count} linked messages")
async def handle_thread_message_edit(bot, before: discord.Message, after: discord.Message):
"""Handles edited messages in threads and updates all linked messages."""
parent_channel_id = str(after.channel.parent_id)
target_channel_ids = helpers.find_linked_channels(parent_channel_id)
if target_channel_ids is None:
logger.debug(f"No linked channels found for parent channel {parent_channel_id}")
return
# Find the message group entry for the edited message
group_name = helpers.get_group_name(parent_channel_id)
message_entry = database.get_message_group_entry_by_message_id(after.id, group_name)
if not message_entry:
logger.warning(f"No message group entry found for edited thread message {after.id}")
return
logger.info(f"Updating edited thread message in {len(target_channel_ids)} linked channels")
# Form new header pieces; include flag is inferred from stored message content.
guild_name = after.guild.name if after.guild else "Unknown Guild"
channel_group_len = len(target_channel_ids)
edited_count = 0
# Update the message in each linked thread
for entry in message_entry:
# Skip the original message entry
if (entry["guild_id"] == helpers.get_guild_id_from_channel_id(parent_channel_id) and
entry["channel_id"] == parent_channel_id and
entry.get("thread_id") == str(after.channel.id)):
continue
target_channel = bot.get_channel(int(entry["channel_id"]))
if target_channel and "thread_id" in entry:
try:
# Get the parent message to access the thread
parent_message = await target_channel.fetch_message(int(entry["thread_id"]))
if parent_message.thread:
# Fetch the linked message in the thread and edit it
linked_message = await parent_message.thread.fetch_message(int(entry["message_id"]))
include_header = header_state.content_has_header(linked_message.content or "")
header = helpers.form_header(after, guild_name, channel_group_len) if include_header else ""
new_msg = helpers.form_message_text(header, after.content)
await linked_message.edit(content=new_msg)
edited_count += 1
logger.debug(f"Updated thread message in {target_channel.guild.name}#{target_channel.name}")
else:
logger.warning(f"Thread not found for parent message {entry['thread_id']}")
except discord.NotFound:
logger.warning(f"Linked thread message {entry['message_id']} not found")
except discord.Forbidden:
logger.error(f"No permission to edit thread message in {target_channel.guild.name}#{target_channel.name}")
except Exception as e:
logger.error(f"Failed to edit thread message in {target_channel.guild.name}#{target_channel.name}: {e}")
else:
logger.error(f"Target channel with ID {entry['channel_id']} not found or no thread_id in entry")
logger.info(f"Successfully updated {edited_count} linked thread messages")
async def handle_forum_thread_message_edit(bot, before: discord.Message, after: discord.Message):
"""Handles edited messages in forum threads and updates all linked messages."""
parent_channel_id = str(after.channel.parent_id)
target_channel_ids = helpers.find_linked_channels(parent_channel_id)
if target_channel_ids is None:
logger.debug(f"No linked channels found for parent channel {parent_channel_id}")
return
group_name = helpers.get_group_name(parent_channel_id)
message_entry = database.get_message_group_entry_by_message_id(after.id, group_name)
if not message_entry:
logger.warning(f"No message group entry found for edited forum message {after.id}")
return
guild_name = after.guild.name if after.guild else "Unknown Guild"
channel_group_len = len(target_channel_ids)
edited_count = 0
for entry in message_entry:
if entry.get("thread_id") == str(after.channel.id):
continue
target_thread = bot.get_channel(int(entry["thread_id"]))
if not target_thread:
try:
target_thread = await bot.fetch_channel(int(entry["thread_id"]))
except Exception as e:
logger.error(f"Failed to fetch forum thread {entry['thread_id']}: {e}")
continue
try:
linked_message = await target_thread.fetch_message(int(entry["message_id"]))
include_header = header_state.content_has_header(linked_message.content or "")
header = helpers.form_header(after, guild_name, channel_group_len) if include_header else ""
new_msg = helpers.form_message_text(header, after.content)
await linked_message.edit(content=new_msg)
edited_count += 1
except Exception as e:
logger.error(f"Failed to edit forum thread message {entry['message_id']}: {e}")
logger.info(f"Successfully updated {edited_count} linked forum messages")