chore: refresh gramsrv public release
This commit is contained in:
parent
75cebe8dbf
commit
70b6820474
1274 changed files with 378751 additions and 59919 deletions
169
internal/store/postgres/message_forward.go
Normal file
169
internal/store/postgres/message_forward.go
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"telesrv/internal/domain"
|
||||
"telesrv/internal/store/postgres/sqlcgen"
|
||||
"time"
|
||||
)
|
||||
|
||||
func cloneMessageForward(forward *domain.MessageForward) *domain.MessageForward {
|
||||
if forward == nil {
|
||||
return nil
|
||||
}
|
||||
clone := *forward
|
||||
return &clone
|
||||
}
|
||||
|
||||
func (s *MessageStore) ForwardPrivateMessages(ctx context.Context, req domain.ForwardPrivateMessagesRequest) (domain.ForwardPrivateMessagesResult, error) {
|
||||
res := domain.ForwardPrivateMessagesResult{OwnerUserID: req.OwnerUserID}
|
||||
if req.OwnerUserID == 0 || req.ToUserID == 0 {
|
||||
return res, fmt.Errorf("forward private messages: missing user id")
|
||||
}
|
||||
if req.FromPeer.Type != domain.PeerTypeUser || req.FromPeer.ID == 0 {
|
||||
return res, fmt.Errorf("forward private messages: invalid source peer")
|
||||
}
|
||||
if len(req.MessageIDs) == 0 || len(req.MessageIDs) != len(req.RandomIDs) {
|
||||
return res, domain.ErrMessageIDInvalid
|
||||
}
|
||||
if len(req.MessageIDs) > domain.MaxForwardMessageIDs {
|
||||
return res, fmt.Errorf("forward private messages: too many ids: %d > %d", len(req.MessageIDs), domain.MaxForwardMessageIDs)
|
||||
}
|
||||
if req.Date == 0 {
|
||||
req.Date = int(time.Now().Unix())
|
||||
}
|
||||
boxIDs := make([]int32, 0, len(req.MessageIDs))
|
||||
for i, id := range req.MessageIDs {
|
||||
if id <= 0 || id > domain.MaxMessageBoxID || req.RandomIDs[i] == 0 {
|
||||
return res, domain.ErrMessageIDInvalid
|
||||
}
|
||||
boxIDs = append(boxIDs, int32(id))
|
||||
}
|
||||
rows, err := s.q.GetMessageBoxesForForward(ctx, sqlcgen.GetMessageBoxesForForwardParams{
|
||||
OwnerUserID: req.OwnerUserID,
|
||||
PeerType: string(req.FromPeer.Type),
|
||||
PeerID: req.FromPeer.ID,
|
||||
BoxIds: boxIDs,
|
||||
})
|
||||
if err != nil {
|
||||
return res, fmt.Errorf("get forward messages: %w", err)
|
||||
}
|
||||
if len(rows) != len(req.MessageIDs) {
|
||||
return res, domain.ErrMessageIDInvalid
|
||||
}
|
||||
res.SenderMessages = make([]domain.Message, 0, len(rows))
|
||||
res.RecipientMessages = make([]domain.Message, 0, len(rows))
|
||||
res.SenderEvents = make([]domain.UpdateEvent, 0, len(rows))
|
||||
res.RecipientEvents = make([]domain.UpdateEvent, 0, len(rows))
|
||||
res.Duplicates = make([]bool, 0, len(rows))
|
||||
for i, row := range rows {
|
||||
if int(row.BoxID) != req.MessageIDs[i] {
|
||||
return res, domain.ErrMessageIDInvalid
|
||||
}
|
||||
source, err := messageFromForwardRow(row)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
if source.NoForwards {
|
||||
return res, domain.ErrChatForwardsRestricted
|
||||
}
|
||||
var forward *domain.MessageForward
|
||||
if !req.DropAuthor {
|
||||
forward = cloneMessageForward(source.Forward)
|
||||
if forward == nil {
|
||||
forward = &domain.MessageForward{From: source.From, Date: source.Date}
|
||||
}
|
||||
// 转发进 Saved Messages 必须带 saved_from_peer/msg_id 成对字段,
|
||||
// 客户端靠它提供"跳回原会话"。
|
||||
if req.ToUserID == req.OwnerUserID {
|
||||
forward.SavedFrom = req.FromPeer
|
||||
forward.SavedFromMsgID = req.MessageIDs[i]
|
||||
}
|
||||
}
|
||||
sent, err := s.SendPrivateText(ctx, domain.SendPrivateTextRequest{
|
||||
SenderUserID: req.OwnerUserID,
|
||||
RecipientUserID: req.ToUserID,
|
||||
RandomID: req.RandomIDs[i],
|
||||
Message: source.Body,
|
||||
Entities: append([]domain.MessageEntity(nil), source.Entities...),
|
||||
Media: source.Media,
|
||||
Silent: req.Silent,
|
||||
NoForwards: req.NoForwards,
|
||||
ReplyTo: req.ReplyTo,
|
||||
Forward: forward,
|
||||
Date: req.Date,
|
||||
OriginAuthKeyID: req.OriginAuthKeyID,
|
||||
OriginSessionID: req.OriginSessionID,
|
||||
RecipientBlocked: req.RecipientBlocked,
|
||||
})
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
res.SenderMessages = append(res.SenderMessages, sent.SenderMessage)
|
||||
res.RecipientMessages = append(res.RecipientMessages, sent.RecipientMessage)
|
||||
res.SenderEvents = append(res.SenderEvents, sent.SenderEvent)
|
||||
res.RecipientEvents = append(res.RecipientEvents, sent.RecipientEvent)
|
||||
res.Duplicates = append(res.Duplicates, sent.Duplicate)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func messageFromForwardRow(row sqlcgen.GetMessageBoxesForForwardRow) (domain.Message, error) {
|
||||
entities, err := decodeMessageEntities(row.EntitiesJson)
|
||||
if err != nil {
|
||||
return domain.Message{}, fmt.Errorf("decode forward message entities: %w", err)
|
||||
}
|
||||
silent, noforwards, reply, forward, err := messageMetadataFromFields(
|
||||
row.Silent,
|
||||
row.Noforwards,
|
||||
row.ReplyToMsgID,
|
||||
row.ReplyToPeerType,
|
||||
row.ReplyToPeerID,
|
||||
row.ReplyToTopID,
|
||||
row.ReplyToStoryID,
|
||||
row.QuoteText,
|
||||
row.QuoteEntitiesJson,
|
||||
row.QuoteOffset,
|
||||
row.FwdFromPeerType,
|
||||
row.FwdFromPeerID,
|
||||
row.FwdFromName,
|
||||
row.FwdDate,
|
||||
row.FwdSavedFromPeerType,
|
||||
row.FwdSavedFromPeerID,
|
||||
row.FwdSavedFromMsgID,
|
||||
)
|
||||
if err != nil {
|
||||
return domain.Message{}, fmt.Errorf("decode forward message metadata: %w", err)
|
||||
}
|
||||
media, err := decodeMessageMedia(row.MediaJson)
|
||||
if err != nil {
|
||||
return domain.Message{}, fmt.Errorf("decode forward message media: %w", err)
|
||||
}
|
||||
return domain.Message{
|
||||
Media: media,
|
||||
ID: int(row.BoxID),
|
||||
UID: row.PrivateMessageID,
|
||||
OwnerUserID: row.OwnerUserID,
|
||||
Peer: domain.Peer{Type: domain.PeerType(row.PeerType), ID: row.PeerID},
|
||||
From: domain.Peer{Type: domain.PeerTypeUser, ID: row.FromUserID},
|
||||
Date: int(row.MessageDate),
|
||||
EditDate: int(row.EditDate),
|
||||
Out: row.Outgoing,
|
||||
Silent: silent,
|
||||
NoForwards: noforwards,
|
||||
Body: row.Body,
|
||||
Entities: entities,
|
||||
ReplyTo: reply,
|
||||
Forward: forward,
|
||||
Pts: int(row.Pts),
|
||||
TTLPeriod: int(row.TtlPeriod),
|
||||
ExpiresAt: int(row.ExpiresAt),
|
||||
MediaUnread: row.MediaUnread,
|
||||
ReactionUnread: row.ReactionUnread,
|
||||
ViaBotID: row.ViaBotID,
|
||||
GroupedID: row.GroupedID,
|
||||
Pinned: row.Pinned,
|
||||
SavedPeer: savedPeerFromFields(row.SavedPeerType, row.SavedPeerID),
|
||||
}, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue