reactions: poll for reactions on read receipt
Signed-off-by: Sumner Evans <sumner.evans@automattic.com>
This commit is contained in:
@@ -15,7 +15,7 @@ require (
|
|||||||
go.uber.org/zap v1.27.0
|
go.uber.org/zap v1.27.0
|
||||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
|
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
|
||||||
golang.org/x/net v0.30.0
|
golang.org/x/net v0.30.0
|
||||||
maunium.net/go/mautrix v0.21.2-0.20241022095053-8a8163106d95
|
maunium.net/go/mautrix v0.21.2-0.20241023204042-6fd4b8a2132d
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|||||||
@@ -117,8 +117,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M=
|
maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M=
|
||||||
maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
|
maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
|
||||||
maunium.net/go/mautrix v0.21.2-0.20241022095053-8a8163106d95 h1:/y/+rB6JduDIjS0SD4STxwE75IcqIwFfUaWocFifws8=
|
maunium.net/go/mautrix v0.21.2-0.20241023204042-6fd4b8a2132d h1:pW2F/uX9eqziumLBDiFAx2XwfiwPuKI6XyKqOkRDNCk=
|
||||||
maunium.net/go/mautrix v0.21.2-0.20241022095053-8a8163106d95/go.mod h1:sjCZR1R/3NET/WjkcXPL6WpAHlWKku9HjRsdOkbM8Qw=
|
maunium.net/go/mautrix v0.21.2-0.20241023204042-6fd4b8a2132d/go.mod h1:sjCZR1R/3NET/WjkcXPL6WpAHlWKku9HjRsdOkbM8Qw=
|
||||||
nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y=
|
nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y=
|
||||||
nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=
|
nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=
|
||||||
rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY=
|
rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY=
|
||||||
|
|||||||
+23
-20
@@ -263,11 +263,11 @@ func (t *TelegramClient) FetchMessages(ctx context.Context, fetchParams bridgev2
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg.TypeID() != tg.MessageTypeID {
|
message, ok := msg.(*tg.Message)
|
||||||
|
if !ok {
|
||||||
log.Warn().Str("type", msg.TypeName()).Msg("skipping backfilling unsupported message type")
|
log.Warn().Str("type", msg.TypeName()).Msg("skipping backfilling unsupported message type")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
message := msg.(*tg.Message)
|
|
||||||
|
|
||||||
sender := t.getEventSender(message)
|
sender := t.getEventSender(message)
|
||||||
intent := portal.GetIntentFor(ctx, sender, t.userLogin, bridgev2.RemoteEventBackfill)
|
intent := portal.GetIntentFor(ctx, sender, t.userLogin, bridgev2.RemoteEventBackfill)
|
||||||
@@ -275,10 +275,6 @@ func (t *TelegramClient) FetchMessages(ctx context.Context, fetchParams bridgev2
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
reactionsList, _, customEmojis, err := t.computeReactionsList(ctx, message)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
backfillMessage := bridgev2.BackfillMessage{
|
backfillMessage := bridgev2.BackfillMessage{
|
||||||
ConvertedMessage: converted,
|
ConvertedMessage: converted,
|
||||||
@@ -287,23 +283,30 @@ func (t *TelegramClient) FetchMessages(ctx context.Context, fetchParams bridgev2
|
|||||||
Timestamp: time.Unix(int64(message.Date), 0),
|
Timestamp: time.Unix(int64(message.Date), 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, reaction := range reactionsList {
|
if reactions, ok := message.GetReactions(); ok {
|
||||||
peer, ok := reaction.PeerID.(*tg.PeerUser)
|
reactionsList, _, customEmojis, err := t.computeReactionsList(ctx, message.PeerID, message.ID, reactions)
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("unknown peer type %T", reaction.PeerID)
|
|
||||||
}
|
|
||||||
|
|
||||||
emojiID, emoji, err := computeEmojiAndID(reaction.Reaction, customEmojis)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to compute emoji and ID: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
backfillMessage.Reactions = append(backfillMessage.Reactions, &bridgev2.BackfillReaction{
|
for _, reaction := range reactionsList {
|
||||||
Timestamp: time.Unix(int64(reaction.Date), 0),
|
peer, ok := reaction.PeerID.(*tg.PeerUser)
|
||||||
Sender: t.senderForUserID(peer.UserID),
|
if !ok {
|
||||||
EmojiID: emojiID,
|
return nil, fmt.Errorf("unknown peer type %T", reaction.PeerID)
|
||||||
Emoji: emoji,
|
}
|
||||||
})
|
|
||||||
|
emojiID, emoji, err := computeEmojiAndID(reaction.Reaction, customEmojis)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to compute emoji and ID: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
backfillMessage.Reactions = append(backfillMessage.Reactions, &bridgev2.BackfillReaction{
|
||||||
|
Timestamp: time.Unix(int64(reaction.Date), 0),
|
||||||
|
Sender: t.senderForUserID(peer.UserID),
|
||||||
|
EmojiID: emojiID,
|
||||||
|
Emoji: emoji,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backfillMessages = append(backfillMessages, &backfillMessage)
|
backfillMessages = append(backfillMessages, &backfillMessage)
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ type TelegramClient struct {
|
|||||||
takeoutDialogsOnce sync.Once
|
takeoutDialogsOnce sync.Once
|
||||||
|
|
||||||
activeCalls map[int64]networkid.PortalKey
|
activeCalls map[int64]networkid.PortalKey
|
||||||
|
|
||||||
|
prevReactionPoll map[networkid.PortalKey]time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -133,6 +135,9 @@ func NewTelegramClient(ctx context.Context, tc *TelegramConnector, login *bridge
|
|||||||
userLogin: login,
|
userLogin: login,
|
||||||
|
|
||||||
takeoutAccepted: exsync.NewEvent(),
|
takeoutAccepted: exsync.NewEvent(),
|
||||||
|
|
||||||
|
activeCalls: map[int64]networkid.PortalKey{},
|
||||||
|
prevReactionPoll: map[networkid.PortalKey]time.Time{},
|
||||||
}
|
}
|
||||||
dispatcher := UpdateDispatcher{
|
dispatcher := UpdateDispatcher{
|
||||||
UpdateDispatcher: tg.NewUpdateDispatcher(),
|
UpdateDispatcher: tg.NewUpdateDispatcher(),
|
||||||
|
|||||||
+33
-6
@@ -455,7 +455,12 @@ func (t *TelegramClient) HandleMatrixReactionRemove(ctx context.Context, msg *br
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *TelegramClient) HandleMatrixReadReceipt(ctx context.Context, msg *bridgev2.MatrixReadReceipt) error {
|
func (t *TelegramClient) HandleMatrixReadReceipt(ctx context.Context, msg *bridgev2.MatrixReadReceipt) error {
|
||||||
peerType, id, parseErr := ids.ParsePortalID(msg.Portal.ID)
|
log := zerolog.Ctx(ctx).With().
|
||||||
|
Str("action", "handle_matrix_read_receipt").
|
||||||
|
Str("portal_id", string(msg.Portal.ID)).
|
||||||
|
Bool("is_supergroup", msg.Portal.Metadata.(*PortalMetadata).IsSuperGroup).
|
||||||
|
Logger()
|
||||||
|
peerType, portalID, parseErr := ids.ParsePortalID(msg.Portal.ID)
|
||||||
if parseErr != nil {
|
if parseErr != nil {
|
||||||
return parseErr
|
return parseErr
|
||||||
}
|
}
|
||||||
@@ -464,7 +469,7 @@ func (t *TelegramClient) HandleMatrixReadReceipt(ctx context.Context, msg *bridg
|
|||||||
return parseErr
|
return parseErr
|
||||||
}
|
}
|
||||||
|
|
||||||
var readMentionsErr, readReactionsErr, readMessagesErr error
|
var readMentionsErr, readReactionsErr, readMessagesErr, reactionPollErr error
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
// Read mentions
|
// Read mentions
|
||||||
@@ -514,22 +519,44 @@ func (t *TelegramClient) HandleMatrixReadReceipt(ctx context.Context, msg *bridg
|
|||||||
})
|
})
|
||||||
case ids.PeerTypeChannel:
|
case ids.PeerTypeChannel:
|
||||||
var accessHash int64
|
var accessHash int64
|
||||||
accessHash, readMessagesErr = t.ScopedStore.GetAccessHash(ctx, ids.PeerTypeChannel, id)
|
accessHash, readMessagesErr = t.ScopedStore.GetAccessHash(ctx, ids.PeerTypeChannel, portalID)
|
||||||
if readMessagesErr != nil {
|
if readMessagesErr != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, readMessagesErr = t.client.API().ChannelsReadHistory(ctx, &tg.ChannelsReadHistoryRequest{
|
_, readMessagesErr = t.client.API().ChannelsReadHistory(ctx, &tg.ChannelsReadHistoryRequest{
|
||||||
Channel: &tg.InputChannel{ChannelID: id, AccessHash: accessHash},
|
Channel: &tg.InputChannel{ChannelID: portalID, AccessHash: accessHash},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if !msg.Portal.Metadata.(*PortalMetadata).IsSuperGroup {
|
||||||
|
// TODO handle sponsored message read receipts
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
readMessagesErr = fmt.Errorf("unknown peer type %s", peerType)
|
readMessagesErr = fmt.Errorf("unknown peer type %s", peerType)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// TODO handle sponsored message read receipts
|
// Poll for reactions
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
if peerType != ids.PeerTypeChannel || msg.Portal.Metadata.(*PortalMetadata).IsSuperGroup {
|
||||||
|
log.Debug().Msg("Not polling reactions because peer is not a channel or is a super-group")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it hasn't been 20 seconds since the last poll, skip
|
||||||
|
now := time.Now()
|
||||||
|
if prev, ok := t.prevReactionPoll[msg.Portal.PortalKey]; ok && now.Before(prev.Add(20*time.Second)) {
|
||||||
|
log.Debug().Msg("Not polling reactions because last poll was less than 20 seconds ago")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.prevReactionPoll[msg.Portal.PortalKey] = now
|
||||||
|
|
||||||
|
reactionPollErr = t.pollForReactions(ctx, msg.Portal.PortalKey, inputPeer)
|
||||||
|
}()
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
return errors.Join(readMentionsErr, readReactionsErr, readMessagesErr)
|
return errors.Join(readMentionsErr, readReactionsErr, readMessagesErr, reactionPollErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TelegramClient) HandleMatrixTyping(ctx context.Context, msg *bridgev2.MatrixTyping) error {
|
func (t *TelegramClient) HandleMatrixTyping(ctx context.Context, msg *bridgev2.MatrixTyping) error {
|
||||||
|
|||||||
+108
-13
@@ -14,19 +14,15 @@ import (
|
|||||||
"go.mau.fi/mautrix-telegram/pkg/connector/ids"
|
"go.mau.fi/mautrix-telegram/pkg/connector/ids"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *TelegramClient) computeReactionsList(ctx context.Context, msg *tg.Message) (reactions []tg.MessagePeerReaction, isFull bool, customEmojis map[networkid.EmojiID]string, err error) {
|
func (t *TelegramClient) computeReactionsList(ctx context.Context, peer tg.PeerClass, msgID int, msgReactions tg.MessageReactions) (reactions []tg.MessagePeerReaction, isFull bool, customEmojis map[networkid.EmojiID]string, err error) {
|
||||||
log := zerolog.Ctx(ctx).With().Str("fn", "computeReactionsList").Logger()
|
log := zerolog.Ctx(ctx).With().Str("fn", "computeReactionsList").Logger()
|
||||||
if _, set := msg.GetReactions(); !set {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var totalCount int
|
var totalCount int
|
||||||
for _, r := range msg.Reactions.Results {
|
for _, r := range msgReactions.Results {
|
||||||
totalCount += r.Count
|
totalCount += r.Count
|
||||||
}
|
}
|
||||||
|
|
||||||
reactionsList := msg.Reactions.RecentReactions
|
reactionsList := msgReactions.RecentReactions
|
||||||
if totalCount > 0 && len(reactionsList) == 0 && !msg.Reactions.CanSeeList {
|
if totalCount > 0 && len(reactionsList) == 0 && !msgReactions.CanSeeList {
|
||||||
// We don't know who reacted in a channel, so we can't bridge it properly either
|
// We don't know who reacted in a channel, so we can't bridge it properly either
|
||||||
log.Warn().Msg("Can't see reaction list in channel")
|
log.Warn().Msg("Can't see reaction list in channel")
|
||||||
return
|
return
|
||||||
@@ -39,8 +35,8 @@ func (t *TelegramClient) computeReactionsList(ctx context.Context, msg *tg.Messa
|
|||||||
// # return
|
// # return
|
||||||
|
|
||||||
if len(reactionsList) < totalCount {
|
if len(reactionsList) < totalCount {
|
||||||
if user, ok := msg.PeerID.(*tg.PeerUser); ok {
|
if user, ok := peer.(*tg.PeerUser); ok {
|
||||||
reactionsList = splitDMReactionCounts(msg.Reactions.Results, user.UserID, t.telegramUserID)
|
reactionsList = splitDMReactionCounts(msgReactions.Results, user.UserID, t.telegramUserID)
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// } else if t.isBot {
|
// } else if t.isBot {
|
||||||
@@ -48,12 +44,12 @@ func (t *TelegramClient) computeReactionsList(ctx context.Context, msg *tg.Messa
|
|||||||
// return
|
// return
|
||||||
|
|
||||||
// TODO should calls to this be limited?
|
// TODO should calls to this be limited?
|
||||||
} else if peer, err := t.inputPeerForPortalID(ctx, t.makePortalKeyFromPeer(msg.PeerID).ID); err != nil {
|
} else if peer, err := t.inputPeerForPortalID(ctx, t.makePortalKeyFromPeer(peer).ID); err != nil {
|
||||||
return nil, false, nil, fmt.Errorf("failed to get input peer: %w", err)
|
return nil, false, nil, fmt.Errorf("failed to get input peer: %w", err)
|
||||||
} else {
|
} else {
|
||||||
reactions, err := APICallWithUpdates(ctx, t, func() (*tg.MessagesMessageReactionsList, error) {
|
reactions, err := APICallWithUpdates(ctx, t, func() (*tg.MessagesMessageReactionsList, error) {
|
||||||
return t.client.API().MessagesGetMessageReactionsList(ctx, &tg.MessagesGetMessageReactionsListRequest{
|
return t.client.API().MessagesGetMessageReactionsList(ctx, &tg.MessagesGetMessageReactionsListRequest{
|
||||||
Peer: peer, ID: msg.ID, Limit: 100,
|
Peer: peer, ID: msgID, Limit: 100,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -104,7 +100,7 @@ func (t *TelegramClient) handleTelegramReactions(ctx context.Context, msg *tg.Me
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
reactionsList, isFull, customEmojis, err := t.computeReactionsList(ctx, msg)
|
reactionsList, isFull, customEmojis, err := t.computeReactionsList(ctx, msg.PeerID, msg.ID, msg.Reactions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg("failed to compute reactions list")
|
log.Err(err).Msg("failed to compute reactions list")
|
||||||
return
|
return
|
||||||
@@ -197,3 +193,102 @@ func (t *TelegramClient) getReactionLimit(ctx context.Context, sender networkid.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *TelegramClient) pollForReactions(ctx context.Context, portalKey networkid.PortalKey, inputPeer tg.InputPeerClass) error {
|
||||||
|
log := zerolog.Ctx(ctx).With().
|
||||||
|
Stringer("portal_key", portalKey).
|
||||||
|
Str("action", "poll_for_reactions").
|
||||||
|
Logger()
|
||||||
|
|
||||||
|
log.Debug().Msg("Polling reactions for recent messages")
|
||||||
|
|
||||||
|
messages, err := t.main.Bridge.DB.Message.GetLastNInPortal(ctx, portalKey, 20)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
messageIDs := make([]int, len(messages))
|
||||||
|
for i, msg := range messages {
|
||||||
|
_, messageIDs[i], err = ids.ParseMessageID(msg.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updates, err := APICallWithUpdates(ctx, t, func() (*tg.Updates, error) {
|
||||||
|
u, err := t.client.API().MessagesGetMessagesReactions(ctx, &tg.MessagesGetMessagesReactionsRequest{
|
||||||
|
Peer: inputPeer,
|
||||||
|
ID: messageIDs,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if updates, ok := u.(*tg.Updates); ok {
|
||||||
|
return updates, nil
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("unexpected updates type %T", u)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get messages reactions: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, update := range updates.Updates {
|
||||||
|
if reaction, ok := update.(*tg.UpdateMessageReactions); ok {
|
||||||
|
dbMsg, err := t.main.Bridge.DB.Message.GetFirstPartByID(ctx, t.loginID, ids.MakeMessageID(portalKey, reaction.MsgID))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get message from database: %w", err)
|
||||||
|
} else if dbMsg == nil {
|
||||||
|
return fmt.Errorf("message not found in database: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
reactionsList, isFull, customEmojis, err := t.computeReactionsList(ctx, reaction.Peer, reaction.MsgID, reaction.Reactions)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to compute reactions list: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
users := map[networkid.UserID]*bridgev2.ReactionSyncUser{}
|
||||||
|
for _, reaction := range reactionsList {
|
||||||
|
peer, ok := reaction.PeerID.(*tg.PeerUser)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unknown peer type %T", reaction.PeerID)
|
||||||
|
}
|
||||||
|
userID := ids.MakeUserID(peer.UserID)
|
||||||
|
reactionLimit, err := t.getReactionLimit(ctx, userID)
|
||||||
|
if err != nil {
|
||||||
|
reactionLimit = 1
|
||||||
|
log.Err(err).Int64("id", peer.UserID).Msg("failed to get reaction limit")
|
||||||
|
}
|
||||||
|
if _, ok := users[userID]; !ok {
|
||||||
|
users[userID] = &bridgev2.ReactionSyncUser{HasAllReactions: isFull, MaxCount: reactionLimit}
|
||||||
|
}
|
||||||
|
|
||||||
|
emojiID, emoji, err := computeEmojiAndID(reaction.Reaction, customEmojis)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to compute emoji and ID: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
users[userID].Reactions = append(users[userID].Reactions, &bridgev2.BackfillReaction{
|
||||||
|
Timestamp: time.Unix(int64(reaction.Date), 0),
|
||||||
|
Sender: t.senderForUserID(peer.UserID),
|
||||||
|
EmojiID: emojiID,
|
||||||
|
Emoji: emoji,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
t.main.Bridge.QueueRemoteEvent(t.userLogin, &simplevent.ReactionSync{
|
||||||
|
EventMeta: simplevent.EventMeta{
|
||||||
|
Type: bridgev2.RemoteEventReactionSync,
|
||||||
|
LogContext: func(c zerolog.Context) zerolog.Context {
|
||||||
|
return c.Int("message_id", reaction.MsgID)
|
||||||
|
},
|
||||||
|
PortalKey: dbMsg.Room,
|
||||||
|
},
|
||||||
|
TargetMessage: dbMsg.ID,
|
||||||
|
Reactions: &bridgev2.ReactionSyncData{Users: users, HasAllUsers: isFull},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
log.Warn().Type("update_type", update).Msg("Unexpected update type in get reactions response")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -584,6 +584,9 @@ func (t *TelegramClient) onMessageEdit(ctx context.Context, update IGetMessage)
|
|||||||
ce.ModifiedParts = append(ce.ModifiedParts, part.ToEditPart(existing[i]))
|
ce.ModifiedParts = append(ce.ModifiedParts, part.ToEditPart(existing[i]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(ce.ModifiedParts) == 0 {
|
||||||
|
return nil, bridgev2.ErrIgnoringRemoteEvent
|
||||||
|
}
|
||||||
return &ce, nil
|
return &ce, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user