implement channel linking in migrated messages

This commit is contained in:
rambros 2026-03-08 21:21:46 +05:30
parent 9a60759b7c
commit 7cf905f16f
3 changed files with 51 additions and 8 deletions

View file

@ -62,6 +62,7 @@ class DiscordReader:
self.guild: discord.Guild | None = None
self.client: discord.Client | None = None
self.role_map: Dict[int, str] = {}
self.channel_name_map: Dict[int, str] = {}
def _create_client(self):
intents = discord.Intents.default()
@ -98,6 +99,18 @@ class DiscordReader:
logger.error(f"Failed to fetch roles: {e}")
self.role_map = {}
# Pre-fetch channels via API
try:
channels = await self.guild.fetch_channels()
self.channel_name_map = {c.id: c.name for c in channels}
logger.debug(f"Pre-fetched {len(self.channel_name_map)} channels")
except discord.Forbidden:
logger.warning("403 Forbidden: Missing Access to fetch channels. Continuing without channel name mapping.")
self.channel_name_map = {}
except Exception as e:
logger.error(f"Failed to fetch channels: {e}")
self.channel_name_map = {}
async def validate(self) -> Dict[str, Any]:
"""Validates the token, server ID, intents, and permissions."""
results = {

View file

@ -7,7 +7,7 @@ from src.core.base import MigrationContext
logger = logging.getLogger(__name__)
def clean_mentions(content: str, guild, user_mentions=None, role_mentions=None, role_map=None, emoji_map=None) -> str:
def clean_mentions(content: str, guild, user_mentions=None, role_mentions=None, role_map=None, emoji_map=None, channel_map=None, discord_channel_map=None) -> str:
if not content or not guild:
return content
@ -54,8 +54,19 @@ def clean_mentions(content: str, guild, user_mentions=None, role_mentions=None,
def replace_channel(match):
cid = int(match.group(1))
# 1. Check if channel is mapped in state
if channel_map and str(cid) in channel_map:
return f"<#{channel_map[str(cid)]}>"
# 2. Fallback to name in backticks
# Try metadata map first (robust)
if discord_channel_map and cid in discord_channel_map:
return f"`#{discord_channel_map[cid]}`"
# Try cache
channel = guild.get_channel(cid)
return f"#{channel.name}" if channel else match.group(0)
return f"`{channel.name}`" if channel else f"<#{cid}>"
def replace_emoji(match):
animated = match.group(1) == "a"
@ -180,7 +191,9 @@ async def migrate_messages(
msg.mentions,
msg.role_mentions,
context.discord_reader.role_map,
context.state.emoji_map
context.state.emoji_map,
context.state.channel_map,
context.discord_reader.channel_name_map
)
# Process attachments
@ -209,7 +222,9 @@ async def migrate_messages(
snapshot.mentions if hasattr(snapshot, 'mentions') else None,
snapshot.role_mentions if hasattr(snapshot, 'role_mentions') else None,
context.discord_reader.role_map,
context.state.emoji_map
context.state.emoji_map,
context.state.channel_map,
context.discord_reader.channel_name_map
)
# Add snapshot attachments to the list to process
attachments_to_process.extend(snapshot.attachments)

View file

@ -7,7 +7,7 @@ from src.core.base import MigrationContext
logger = logging.getLogger(__name__)
def clean_mentions(content: str, guild, user_mentions=None, role_mentions=None, role_map=None, emoji_map=None) -> str:
def clean_mentions(content: str, guild, user_mentions=None, role_mentions=None, role_map=None, emoji_map=None, channel_map=None, discord_channel_map=None) -> str:
if not content or not guild:
return content
@ -54,8 +54,19 @@ def clean_mentions(content: str, guild, user_mentions=None, role_mentions=None,
def replace_channel(match):
cid = int(match.group(1))
# 1. Check if channel is mapped in state
if channel_map and str(cid) in channel_map:
return f"<#{channel_map[str(cid)]}>"
# 2. Fallback to name in backticks
# Try metadata map first (robust)
if discord_channel_map and cid in discord_channel_map:
return f"`#{discord_channel_map[cid]}`"
# Try cache
channel = guild.get_channel(cid)
return f"#{channel.name}" if channel else match.group(0)
return f"`{channel.name}`" if channel else f"<#{cid}>"
def replace_emoji(match):
animated = match.group(1) == "a"
@ -188,7 +199,9 @@ async def migrate_messages(
msg.mentions,
msg.role_mentions,
context.discord_reader.role_map,
context.state.emoji_map
context.state.emoji_map,
context.state.channel_map,
context.discord_reader.channel_name_map
)
# Process attachments
@ -213,7 +226,9 @@ async def migrate_messages(
snapshot.mentions if hasattr(snapshot, 'mentions') else None,
snapshot.role_mentions if hasattr(snapshot, 'role_mentions') else None,
context.discord_reader.role_map,
context.state.emoji_map
context.state.emoji_map,
context.state.channel_map,
context.discord_reader.channel_name_map
)
attachments_to_process.extend(snapshot.attachments)
logger.debug(f"Found forwarded snapshot content: {content[:50]}... and {len(snapshot.attachments)} attachments")