feat: add log-backed receive message source
This commit is contained in:
95
internal/isphere/source.go
Normal file
95
internal/isphere/source.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package isphere
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"isphere-ai-bridge/internal/isphere/logcodec"
|
||||
"isphere-ai-bridge/internal/isphere/packetlog"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
ID string
|
||||
ConversationID string
|
||||
ConversationType string
|
||||
SenderID string
|
||||
ReceiverID string
|
||||
Text string
|
||||
Timestamp string
|
||||
Subject string
|
||||
ReceiptID string
|
||||
Read bool
|
||||
}
|
||||
|
||||
type ReceiveMessagesQuery struct {
|
||||
Limit int
|
||||
}
|
||||
|
||||
type ReceiveMessagesResult struct {
|
||||
Messages []Message
|
||||
}
|
||||
|
||||
type EncryptedPacketLogSource struct {
|
||||
Lines []string
|
||||
}
|
||||
|
||||
func (s EncryptedPacketLogSource) ReceiveMessages(ctx context.Context, query ReceiveMessagesQuery) (ReceiveMessagesResult, error) {
|
||||
limit := query.Limit
|
||||
if limit <= 0 || limit > len(s.Lines) {
|
||||
limit = len(s.Lines)
|
||||
}
|
||||
messages := make([]Message, 0, limit)
|
||||
for index, line := range s.Lines {
|
||||
if len(messages) == limit {
|
||||
break
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ReceiveMessagesResult{}, ctx.Err()
|
||||
default:
|
||||
}
|
||||
plaintext, err := logcodec.DecryptLine(line)
|
||||
if err != nil {
|
||||
return ReceiveMessagesResult{}, fmt.Errorf("decrypt packet log line %d: %w", index, err)
|
||||
}
|
||||
parsed, err := packetlog.ParseMessageLog(plaintext)
|
||||
if err != nil {
|
||||
return ReceiveMessagesResult{}, fmt.Errorf("parse packet log line %d: %w", index, err)
|
||||
}
|
||||
messages = append(messages, normalizePacketMessage(parsed))
|
||||
}
|
||||
return ReceiveMessagesResult{Messages: messages}, nil
|
||||
}
|
||||
|
||||
func normalizePacketMessage(msg packetlog.Message) Message {
|
||||
sender := bareJID(msg.From)
|
||||
receiver := bareJID(msg.To)
|
||||
return Message{
|
||||
ID: msg.ID,
|
||||
ConversationID: conversationID(sender, receiver),
|
||||
ConversationType: msg.Type,
|
||||
SenderID: sender,
|
||||
ReceiverID: receiver,
|
||||
Text: msg.Body,
|
||||
Timestamp: msg.SendTime,
|
||||
Subject: msg.Subject,
|
||||
ReceiptID: msg.ReceiptID,
|
||||
Read: msg.Read,
|
||||
}
|
||||
}
|
||||
|
||||
func bareJID(value string) string {
|
||||
beforeResource, _, _ := strings.Cut(value, "/")
|
||||
return beforeResource
|
||||
}
|
||||
|
||||
func conversationID(sender string, receiver string) string {
|
||||
if sender == "" {
|
||||
return receiver
|
||||
}
|
||||
if receiver == "" {
|
||||
return sender
|
||||
}
|
||||
return sender + "|" + receiver
|
||||
}
|
||||
Reference in New Issue
Block a user