Preserve inbound reply IDs across channels
This commit is contained in:
parent
bd3017dd8e
commit
7f91fa90f2
6 changed files with 128 additions and 0 deletions
|
|
@ -478,6 +478,9 @@ func (c *DiscordChannel) handleMessage(s *discordgo.Session, m *discordgo.Messag
|
|||
"channel_id": m.ChannelID,
|
||||
"is_dm": fmt.Sprintf("%t", m.GuildID == ""),
|
||||
}
|
||||
if m.MessageReference != nil && m.MessageReference.MessageID != "" {
|
||||
metadata["reply_to_message_id"] = m.MessageReference.MessageID
|
||||
}
|
||||
|
||||
c.HandleMessage(c.ctx, peer, m.ID, senderID, m.ChannelID, content, mediaPaths, metadata, sender)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
package discord
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
|
||||
"github.com/sipeed/picoclaw/pkg/bus"
|
||||
"github.com/sipeed/picoclaw/pkg/channels"
|
||||
)
|
||||
|
||||
func TestApplyDiscordProxy_CustomProxy(t *testing.T) {
|
||||
|
|
@ -89,3 +93,43 @@ func TestApplyDiscordProxy_InvalidProxyURL(t *testing.T) {
|
|||
t.Fatal("applyDiscordProxy() expected error for invalid proxy URL, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleMessage_PreservesReplyToMessageID(t *testing.T) {
|
||||
messageBus := bus.NewMessageBus()
|
||||
ch := &DiscordChannel{
|
||||
BaseChannel: channels.NewBaseChannel("discord", nil, messageBus, nil),
|
||||
ctx: context.Background(),
|
||||
}
|
||||
|
||||
session := &discordgo.Session{
|
||||
State: &discordgo.State{
|
||||
Ready: discordgo.Ready{
|
||||
User: &discordgo.User{ID: "bot"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ch.handleMessage(session, &discordgo.MessageCreate{
|
||||
Message: &discordgo.Message{
|
||||
ID: "msg-2",
|
||||
ChannelID: "chan-1",
|
||||
Content: "hello",
|
||||
Author: &discordgo.User{
|
||||
ID: "user-1",
|
||||
Username: "alice",
|
||||
},
|
||||
MessageReference: &discordgo.MessageReference{
|
||||
MessageID: "msg-1",
|
||||
ChannelID: "chan-1",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
inbound := <-messageBus.InboundChan()
|
||||
if inbound.MessageID != "msg-2" {
|
||||
t.Fatalf("expected MessageID msg-2, got %q", inbound.MessageID)
|
||||
}
|
||||
if inbound.ReplyToMessageID != "msg-1" {
|
||||
t.Fatalf("expected ReplyToMessageID msg-1, got %q", inbound.ReplyToMessageID)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -743,6 +743,7 @@ func (c *MatrixChannel) handleMessageEvent(ctx context.Context, evt *event.Event
|
|||
"sender_raw": senderID,
|
||||
}
|
||||
if replyTo := msgEvt.GetRelatesTo().GetReplyTo(); replyTo != "" {
|
||||
metadata["reply_to_message_id"] = replyTo.String()
|
||||
metadata["reply_to_msg_id"] = replyTo.String()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import (
|
|||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
|
||||
"github.com/sipeed/picoclaw/pkg/bus"
|
||||
"github.com/sipeed/picoclaw/pkg/channels"
|
||||
"github.com/sipeed/picoclaw/pkg/config"
|
||||
"github.com/sipeed/picoclaw/pkg/media"
|
||||
)
|
||||
|
|
@ -386,3 +388,45 @@ func TestMessageContent(t *testing.T) {
|
|||
t.Errorf("plain: expected no formatting, got format=%q formattedBody=%q", mc.Format, mc.FormattedBody)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleMessageEvent_PreservesReplyToMessageID(t *testing.T) {
|
||||
messageBus := bus.NewMessageBus()
|
||||
roomID := id.RoomID("!room:matrix.test")
|
||||
ch := &MatrixChannel{
|
||||
BaseChannel: channels.NewBaseChannel("matrix", nil, messageBus, nil),
|
||||
client: &mautrix.Client{UserID: id.UserID("@bot:matrix.test")},
|
||||
startTime: time.Unix(0, 0),
|
||||
roomKindCache: newRoomKindCache(4, time.Minute),
|
||||
}
|
||||
ch.roomKindCache.set(roomID.String(), false, time.Now())
|
||||
|
||||
msgContent := &event.MessageEventContent{
|
||||
MsgType: event.MsgText,
|
||||
Body: "hello",
|
||||
RelatesTo: &event.RelatesTo{
|
||||
InReplyTo: &event.InReplyTo{EventID: id.EventID("$parent")},
|
||||
},
|
||||
}
|
||||
|
||||
ch.handleMessageEvent(context.Background(), &event.Event{
|
||||
Sender: id.UserID("@alice:matrix.test"),
|
||||
Type: event.EventMessage,
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
ID: id.EventID("$event"),
|
||||
RoomID: roomID,
|
||||
Content: event.Content{
|
||||
Parsed: msgContent,
|
||||
},
|
||||
})
|
||||
|
||||
inbound := <-messageBus.InboundChan()
|
||||
if inbound.MessageID != "$event" {
|
||||
t.Fatalf("expected MessageID $event, got %q", inbound.MessageID)
|
||||
}
|
||||
if inbound.ReplyToMessageID != "$parent" {
|
||||
t.Fatalf("expected ReplyToMessageID $parent, got %q", inbound.ReplyToMessageID)
|
||||
}
|
||||
if inbound.Metadata["reply_to_message_id"] != "$parent" {
|
||||
t.Fatalf("expected metadata reply_to_message_id $parent, got %q", inbound.Metadata["reply_to_message_id"])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -375,6 +375,9 @@ func (c *SlackChannel) handleMessageEvent(ev *slackevents.MessageEvent) {
|
|||
"platform": "slack",
|
||||
"team_id": c.teamID,
|
||||
}
|
||||
if threadTS != "" && threadTS != messageTS {
|
||||
metadata["reply_to_message_id"] = threadTS
|
||||
}
|
||||
|
||||
logger.DebugCF("slack", "Received message", map[string]any{
|
||||
"sender_id": senderID,
|
||||
|
|
@ -447,6 +450,9 @@ func (c *SlackChannel) handleAppMention(ev *slackevents.AppMentionEvent) {
|
|||
"is_mention": "true",
|
||||
"team_id": c.teamID,
|
||||
}
|
||||
if threadTS != "" && threadTS != messageTS {
|
||||
metadata["reply_to_message_id"] = threadTS
|
||||
}
|
||||
|
||||
c.HandleMessage(c.ctx, mentionPeer, messageTS, senderID, chatID, content, nil, metadata, mentionSender)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
package slack
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/slack-go/slack/slackevents"
|
||||
|
||||
"github.com/sipeed/picoclaw/pkg/bus"
|
||||
"github.com/sipeed/picoclaw/pkg/channels"
|
||||
"github.com/sipeed/picoclaw/pkg/config"
|
||||
)
|
||||
|
||||
|
|
@ -168,3 +172,29 @@ func TestSlackChannelIsAllowed(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestHandleMessageEvent_PreservesReplyToMessageIDFromThreadTS(t *testing.T) {
|
||||
messageBus := bus.NewMessageBus()
|
||||
ch := &SlackChannel{
|
||||
BaseChannel: channels.NewBaseChannel("slack", nil, messageBus, nil),
|
||||
ctx: context.Background(),
|
||||
teamID: "T1",
|
||||
}
|
||||
|
||||
ch.handleMessageEvent(&slackevents.MessageEvent{
|
||||
Type: "message",
|
||||
User: "U123",
|
||||
Text: "hello",
|
||||
ThreadTimeStamp: "1710000000.000100",
|
||||
TimeStamp: "1710000000.000200",
|
||||
Channel: "C123",
|
||||
})
|
||||
|
||||
inbound := <-messageBus.InboundChan()
|
||||
if inbound.MessageID != "1710000000.000200" {
|
||||
t.Fatalf("expected MessageID to be message ts, got %q", inbound.MessageID)
|
||||
}
|
||||
if inbound.ReplyToMessageID != "1710000000.000100" {
|
||||
t.Fatalf("expected ReplyToMessageID thread root ts, got %q", inbound.ReplyToMessageID)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue