mirror Discord replies as replies on X and bluesky

Replying to a message on the watched channel now posts the reply as a
reply to the posts that message produced, instead of as a standalone
post.

Discord tells us the parent through MessageReference, and the store maps
it back to the Ref each output returned; that Ref rides along on the new
Post.ReplyTo. X takes it as in_reply_to_tweet_id. Bluesky needs the
thread root as well as the parent, so a Ref now carries the root it was
posted under and a post that is not itself a reply acts as its own root.

Replying to something we never distributed, an error notice from the bot
for instance, still posts normally.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-26 11:55:28 +09:00
parent 067c9252c9
commit 1c2ab29404
6 changed files with 75 additions and 10 deletions

View File

@@ -20,6 +20,9 @@ type Event struct {
MessageID string
Content string
Attachments []*discordgo.MessageAttachment
// ReplyToID is the ID of the message this one replies to, empty when the
// message is not a reply.
ReplyToID string
}
type Client struct {
@@ -49,12 +52,16 @@ func (d *Client) read(eventchannel chan<- Event) {
if m.ChannelID != d.ChannelID || m.Author.ID == s.State.User.ID {
return
}
eventchannel <- Event{
event := Event{
Kind: MessageCreated,
MessageID: m.ID,
Content: m.Content,
Attachments: m.Attachments,
}
if m.MessageReference != nil {
event.ReplyToID = m.MessageReference.MessageID
}
eventchannel <- event
})
// Deleted messages arrive without an author, so the channel is the only