chore: refresh gramsrv public release

This commit is contained in:
A 2026-06-30 14:37:43 +08:00
parent 75cebe8dbf
commit 70b6820474
1274 changed files with 378751 additions and 59919 deletions

View file

@ -0,0 +1,67 @@
package rpc
import (
"context"
"go.uber.org/zap"
"telesrv/internal/domain"
)
// sendPhoneCallServiceMessage 把已终结的通话落成 messageActionPhoneCall 历史
// (完整复刻 pin 服务消息模式,messages_pin.go)。要点:
// - sender 恒为主叫 AdminID——无论谁发起 discard(官方语义:主叫侧渲染
// 「呼出」、被叫侧渲染「未接来电/通话 X 分钟」,missed 在被叫侧计未读);
// - Origin 置零:双方全部设备(含 discard 发起设备)都经 outbox 收到
// updateNewMessage(带 pts)——发起设备的 RPC 响应里只有 updatePhoneCall,
// 服务消息必须从 update 流来;离线设备重连经 getDifference 补收,正好
// 补偿信令直推的不可靠(「未接来电」由此而来);
// - RandomID 由 callID 确定性派生:状态机保证一通通话只落一次历史,
// 极端重放也会被发送管道的 random_id 去重吸收;
// - 失败仅 Warn 不回滚:通话状态是真值,历史是装饰(与 pin 同哲学)。
//
// 注意:本路径绕过 RPC 层的 checkSendRateLimit(限速挂在 handler 侧)——
// 这是有意为之,呼叫轰炸防护由通话并发上限与振铃超时承担。
func (r *Router) sendPhoneCallServiceMessage(ctx context.Context, call domain.PhoneCall) {
if r.deps.Messages == nil || !call.Terminal() {
return
}
recipientBlocked, err := r.peerBlocksUser(ctx, call.AdminID, call.ParticipantID)
if err != nil {
recipientBlocked = false
}
_, err = r.deps.Messages.SendPrivateText(ctx, call.AdminID, domain.SendPrivateTextRequest{
SenderUserID: call.AdminID,
RecipientUserID: call.ParticipantID,
RandomID: phoneCallServiceMessageRandomID(call.ID),
Media: &domain.MessageMedia{
Kind: domain.MessageMediaKindService,
ServiceAction: &domain.MessageServiceAction{
Kind: domain.MessageServiceActionPhoneCall,
Call: &domain.MessagePhoneCallAction{
CallID: call.ID,
Reason: string(call.DiscardReason),
Duration: call.Duration,
Video: call.Video,
},
},
},
Date: int(r.clock.Now().Unix()),
RecipientBlocked: recipientBlocked,
})
if err != nil {
r.log.Warn("phone call service message",
zap.Int64("call_id", call.ID),
zap.Int64("admin_id", call.AdminID),
zap.Int64("participant_id", call.ParticipantID),
zap.Error(err))
}
}
func phoneCallServiceMessageRandomID(callID int64) int64 {
id := callID ^ 0x70686f6e6563616c // "phonecal"
if id == 0 {
return 1
}
return id
}