feat: add reply support with blockquote formatting

Fetch replied message content/author when Discord message type is REPLY,
display as Telegram blockquote with link to original.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
devilreef 2026-01-10 18:49:50 +06:00
parent 790abfd692
commit 594b0e7a48
3 changed files with 38 additions and 2 deletions

View file

@ -14,6 +14,12 @@ interface MatchResult {
type: 'channel' | 'role'
}
interface ReplyInfo {
author: string
content: string
messageLink: string
}
async function handleMessage(message: Message): Promise<void> {
if (!message.guild)
return
@ -55,6 +61,22 @@ async function handleMessage(message: Message): Promise<void> {
const messageLink = `https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.id}`
const channelName = 'name' in message.channel ? (message.channel.name ?? 'unknown') : 'DM'
// Fetch replied message if this is a reply
let replyTo: ReplyInfo | undefined
if (message.type === 'REPLY' && message.reference?.messageId) {
try {
const repliedMessage = await message.channel.messages.fetch(message.reference.messageId)
replyTo = {
author: repliedMessage.author.displayName ?? repliedMessage.author.username,
content: repliedMessage.content,
messageLink: `https://discord.com/channels/${message.reference.guildId}/${message.reference.channelId}/${message.reference.messageId}`,
}
}
catch {
// Replied message deleted or inaccessible
}
}
try {
await forwardMessage({
topicId: match.topicId,
@ -64,6 +86,7 @@ async function handleMessage(message: Message): Promise<void> {
content: message.content,
attachments,
messageLink,
replyTo,
})
console.log(`Forwarded message from ${message.author.tag} (${match.type}: ${match.label}) in ${serverConfig.name}`)
}

View file

@ -4,10 +4,18 @@ import { config } from '../config.js'
import { telegram } from './client.js'
export async function forwardMessage(opts: ForwardMessageOptions): Promise<void> {
const { topicId, author, role, channel, content, attachments, messageLink } = opts
const { topicId, author, role, channel, content, attachments, messageLink, replyTo } = opts
let text = ''
// Add reply context as blockquote if present
if (replyTo) {
const replyContent = replyTo.content || '(no text)'
text += `<blockquote><b>${escapeHtml(replyTo.author)}</b>\n${escapeHtml(replyContent)}\n<a href="${replyTo.messageLink}">View original</a></blockquote>\n\n`
}
const roleText = role ? ` (${escapeHtml(role)})` : ''
const text = `<b>${escapeHtml(author)}</b>${roleText} in <code>#${escapeHtml(channel)}</code>\n${escapeHtml(content)}\n\n<a href="${messageLink}">Jump to message</a>`
text += `<b>${escapeHtml(author)}</b>${roleText} in <code>#${escapeHtml(channel)}</code>\n${escapeHtml(content)}\n\n<a href="${messageLink}">Jump to message</a>`
// Enable link preview only if content has URLs (not just the discord jump link)
const hasLinks = /https?:\/\/\S+/i.test(content)

View file

@ -32,6 +32,11 @@ export interface ForwardMessageOptions {
content: string
attachments: AttachmentInfo[]
messageLink: string
replyTo?: {
author: string
content: string
messageLink: string
}
}
export interface AttachmentInfo {