mirror of
https://github.com/mautrix/telegram.git
synced 2026-05-17 07:25:46 +03:00
reactions: use allowed reactions when possible
Signed-off-by: Sumner Evans <sumner.evans@automattic.com>
This commit is contained in:
@@ -49,4 +49,5 @@ func migrateLegacyConfig(helper up.Helper) {
|
||||
bridgeconfig.CopyToOtherLocation(helper, up.Int, []string{"bridge", "sync_update_limit"}, []string{"network", "sync", "update_limit"})
|
||||
bridgeconfig.CopyToOtherLocation(helper, up.Int, []string{"bridge", "sync_create_limit"}, []string{"network", "sync", "create_limit"})
|
||||
bridgeconfig.CopyToOtherLocation(helper, up.Bool, []string{"bridge", "sync_direct_chats"}, []string{"network", "sync", "direct_chats"})
|
||||
bridgeconfig.CopyToOtherLocation(helper, up.Bool, []string{"bridge", "always_custom_emoji_reaction"}, []string{"network", "always_custom_emoji_reaction"})
|
||||
}
|
||||
|
||||
@@ -44,9 +44,15 @@ type TelegramClient struct {
|
||||
updatesManager *updates.Manager
|
||||
clientCancel context.CancelFunc
|
||||
|
||||
appConfigLock sync.Mutex
|
||||
appConfig map[string]any
|
||||
appConfigHash int
|
||||
|
||||
availableReactionsLock sync.Mutex
|
||||
availableReactions map[string]struct{}
|
||||
availableReactionsHash int
|
||||
availableReactionsFetched time.Time
|
||||
|
||||
telegramFmtParams *telegramfmt.FormatParams
|
||||
matrixParser *matrixfmt.HTMLParser
|
||||
|
||||
|
||||
@@ -63,6 +63,8 @@ type TelegramConfig struct {
|
||||
CreateLimit int `yaml:"create_limit"`
|
||||
DirectChats bool `yaml:"direct_chats"`
|
||||
} `yaml:"sync"`
|
||||
|
||||
AlwaysCustomEmojiReaction bool `yaml:"always_custom_emoji_reaction"`
|
||||
}
|
||||
|
||||
func (c TelegramConfig) ShouldBridge(participantCount int) bool {
|
||||
@@ -96,6 +98,7 @@ func upgradeConfig(helper up.Helper) {
|
||||
helper.Copy(up.Int, "sync", "update_limit")
|
||||
helper.Copy(up.Int, "sync", "create_limit")
|
||||
helper.Copy(up.Bool, "sync", "direct_chats")
|
||||
helper.Copy(up.Bool, "always_custom_emoji_reaction")
|
||||
}
|
||||
|
||||
func (tg *TelegramConnector) GetConfig() (example string, data any, upgrader up.Upgrader) {
|
||||
|
||||
@@ -70,3 +70,9 @@ sync:
|
||||
create_limit: 15
|
||||
# Whether or not to sync and create portals for direct chats at startup.
|
||||
direct_chats: false
|
||||
|
||||
|
||||
# Should the bridge send all unicode reactions as custom emoji reactions to
|
||||
# Telegram? By default, the bridge only uses custom emojis for unicode emojis
|
||||
# that aren't allowed in reactions.
|
||||
always_custom_emoji_reaction: false
|
||||
|
||||
@@ -285,6 +285,11 @@ func (t *TelegramClient) HandleMatrixMessageRemove(ctx context.Context, msg *bri
|
||||
}
|
||||
|
||||
func (t *TelegramClient) PreHandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (bridgev2.MatrixReactionPreResponse, error) {
|
||||
log := zerolog.Ctx(ctx).With().
|
||||
Str("conversion_direction", "to_telegram").
|
||||
Str("handler", "pre_handle_matrix_reaction").
|
||||
Str("key", msg.Content.RelatesTo.Key).
|
||||
Logger()
|
||||
var resp bridgev2.MatrixReactionPreResponse
|
||||
|
||||
var maxReactions int
|
||||
@@ -293,7 +298,8 @@ func (t *TelegramClient) PreHandleMatrixReaction(ctx context.Context, msg *bridg
|
||||
return resp, err
|
||||
}
|
||||
|
||||
var emojiID networkid.EmojiID
|
||||
keyNoVariation := variationselector.Remove(msg.Content.RelatesTo.Key)
|
||||
emojiID := ids.MakeEmojiIDFromEmoticon(msg.Content.RelatesTo.Key)
|
||||
if strings.HasPrefix(msg.Content.RelatesTo.Key, "mxc://") {
|
||||
if file, err := t.main.Store.TelegramFile.GetByMXC(ctx, msg.Content.RelatesTo.Key); err != nil {
|
||||
return resp, err
|
||||
@@ -304,12 +310,25 @@ func (t *TelegramClient) PreHandleMatrixReaction(ctx context.Context, msg *bridg
|
||||
} else {
|
||||
emojiID = ids.MakeEmojiIDFromDocumentID(documentID)
|
||||
}
|
||||
} else if documentID, ok := emojis.GetEmojiDocumentID(msg.Content.RelatesTo.Key); ok {
|
||||
emojiID = ids.MakeEmojiIDFromDocumentID(documentID)
|
||||
} else if t.main.Config.AlwaysCustomEmojiReaction {
|
||||
// Always use the unicodemoji reaction if available
|
||||
if documentID, ok := emojis.GetEmojiDocumentID(keyNoVariation); ok {
|
||||
log.Debug().Msg("Using custom emoji reaction")
|
||||
emojiID = ids.MakeEmojiIDFromDocumentID(documentID)
|
||||
}
|
||||
} else if availableReactions, err := t.getAvailableReactions(ctx); err != nil {
|
||||
return resp, fmt.Errorf("failed to get available reactions: %w", err)
|
||||
} else if _, ok := availableReactions[keyNoVariation]; ok {
|
||||
log.Debug().Msg("Not using custom emoji reaction since the emoji is available")
|
||||
} else {
|
||||
emojiID = ids.MakeEmojiIDFromEmoticon(msg.Content.RelatesTo.Key)
|
||||
if documentID, ok := emojis.GetEmojiDocumentID(keyNoVariation); ok {
|
||||
log.Debug().Msg("Using custom emoji reaction")
|
||||
emojiID = ids.MakeEmojiIDFromDocumentID(documentID)
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug().Str("emoji_id", string(emojiID)).Msg("Pre-handled reaction")
|
||||
|
||||
return bridgev2.MatrixReactionPreResponse{
|
||||
SenderID: t.userID,
|
||||
EmojiID: emojiID,
|
||||
|
||||
@@ -515,6 +515,8 @@ func (t *TelegramClient) inputPeerForPortalID(ctx context.Context, portalID netw
|
||||
}
|
||||
|
||||
func (t *TelegramClient) getAppConfigCached(ctx context.Context) (map[string]any, error) {
|
||||
t.appConfigLock.Lock()
|
||||
defer t.appConfigLock.Unlock()
|
||||
if t.appConfig == nil {
|
||||
cfg, err := t.client.API().HelpGetAppConfig(ctx, t.appConfigHash)
|
||||
if err != nil {
|
||||
@@ -537,6 +539,46 @@ func (t *TelegramClient) getAppConfigCached(ctx context.Context) (map[string]any
|
||||
return t.appConfig, nil
|
||||
}
|
||||
|
||||
func (t *TelegramClient) getAvailableReactions(ctx context.Context) (map[string]struct{}, error) {
|
||||
log := zerolog.Ctx(ctx).With().Str("handler", "get_available_reactions").Logger()
|
||||
t.availableReactionsLock.Lock()
|
||||
defer t.availableReactionsLock.Unlock()
|
||||
if t.availableReactions == nil || time.Since(t.availableReactionsFetched) > 12*time.Hour {
|
||||
cfg, err := t.client.API().MessagesGetAvailableReactions(ctx, t.availableReactionsHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t.availableReactionsFetched = time.Now()
|
||||
switch v := cfg.(type) {
|
||||
case *tg.MessagesAvailableReactions:
|
||||
availableReactions, ok := cfg.(*tg.MessagesAvailableReactions)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to get app config: unexpected type %T", availableReactions)
|
||||
}
|
||||
|
||||
log.Debug().Msg("Fetched new available reactions")
|
||||
|
||||
myGhost, err := t.main.Bridge.GetGhostByID(ctx, t.userID)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to get own ghost")
|
||||
}
|
||||
t.availableReactions = make(map[string]struct{}, len(availableReactions.Reactions))
|
||||
for _, reaction := range availableReactions.Reactions {
|
||||
if !reaction.Inactive && (myGhost.Metadata.(*GhostMetadata).IsPremium || !reaction.Premium) {
|
||||
t.availableReactions[reaction.Reaction] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
t.availableReactionsHash = availableReactions.Hash
|
||||
case *tg.MessagesAvailableReactionsNotModified:
|
||||
log.Debug().Msg("Available reactions not modified")
|
||||
default:
|
||||
log.Error().Type("reaction_type", v).Msg("failed to get available reactions: unexpected type")
|
||||
}
|
||||
}
|
||||
return t.availableReactions, nil
|
||||
}
|
||||
|
||||
func (t *TelegramClient) transferEmojisToMatrix(ctx context.Context, customEmojiIDs []int64) (result map[networkid.EmojiID]string, err error) {
|
||||
result, customEmojiIDs = emojis.ConvertKnownEmojis(customEmojiIDs)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user