111 lines
3.6 KiB
Go
111 lines
3.6 KiB
Go
package rpc
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/iamxvbaba/td/proto"
|
|
"github.com/iamxvbaba/td/tg"
|
|
"github.com/iamxvbaba/td/tlprofile"
|
|
"go.uber.org/zap"
|
|
|
|
"telesrv/internal/store"
|
|
)
|
|
|
|
const ephemeralPushSubscribeRetry = time.Second
|
|
|
|
func (r *Router) RunEphemeralPushSubscriber(ctx context.Context) {
|
|
if r == nil || r.deps.EphemeralPush == nil {
|
|
return
|
|
}
|
|
for {
|
|
err := r.deps.EphemeralPush.SubscribeEphemeralPushes(ctx, func(ctx context.Context, event store.EphemeralPush) {
|
|
if event.SourceID == "" || event.SourceID == r.instanceID {
|
|
return
|
|
}
|
|
r.deliverEphemeralPushLocal(ctx, event)
|
|
})
|
|
if ctx.Err() != nil {
|
|
return
|
|
}
|
|
if err != nil {
|
|
r.log.Warn("ephemeral push subscriber stopped", zap.Error(err))
|
|
}
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-time.After(ephemeralPushSubscribeRetry):
|
|
}
|
|
}
|
|
}
|
|
|
|
func (r *Router) publishEphemeralPush(ctx context.Context, event store.EphemeralPush) {
|
|
if r == nil || event.TargetUserID <= 0 {
|
|
return
|
|
}
|
|
event.SourceID = r.instanceID
|
|
if event.Date <= 0 {
|
|
event.Date = int(r.clock.Now().Unix())
|
|
}
|
|
r.deliverEphemeralPushLocal(ctx, event)
|
|
if r.deps.EphemeralPush != nil {
|
|
if err := r.deps.EphemeralPush.PublishEphemeralPush(ctx, event); err != nil {
|
|
r.log.Debug("publish ephemeral push", zap.String("kind", string(event.Kind)), zap.Int64("target_user_id", event.TargetUserID), zap.Error(err))
|
|
}
|
|
}
|
|
}
|
|
|
|
func (r *Router) deliverEphemeralPushLocal(ctx context.Context, event store.EphemeralPush) {
|
|
if r == nil || r.deps.Sessions == nil || event.TargetUserID <= 0 || event.Message.ID <= 0 {
|
|
return
|
|
}
|
|
if online, ok := r.deps.Sessions.(OnlineUserProvider); ok && !online.IsUserOnline(event.TargetUserID) {
|
|
return
|
|
}
|
|
binder, ok := r.deps.Sessions.(SemanticTransientSessionBinder)
|
|
if !ok {
|
|
return
|
|
}
|
|
var updates tg.UpdatesClass
|
|
var semantic tlprofile.SemanticID
|
|
switch event.Kind {
|
|
case store.EphemeralPushNew, store.EphemeralPushEdit:
|
|
if event.TargetUserID != event.Message.ReceiverUserID || event.Message.Deleted {
|
|
return
|
|
}
|
|
built, err := r.ephemeralMessageUpdates(ctx, event.TargetUserID, event.Message, event.Kind == store.EphemeralPushEdit)
|
|
if err != nil {
|
|
return
|
|
}
|
|
updates = built
|
|
semantic = tlprofile.SemanticTypeUpdateNewEphemeralMessage
|
|
if event.Kind == store.EphemeralPushEdit {
|
|
semantic = tlprofile.SemanticTypeUpdateEditEphemeralMessage
|
|
}
|
|
case store.EphemeralPushDelete:
|
|
if !event.Message.Deleted || (event.TargetUserID != event.Message.SenderUserID && event.TargetUserID != event.Message.ReceiverUserID) {
|
|
return
|
|
}
|
|
updates = ephemeralDeleteUpdates(event.Message, event.Date)
|
|
semantic = tlprofile.SemanticTypeUpdateDeleteEphemeralMessages
|
|
case store.EphemeralPushCallback:
|
|
callback := event.Callback
|
|
if callback == nil || callback.BotUserID != event.TargetUserID || callback.MessageID != event.Message.ID || callback.Peer != event.Message.Peer {
|
|
return
|
|
}
|
|
update := &tg.UpdateBotCallbackQuery{
|
|
QueryID: callback.ID, UserID: callback.UserID, Peer: tgPeer(callback.Peer),
|
|
MsgID: callback.MessageID, ChatInstance: callback.ChatInstance,
|
|
}
|
|
update.SetData(callback.Data)
|
|
updates = &tg.Updates{Updates: []tg.UpdateClass{update}, Date: event.Date}
|
|
semantic = tlprofile.SemanticTypeUpdateBotCallbackQuery
|
|
default:
|
|
return
|
|
}
|
|
if event.TargetBusinessAuthKey != ([8]byte{}) {
|
|
_, _ = binder.PushToUserAuthKeyTransientCompatible(ctx, event.TargetUserID, event.TargetBusinessAuthKey, semantic, proto.MessageFromServer, updates, r.cfg.OutboundPushTimeout)
|
|
return
|
|
}
|
|
_, _ = binder.PushToUserTransientCompatible(ctx, event.TargetUserID, semantic, proto.MessageFromServer, updates, r.cfg.OutboundPushTimeout)
|
|
}
|