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_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.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", "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
|
updatesManager *updates.Manager
|
||||||
clientCancel context.CancelFunc
|
clientCancel context.CancelFunc
|
||||||
|
|
||||||
|
appConfigLock sync.Mutex
|
||||||
appConfig map[string]any
|
appConfig map[string]any
|
||||||
appConfigHash int
|
appConfigHash int
|
||||||
|
|
||||||
|
availableReactionsLock sync.Mutex
|
||||||
|
availableReactions map[string]struct{}
|
||||||
|
availableReactionsHash int
|
||||||
|
availableReactionsFetched time.Time
|
||||||
|
|
||||||
telegramFmtParams *telegramfmt.FormatParams
|
telegramFmtParams *telegramfmt.FormatParams
|
||||||
matrixParser *matrixfmt.HTMLParser
|
matrixParser *matrixfmt.HTMLParser
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ type TelegramConfig struct {
|
|||||||
CreateLimit int `yaml:"create_limit"`
|
CreateLimit int `yaml:"create_limit"`
|
||||||
DirectChats bool `yaml:"direct_chats"`
|
DirectChats bool `yaml:"direct_chats"`
|
||||||
} `yaml:"sync"`
|
} `yaml:"sync"`
|
||||||
|
|
||||||
|
AlwaysCustomEmojiReaction bool `yaml:"always_custom_emoji_reaction"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c TelegramConfig) ShouldBridge(participantCount int) bool {
|
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", "update_limit")
|
||||||
helper.Copy(up.Int, "sync", "create_limit")
|
helper.Copy(up.Int, "sync", "create_limit")
|
||||||
helper.Copy(up.Bool, "sync", "direct_chats")
|
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) {
|
func (tg *TelegramConnector) GetConfig() (example string, data any, upgrader up.Upgrader) {
|
||||||
|
|||||||
@@ -70,3 +70,9 @@ sync:
|
|||||||
create_limit: 15
|
create_limit: 15
|
||||||
# Whether or not to sync and create portals for direct chats at startup.
|
# Whether or not to sync and create portals for direct chats at startup.
|
||||||
direct_chats: false
|
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
|
||||||
|
|||||||
+23
-4
@@ -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) {
|
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 resp bridgev2.MatrixReactionPreResponse
|
||||||
|
|
||||||
var maxReactions int
|
var maxReactions int
|
||||||
@@ -293,7 +298,8 @@ func (t *TelegramClient) PreHandleMatrixReaction(ctx context.Context, msg *bridg
|
|||||||
return resp, err
|
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 strings.HasPrefix(msg.Content.RelatesTo.Key, "mxc://") {
|
||||||
if file, err := t.main.Store.TelegramFile.GetByMXC(ctx, msg.Content.RelatesTo.Key); err != nil {
|
if file, err := t.main.Store.TelegramFile.GetByMXC(ctx, msg.Content.RelatesTo.Key); err != nil {
|
||||||
return resp, err
|
return resp, err
|
||||||
@@ -304,12 +310,25 @@ func (t *TelegramClient) PreHandleMatrixReaction(ctx context.Context, msg *bridg
|
|||||||
} else {
|
} else {
|
||||||
emojiID = ids.MakeEmojiIDFromDocumentID(documentID)
|
emojiID = ids.MakeEmojiIDFromDocumentID(documentID)
|
||||||
}
|
}
|
||||||
} else if documentID, ok := emojis.GetEmojiDocumentID(msg.Content.RelatesTo.Key); ok {
|
} else if t.main.Config.AlwaysCustomEmojiReaction {
|
||||||
emojiID = ids.MakeEmojiIDFromDocumentID(documentID)
|
// 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 {
|
} 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{
|
return bridgev2.MatrixReactionPreResponse{
|
||||||
SenderID: t.userID,
|
SenderID: t.userID,
|
||||||
EmojiID: emojiID,
|
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) {
|
func (t *TelegramClient) getAppConfigCached(ctx context.Context) (map[string]any, error) {
|
||||||
|
t.appConfigLock.Lock()
|
||||||
|
defer t.appConfigLock.Unlock()
|
||||||
if t.appConfig == nil {
|
if t.appConfig == nil {
|
||||||
cfg, err := t.client.API().HelpGetAppConfig(ctx, t.appConfigHash)
|
cfg, err := t.client.API().HelpGetAppConfig(ctx, t.appConfigHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -537,6 +539,46 @@ func (t *TelegramClient) getAppConfigCached(ctx context.Context) (map[string]any
|
|||||||
return t.appConfig, nil
|
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) {
|
func (t *TelegramClient) transferEmojisToMatrix(ctx context.Context, customEmojiIDs []int64) (result map[networkid.EmojiID]string, err error) {
|
||||||
result, customEmojiIDs = emojis.ConvertKnownEmojis(customEmojiIDs)
|
result, customEmojiIDs = emojis.ConvertKnownEmojis(customEmojiIDs)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user