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,
|
"channel_id": m.ChannelID,
|
||||||
"is_dm": fmt.Sprintf("%t", m.GuildID == ""),
|
"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)
|
c.HandleMessage(c.ctx, peer, m.ID, senderID, m.ChannelID, content, mediaPaths, metadata, sender)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
package discord
|
package discord
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
|
|
||||||
|
"github.com/sipeed/picoclaw/pkg/bus"
|
||||||
|
"github.com/sipeed/picoclaw/pkg/channels"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestApplyDiscordProxy_CustomProxy(t *testing.T) {
|
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")
|
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,
|
"sender_raw": senderID,
|
||||||
}
|
}
|
||||||
if replyTo := msgEvt.GetRelatesTo().GetReplyTo(); replyTo != "" {
|
if replyTo := msgEvt.GetRelatesTo().GetReplyTo(); replyTo != "" {
|
||||||
|
metadata["reply_to_message_id"] = replyTo.String()
|
||||||
metadata["reply_to_msg_id"] = replyTo.String()
|
metadata["reply_to_msg_id"] = replyTo.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ import (
|
||||||
"maunium.net/go/mautrix/event"
|
"maunium.net/go/mautrix/event"
|
||||||
"maunium.net/go/mautrix/id"
|
"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/config"
|
||||||
"github.com/sipeed/picoclaw/pkg/media"
|
"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)
|
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",
|
"platform": "slack",
|
||||||
"team_id": c.teamID,
|
"team_id": c.teamID,
|
||||||
}
|
}
|
||||||
|
if threadTS != "" && threadTS != messageTS {
|
||||||
|
metadata["reply_to_message_id"] = threadTS
|
||||||
|
}
|
||||||
|
|
||||||
logger.DebugCF("slack", "Received message", map[string]any{
|
logger.DebugCF("slack", "Received message", map[string]any{
|
||||||
"sender_id": senderID,
|
"sender_id": senderID,
|
||||||
|
|
@ -447,6 +450,9 @@ func (c *SlackChannel) handleAppMention(ev *slackevents.AppMentionEvent) {
|
||||||
"is_mention": "true",
|
"is_mention": "true",
|
||||||
"team_id": c.teamID,
|
"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)
|
c.HandleMessage(c.ctx, mentionPeer, messageTS, senderID, chatID, content, nil, metadata, mentionSender)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
package slack
|
package slack
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/slack-go/slack/slackevents"
|
||||||
|
|
||||||
"github.com/sipeed/picoclaw/pkg/bus"
|
"github.com/sipeed/picoclaw/pkg/bus"
|
||||||
|
"github.com/sipeed/picoclaw/pkg/channels"
|
||||||
"github.com/sipeed/picoclaw/pkg/config"
|
"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