reactions: support deletions
Signed-off-by: Sumner Evans <sumner.evans@automattic.com>
This commit is contained in:
+28
-24
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@@ -24,14 +23,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type TelegramClient struct {
|
type TelegramClient struct {
|
||||||
main *TelegramConnector
|
main *TelegramConnector
|
||||||
loginID int64
|
telegramUserID int64
|
||||||
userLogin *bridgev2.UserLogin
|
loginID networkid.UserLoginID
|
||||||
client *telegram.Client
|
userID networkid.UserID
|
||||||
clientCancel context.CancelFunc
|
userLogin *bridgev2.UserLogin
|
||||||
msgConv *msgconv.MessageConverter
|
client *telegram.Client
|
||||||
|
clientCancel context.CancelFunc
|
||||||
|
msgConv *msgconv.MessageConverter
|
||||||
|
|
||||||
reactionMessageLocks map[int]*sync.Mutex
|
reactionMessageLocks map[int]*sync.Mutex
|
||||||
|
|
||||||
|
appConfig map[string]any
|
||||||
|
appConfigHash int
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -74,22 +78,24 @@ func (u UpdateDispatcher) Handle(ctx context.Context, updates tg.UpdatesClass) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewTelegramClient(ctx context.Context, tc *TelegramConnector, login *bridgev2.UserLogin) (*TelegramClient, error) {
|
func NewTelegramClient(ctx context.Context, tc *TelegramConnector, login *bridgev2.UserLogin) (*TelegramClient, error) {
|
||||||
loginID, err := strconv.ParseInt(string(login.ID), 10, 64)
|
telegramUserID, err := ids.ParseUserLoginID(login.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log := zerolog.Ctx(ctx).With().
|
log := zerolog.Ctx(ctx).With().
|
||||||
Str("component", "telegram_client").
|
Str("component", "telegram_client").
|
||||||
Int64("login_id", loginID).
|
Str("user_login_id", string(login.ID)).
|
||||||
Logger()
|
Logger()
|
||||||
|
|
||||||
zaplog := zap.New(zerozap.New(log))
|
zaplog := zap.New(zerozap.New(log))
|
||||||
|
|
||||||
client := TelegramClient{
|
client := TelegramClient{
|
||||||
main: tc,
|
main: tc,
|
||||||
loginID: loginID,
|
telegramUserID: telegramUserID,
|
||||||
userLogin: login,
|
loginID: login.ID,
|
||||||
|
userID: networkid.UserID(login.ID),
|
||||||
|
userLogin: login,
|
||||||
}
|
}
|
||||||
dispatcher := UpdateDispatcher{
|
dispatcher := UpdateDispatcher{
|
||||||
UpdateDispatcher: tg.NewUpdateDispatcher(),
|
UpdateDispatcher: tg.NewUpdateDispatcher(),
|
||||||
@@ -101,7 +107,7 @@ func NewTelegramClient(ctx context.Context, tc *TelegramConnector, login *bridge
|
|||||||
dispatcher.OnDeleteMessages(client.onDeleteMessages)
|
dispatcher.OnDeleteMessages(client.onDeleteMessages)
|
||||||
dispatcher.OnEditMessage(client.onMessageEdit)
|
dispatcher.OnEditMessage(client.onMessageEdit)
|
||||||
|
|
||||||
store := tc.Store.GetScopedStore(loginID)
|
store := tc.Store.GetScopedStore(telegramUserID)
|
||||||
|
|
||||||
updatesManager := updates.New(updates.Config{
|
updatesManager := updates.New(updates.Config{
|
||||||
OnChannelTooLong: func(channelID int64) {
|
OnChannelTooLong: func(channelID int64) {
|
||||||
@@ -123,7 +129,7 @@ func NewTelegramClient(ctx context.Context, tc *TelegramConnector, login *bridge
|
|||||||
client.clientCancel, err = connectTelegramClient(ctx, client.client)
|
client.clientCancel, err = connectTelegramClient(ctx, client.client)
|
||||||
client.reactionMessageLocks = map[int]*sync.Mutex{}
|
client.reactionMessageLocks = map[int]*sync.Mutex{}
|
||||||
go func() {
|
go func() {
|
||||||
err = updatesManager.Run(ctx, client.client.API(), loginID, updates.AuthOptions{})
|
err = updatesManager.Run(ctx, client.client.API(), telegramUserID, updates.AuthOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg("updates manager error")
|
log.Err(err).Msg("updates manager error")
|
||||||
client.clientCancel()
|
client.clientCancel()
|
||||||
@@ -165,9 +171,6 @@ func connectTelegramClient(ctx context.Context, client *telegram.Client) (contex
|
|||||||
return cancel, nil
|
return cancel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func (t *TelegramClient) Connect(ctx context.Context) (err error) {
|
func (t *TelegramClient) Connect(ctx context.Context) (err error) {
|
||||||
t.clientCancel, err = connectTelegramClient(ctx, t.client)
|
t.clientCancel, err = connectTelegramClient(ctx, t.client)
|
||||||
return
|
return
|
||||||
@@ -213,8 +216,8 @@ func (t *TelegramClient) GetChatInfo(ctx context.Context, portal *bridgev2.Porta
|
|||||||
{
|
{
|
||||||
EventSender: bridgev2.EventSender{
|
EventSender: bridgev2.EventSender{
|
||||||
IsFromMe: true,
|
IsFromMe: true,
|
||||||
SenderLogin: ids.MakeUserLoginID(t.loginID),
|
SenderLogin: t.loginID,
|
||||||
Sender: ids.MakeUserID(t.loginID),
|
Sender: t.userID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -250,7 +253,7 @@ func (t *TelegramClient) GetChatInfo(ctx context.Context, portal *bridgev2.Porta
|
|||||||
for _, user := range fullChat.Users {
|
for _, user := range fullChat.Users {
|
||||||
memberList.Members = append(memberList.Members, bridgev2.ChatMember{
|
memberList.Members = append(memberList.Members, bridgev2.ChatMember{
|
||||||
EventSender: bridgev2.EventSender{
|
EventSender: bridgev2.EventSender{
|
||||||
IsFromMe: user.GetID() == t.loginID,
|
IsFromMe: user.GetID() == t.telegramUserID,
|
||||||
SenderLogin: ids.MakeUserLoginID(user.GetID()),
|
SenderLogin: ids.MakeUserLoginID(user.GetID()),
|
||||||
Sender: ids.MakeUserID(user.GetID()),
|
Sender: ids.MakeUserID(user.GetID()),
|
||||||
},
|
},
|
||||||
@@ -316,10 +319,11 @@ func (t *TelegramClient) getUserInfoFromTelegramUser(user *tg.User) (*bridgev2.U
|
|||||||
|
|
||||||
name := util.FormatFullName(user.FirstName, user.LastName)
|
name := util.FormatFullName(user.FirstName, user.LastName)
|
||||||
return &bridgev2.UserInfo{
|
return &bridgev2.UserInfo{
|
||||||
IsBot: &user.Bot,
|
IsBot: &user.Bot,
|
||||||
Name: &name,
|
Name: &name,
|
||||||
Avatar: avatar,
|
Avatar: avatar,
|
||||||
Identifiers: identifiers,
|
Identifiers: identifiers,
|
||||||
|
ExtraUpdates: bridgev2.SimpleMetadataUpdater[*bridgev2.Ghost]("fi.mau.telegram.is_premium", user.Premium),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ func ParseUserID(userID networkid.UserID) (int64, error) {
|
|||||||
return strconv.ParseInt(string(userID), 10, 64)
|
return strconv.ParseInt(string(userID), 10, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ParseUserLoginID(userID networkid.UserLoginID) (int64, error) {
|
||||||
|
return strconv.ParseInt(string(userID), 10, 64)
|
||||||
|
}
|
||||||
|
|
||||||
func MakeUserLoginID(userID int64) networkid.UserLoginID {
|
func MakeUserLoginID(userID int64) networkid.UserLoginID {
|
||||||
return networkid.UserLoginID(strconv.FormatInt(userID, 10))
|
return networkid.UserLoginID(strconv.FormatInt(userID, 10))
|
||||||
}
|
}
|
||||||
|
|||||||
+63
-16
@@ -157,7 +157,7 @@ func (t *TelegramClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.
|
|||||||
ID: ids.MakeMessageID(tgMessageID),
|
ID: ids.MakeMessageID(tgMessageID),
|
||||||
MXID: msg.Event.ID,
|
MXID: msg.Event.ID,
|
||||||
Room: networkid.PortalKey{ID: msg.Portal.ID},
|
Room: networkid.PortalKey{ID: msg.Portal.ID},
|
||||||
SenderID: ids.MakeUserID(t.loginID),
|
SenderID: t.userID,
|
||||||
Timestamp: time.Unix(int64(tgDate), 0),
|
Timestamp: time.Unix(int64(tgDate), 0),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -182,9 +182,8 @@ func (t *TelegramClient) HandleMatrixMessageRemove(ctx context.Context, msg *bri
|
|||||||
func (t *TelegramClient) PreHandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (bridgev2.MatrixReactionPreResponse, error) {
|
func (t *TelegramClient) PreHandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (bridgev2.MatrixReactionPreResponse, error) {
|
||||||
var resp bridgev2.MatrixReactionPreResponse
|
var resp bridgev2.MatrixReactionPreResponse
|
||||||
|
|
||||||
sender := ids.MakeUserID(t.loginID)
|
|
||||||
var maxReactions int
|
var maxReactions int
|
||||||
maxReactions, err := t.getReactionLimit(ctx, sender)
|
maxReactions, err := t.getReactionLimit(ctx, t.userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
@@ -207,13 +206,23 @@ func (t *TelegramClient) PreHandleMatrixReaction(ctx context.Context, msg *bridg
|
|||||||
}
|
}
|
||||||
|
|
||||||
return bridgev2.MatrixReactionPreResponse{
|
return bridgev2.MatrixReactionPreResponse{
|
||||||
SenderID: sender,
|
SenderID: t.userID,
|
||||||
EmojiID: emojiID,
|
EmojiID: emojiID,
|
||||||
Emoji: variationselector.FullyQualify(msg.Content.RelatesTo.Key),
|
Emoji: variationselector.FullyQualify(msg.Content.RelatesTo.Key),
|
||||||
MaxReactions: maxReactions,
|
MaxReactions: maxReactions,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *TelegramClient) appendEmojiID(reactionList []tg.ReactionClass, emojiID networkid.EmojiID) ([]tg.ReactionClass, error) {
|
||||||
|
if documentID, emoticon, err := ids.ParseEmojiID(emojiID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if documentID > 0 {
|
||||||
|
return append(reactionList, &tg.ReactionCustomEmoji{DocumentID: documentID}), nil
|
||||||
|
} else {
|
||||||
|
return append(reactionList, &tg.ReactionEmoji{Emoticon: emoticon}), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (t *TelegramClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (reaction *database.Reaction, err error) {
|
func (t *TelegramClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (reaction *database.Reaction, err error) {
|
||||||
peer, err := ids.InputPeerForPortalID(msg.Portal.ID)
|
peer, err := ids.InputPeerForPortalID(msg.Portal.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -224,25 +233,63 @@ func (t *TelegramClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req := tg.MessagesSendReactionRequest{
|
var newReactions []tg.ReactionClass
|
||||||
|
for _, existing := range msg.ExistingReactionsToKeep {
|
||||||
|
newReactions, err = t.appendEmojiID(newReactions, existing.EmojiID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newReactions, err = t.appendEmojiID(newReactions, msg.PreHandleResp.EmojiID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = t.client.API().MessagesSendReaction(ctx, &tg.MessagesSendReactionRequest{
|
||||||
Peer: peer,
|
Peer: peer,
|
||||||
AddToRecent: true,
|
AddToRecent: true,
|
||||||
MsgID: targetMessageID,
|
MsgID: targetMessageID,
|
||||||
}
|
Reaction: newReactions,
|
||||||
if documentID, emoticon, err := ids.ParseEmojiID(msg.PreHandleResp.EmojiID); err != nil {
|
})
|
||||||
return nil, err
|
|
||||||
} else if documentID > 0 {
|
|
||||||
req.SetReaction([]tg.ReactionClass{&tg.ReactionCustomEmoji{DocumentID: documentID}})
|
|
||||||
} else {
|
|
||||||
req.SetReaction([]tg.ReactionClass{&tg.ReactionEmoji{Emoticon: emoticon}})
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = t.client.API().MessagesSendReaction(ctx, &req)
|
|
||||||
return &database.Reaction{}, err
|
return &database.Reaction{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TelegramClient) HandleMatrixReactionRemove(ctx context.Context, msg *bridgev2.MatrixReactionRemove) error {
|
func (t *TelegramClient) HandleMatrixReactionRemove(ctx context.Context, msg *bridgev2.MatrixReactionRemove) error {
|
||||||
panic("unimplemented reaction remove")
|
peer, err := ids.InputPeerForPortalID(msg.Portal.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var newReactions []tg.ReactionClass
|
||||||
|
|
||||||
|
if maxReactions, err := t.getReactionLimit(ctx, t.userID); err != nil {
|
||||||
|
return err
|
||||||
|
} else if maxReactions > 1 {
|
||||||
|
existing, err := t.main.Bridge.DB.Reaction.GetAllToMessageBySender(ctx, msg.TargetReaction.MessageID, msg.TargetReaction.SenderID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, existing := range existing {
|
||||||
|
if msg.TargetReaction.EmojiID != existing.EmojiID {
|
||||||
|
newReactions, err = t.appendEmojiID(newReactions, existing.EmojiID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
messageID, err := ids.ParseMessageID(msg.TargetReaction.MessageID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = t.client.API().MessagesSendReaction(ctx, &tg.MessagesSendReactionRequest{
|
||||||
|
Peer: peer,
|
||||||
|
AddToRecent: true,
|
||||||
|
MsgID: messageID,
|
||||||
|
Reaction: newReactions,
|
||||||
|
})
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TelegramClient) HandleMatrixReadReceipt(ctx context.Context, msg *bridgev2.MatrixReadReceipt) error {
|
func (t *TelegramClient) HandleMatrixReadReceipt(ctx context.Context, msg *bridgev2.MatrixReadReceipt) error {
|
||||||
|
|||||||
+46
-18
@@ -16,6 +16,7 @@ import (
|
|||||||
"go.mau.fi/mautrix-telegram/pkg/connector/emojis"
|
"go.mau.fi/mautrix-telegram/pkg/connector/emojis"
|
||||||
"go.mau.fi/mautrix-telegram/pkg/connector/ids"
|
"go.mau.fi/mautrix-telegram/pkg/connector/ids"
|
||||||
"go.mau.fi/mautrix-telegram/pkg/connector/media"
|
"go.mau.fi/mautrix-telegram/pkg/connector/media"
|
||||||
|
"go.mau.fi/mautrix-telegram/pkg/connector/tljson"
|
||||||
"go.mau.fi/mautrix-telegram/pkg/connector/util"
|
"go.mau.fi/mautrix-telegram/pkg/connector/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -119,8 +120,8 @@ type messageWithSender interface {
|
|||||||
func (t *TelegramClient) getEventSender(msg messageWithSender) (sender bridgev2.EventSender) {
|
func (t *TelegramClient) getEventSender(msg messageWithSender) (sender bridgev2.EventSender) {
|
||||||
if msg.GetOut() {
|
if msg.GetOut() {
|
||||||
sender.IsFromMe = true
|
sender.IsFromMe = true
|
||||||
sender.SenderLogin = ids.MakeUserLoginID(t.loginID)
|
sender.SenderLogin = t.loginID
|
||||||
sender.Sender = ids.MakeUserID(t.loginID)
|
sender.Sender = t.userID
|
||||||
} else if f, ok := msg.GetFromID(); ok {
|
} else if f, ok := msg.GetFromID(); ok {
|
||||||
switch from := f.(type) {
|
switch from := f.(type) {
|
||||||
case *tg.PeerUser:
|
case *tg.PeerUser:
|
||||||
@@ -160,7 +161,7 @@ func (t *TelegramClient) onUserName(ctx context.Context, e tg.Entities, update *
|
|||||||
|
|
||||||
func (t *TelegramClient) onDeleteMessages(ctx context.Context, e tg.Entities, update *tg.UpdateDeleteMessages) error {
|
func (t *TelegramClient) onDeleteMessages(ctx context.Context, e tg.Entities, update *tg.UpdateDeleteMessages) error {
|
||||||
for _, messageID := range update.Messages {
|
for _, messageID := range update.Messages {
|
||||||
parts, err := t.main.Bridge.DB.Message.GetAllPartsByID(ctx, ids.MakeUserLoginID(t.loginID), ids.MakeMessageID(messageID))
|
parts, err := t.main.Bridge.DB.Message.GetAllPartsByID(ctx, t.loginID, ids.MakeMessageID(messageID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -243,7 +244,7 @@ func (t *TelegramClient) handleTelegramReactions(ctx context.Context, msg *tg.Me
|
|||||||
// self.log.warning(f"Can see reaction list in channel ({data!s})")
|
// self.log.warning(f"Can see reaction list in channel ({data!s})")
|
||||||
// # return
|
// # return
|
||||||
|
|
||||||
dbMsg, err := t.main.Bridge.DB.Message.GetFirstPartByID(ctx, ids.MakeUserLoginID(t.loginID), ids.MakeMessageID(msg.ID))
|
dbMsg, err := t.main.Bridge.DB.Message.GetFirstPartByID(ctx, t.loginID, ids.MakeMessageID(msg.ID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if dbMsg == nil {
|
} else if dbMsg == nil {
|
||||||
@@ -252,7 +253,7 @@ func (t *TelegramClient) handleTelegramReactions(ctx context.Context, msg *tg.Me
|
|||||||
|
|
||||||
if len(reactionsList) < totalCount {
|
if len(reactionsList) < totalCount {
|
||||||
if user, ok := msg.PeerID.(*tg.PeerUser); ok {
|
if user, ok := msg.PeerID.(*tg.PeerUser); ok {
|
||||||
reactionsList = splitDMReactionCounts(msg.Reactions.Results, user.UserID, t.loginID)
|
reactionsList = splitDMReactionCounts(msg.Reactions.Results, user.UserID, t.telegramUserID)
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// } else if t.isBot {
|
// } else if t.isBot {
|
||||||
@@ -318,13 +319,44 @@ func splitDMReactionCounts(res []tg.ReactionCount, theirUserID, myUserID int64)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TelegramClient) getReactionLimit(ctx context.Context, sender networkid.UserID) (int, error) {
|
func (t *TelegramClient) getAppConfigCached(ctx context.Context) (map[string]any, error) {
|
||||||
// TODO implement this correctly (probably need to put something into metadata)
|
if t.appConfig == nil {
|
||||||
// ghost, err := t.main.Bridge.GetGhostByID(ctx, sender)
|
cfg, err := t.client.API().HelpGetAppConfig(ctx, t.appConfigHash)
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// return 0, err
|
return nil, err
|
||||||
// }
|
}
|
||||||
return 1, nil
|
appConfig, ok := cfg.(*tg.HelpAppConfig)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("failed to get app config: unexpected type %T", appConfig)
|
||||||
|
}
|
||||||
|
parsedConfig, err := tljson.Parse(appConfig.Config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
t.appConfig, ok = parsedConfig.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("failed to parse app config: unexpected type %T", t.appConfig)
|
||||||
|
}
|
||||||
|
t.appConfigHash = appConfig.Hash
|
||||||
|
}
|
||||||
|
return t.appConfig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TelegramClient) getReactionLimit(ctx context.Context, sender networkid.UserID) (limit int, err error) {
|
||||||
|
config, err := t.getAppConfigCached(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ghost, err := t.main.Bridge.GetGhostByID(ctx, sender)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if isPremium, ok := ghost.Metadata.Extra["fi.mau.telegram.is_premium"].(bool); ok && isPremium {
|
||||||
|
return int(config["reactions_user_max_premium"].(float64)), nil
|
||||||
|
} else {
|
||||||
|
return int(config["reactions_user_max_default"].(float64)), nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TelegramClient) transferEmojisToMatrix(ctx context.Context, customEmojiIDs []int64) (result map[networkid.EmojiID]string, err error) {
|
func (t *TelegramClient) transferEmojisToMatrix(ctx context.Context, customEmojiIDs []int64) (result map[networkid.EmojiID]string, err error) {
|
||||||
@@ -430,10 +462,6 @@ func (t *TelegramClient) handleTelegramParsedReactionsLocked(ctx context.Context
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range removed {
|
for _, r := range removed {
|
||||||
senderID, err := ids.ParseUserID(r.SenderID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
evt := &bridgev2.SimpleRemoteEvent[any]{
|
evt := &bridgev2.SimpleRemoteEvent[any]{
|
||||||
Type: bridgev2.RemoteEventReactionRemove,
|
Type: bridgev2.RemoteEventReactionRemove,
|
||||||
LogContext: func(c zerolog.Context) zerolog.Context {
|
LogContext: func(c zerolog.Context) zerolog.Context {
|
||||||
@@ -443,8 +471,8 @@ func (t *TelegramClient) handleTelegramParsedReactionsLocked(ctx context.Context
|
|||||||
Str("message_id", string(msg.ID))
|
Str("message_id", string(msg.ID))
|
||||||
},
|
},
|
||||||
Sender: bridgev2.EventSender{
|
Sender: bridgev2.EventSender{
|
||||||
IsFromMe: t.loginID == senderID,
|
IsFromMe: t.userID == r.SenderID,
|
||||||
SenderLogin: ids.MakeUserLoginID(senderID),
|
SenderLogin: t.loginID,
|
||||||
Sender: r.SenderID,
|
Sender: r.SenderID,
|
||||||
},
|
},
|
||||||
PortalKey: msg.Room,
|
PortalKey: msg.Room,
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package tljson
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/gotd/td/tg"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Parse(v tg.JSONValueClass) (out any, err error) {
|
||||||
|
switch val := v.(type) {
|
||||||
|
case *tg.JSONBool:
|
||||||
|
return val.Value, nil
|
||||||
|
case *tg.JSONNumber:
|
||||||
|
return val.Value, nil
|
||||||
|
case *tg.JSONString:
|
||||||
|
return val.Value, nil
|
||||||
|
case *tg.JSONArray:
|
||||||
|
out := make([]any, len(val.Value))
|
||||||
|
for i, entry := range val.Value {
|
||||||
|
out[i], err = Parse(entry)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
case *tg.JSONObject:
|
||||||
|
out := make(map[string]any, len(val.Value))
|
||||||
|
for _, entry := range val.Value {
|
||||||
|
out[entry.Key], err = Parse(entry.Value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
case *tg.JSONNull:
|
||||||
|
return nil, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown JSON value type %T", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user