96 lines
2.6 KiB
Go
96 lines
2.6 KiB
Go
package logic
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
deliverentity "spark-server/internal/module/deliver/entity"
|
|
friendentity "spark-server/internal/module/friend/entity"
|
|
msgentity "spark-server/internal/module/message/entity"
|
|
"spark-server/internal/pkg/reply"
|
|
)
|
|
|
|
const cmdMessage uint16 = 6
|
|
|
|
// DeliverQueue is Redis deliver:queue Push (C5).
|
|
type DeliverQueue interface {
|
|
Push(ctx context.Context, job *deliverentity.Job) error
|
|
}
|
|
|
|
// SystemGreeter inserts a type-9 system message into the P2P conversation and enqueues deliver.
|
|
type SystemGreeter struct {
|
|
chats P2PChats
|
|
msgs Messages
|
|
ids IDGen
|
|
queue DeliverQueue
|
|
}
|
|
|
|
func NewGreeter(chats P2PChats, msgs Messages, ids IDGen, queue DeliverQueue) *SystemGreeter {
|
|
return &SystemGreeter{chats: chats, msgs: msgs, ids: ids, queue: queue}
|
|
}
|
|
|
|
func (g *SystemGreeter) BecameFriends(ctx context.Context, userA, userB int64) error {
|
|
if g == nil || g.chats == nil || g.msgs == nil || g.ids == nil {
|
|
return nil
|
|
}
|
|
convID, err := g.chats.EnsureP2P(ctx, userA, userB)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
msgID, err := g.ids.NextID()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
now := time.Now()
|
|
content := msgentity.NewSystem(&msgentity.System{Kind: friendentity.SystemKindBecameFriends})
|
|
raw, err := content.Marshal()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
msg := &msgentity.Message{
|
|
ID: msgID,
|
|
ConversationID: convID,
|
|
SenderID: 0,
|
|
ClientMsgID: fmt.Sprintf("sys:friend:%d", msgID),
|
|
Type: msgentity.TypeSystem,
|
|
Kind: msgentity.KindPrivate,
|
|
Content: raw,
|
|
Status: msgentity.StatusNormal,
|
|
CreatedAtMS: now.UnixMilli(),
|
|
}
|
|
if err := g.msgs.Create(ctx, msg); err != nil {
|
|
return err
|
|
}
|
|
if err := g.chats.UpdateLastMsg(ctx, convID, msgID, now.UnixMilli()); err != nil {
|
|
return err
|
|
}
|
|
if g.queue == nil {
|
|
return nil
|
|
}
|
|
return g.queue.Push(ctx, &deliverentity.Job{
|
|
MsgID: msgID,
|
|
Cmd: cmdMessage,
|
|
ConversationID: convID,
|
|
ToUserIDs: []int64{userA, userB},
|
|
Payload: reply.MustMarshal(reply.OK(pushBodyOf(msg))),
|
|
})
|
|
}
|
|
|
|
type pushBody struct {
|
|
MsgID int64 `json:"msg_id"`
|
|
ConversationID int64 `json:"conversation_id"`
|
|
SenderID int64 `json:"sender_id"`
|
|
MessageType msgentity.Type `json:"message_type"`
|
|
Content json.RawMessage `json:"content"`
|
|
CreatedAt int64 `json:"created_at"`
|
|
}
|
|
|
|
func pushBodyOf(m *msgentity.Message) pushBody {
|
|
return pushBody{
|
|
MsgID: m.ID, ConversationID: m.ConversationID, SenderID: m.SenderID,
|
|
MessageType: m.Type, Content: m.Content, CreatedAt: m.CreatedAtMS,
|
|
}
|
|
}
|