diff --git a/CHANGELOG.md b/CHANGELOG.md index f1b006a3..db2044b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,10 @@ old room will be assigned to one Matrix user randomly and others will get a new room created automatically when receiving a message in the chat or when using the `!tg sync-chats` command. + * If you want shared portals, upgrade the affected groups to supergroups. + You can upgrade groups using the `!tg upgrade` command, or in the + official apps by enabling any setting that requires a supergroup + (e.g. add a member tag for any admin). * Any migration issues should be reported in the Matrix room linked in the readme. * Notable new features include: diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 6f1919cc..66dc095e 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -79,6 +79,7 @@ type TelegramClient struct { metadata *UserLoginMetadata client *telegram.Client updatesManager *updates.Manager + dispatcher tg.UpdateDispatcher clientCtx context.Context clientCancel context.CancelFunc clientDone *exsync.Event @@ -183,8 +184,8 @@ func NewTelegramClient(ctx context.Context, tc *TelegramConnector, login *bridge return &client, nil } - dispatcher := tg.NewUpdateDispatcher() - dispatcher.OnFallback(client.onUpdateWrapper) + client.dispatcher = tg.NewUpdateDispatcher() + client.dispatcher.OnFallback(client.onUpdateWrapper) client.updatesManager = updates.New(updates.Config{ OnNotChannelMember: client.onNotChannelMember, @@ -205,7 +206,7 @@ func NewTelegramClient(ctx context.Context, tc *TelegramConnector, login *bridge return resultToError(res) }, - Handler: dispatcher, + Handler: client.dispatcher, Logger: zaplog.Named("gaps"), Storage: client.ScopedStore, AccessHasher: client.ScopedStore, diff --git a/pkg/connector/commands.go b/pkg/connector/commands.go index 5d8f0d22..f816db26 100644 --- a/pkg/connector/commands.go +++ b/pkg/connector/commands.go @@ -17,6 +17,7 @@ package connector import ( + "errors" "slices" "strings" @@ -24,6 +25,8 @@ import ( "maunium.net/go/mautrix/bridgev2/commands" "maunium.net/go/mautrix/bridgev2/networkid" "maunium.net/go/mautrix/format" + + "go.mau.fi/mautrix-telegram/pkg/connector/ids" ) var cmdSyncChats = &commands.FullHandler{ @@ -58,6 +61,46 @@ func fnSyncChats(ce *commands.Event) { } } +var cmdUpgrade = &commands.FullHandler{ + Func: fnUpgrade, + Name: "upgrade", + Help: commands.HelpMeta{ + Section: commands.HelpSectionChats, + Description: "Upgrade a minigroup to a supergroup on Telegram", + }, + RequiresPortal: true, +} + +func fnUpgrade(ce *commands.Event) { + login, _, err := ce.Portal.FindPreferredLogin(ce.Ctx, ce.User, false) + if errors.Is(err, bridgev2.ErrNotLoggedIn) { + ce.Reply("No logins found to upgrade the chat.") + } else if err != nil { + ce.Log.Err(err).Msg("Failed to find preferred login for upgrade command") + ce.Reply("Failed to find a login to upgrade the chat.") + } else if peerType, chatID, _, err := ids.ParsePortalID(ce.Portal.ID); err != nil { + ce.Log.Err(err).Str("portal_id", string(ce.Portal.ID)).Msg("Failed to parse portal ID for upgrade command") + ce.Reply("Failed to parse portal ID") + } else if peerType == ids.PeerTypeChannel { + ce.Reply("Only minigroups can be upgraded (this is already a channel/supergroup).") + } else if peerType == ids.PeerTypeUser { + ce.Reply("Only minigroups can be upgraded (this is direct chat).") + } else if resp, err := login.Client.(*TelegramClient).client.API().MessagesMigrateChat(ce.Ctx, chatID); err != nil { + ce.Log.Err(err).Int64("chat_id", chatID).Msg("Failed to upgrade chat") + ce.Reply("Failed to upgrade chat: %v", err) + } else { + ce.Log.Trace().Any("response", resp).Msg("Updates from chat upgrade") + ce.Log.Info().Int64("old_chat_id", chatID).Msg("Successfully upgraded chat") + ce.React("\u2705\ufe0f") + err = login.Client.(*TelegramClient).dispatcher.Handle(ce.Ctx, resp) + if err != nil { + ce.Log.Err(err).Msg("Failed to handle updates from chat upgrade") + } else { + ce.Log.Debug().Msg("Finished handling updates from chat upgrade") + } + } +} + var cmdEmojiPack = &commands.FullHandler{ Func: fnEmojiPack, Name: "emoji-pack", diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index cf540559..d6a2b7c3 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -41,7 +41,7 @@ var _ bridgev2.MaxFileSizeingNetwork = (*TelegramConnector)(nil) func (tg *TelegramConnector) Init(bridge *bridgev2.Bridge) { tg.Store = store.NewStore(bridge.DB.Database, dbutil.ZeroLogger(bridge.Log.With().Str("db_section", "telegram").Logger())) tg.Bridge = bridge - tg.Bridge.Commands.(*commands.Processor).AddHandlers(cmdSyncChats, cmdEmojiPack) + tg.Bridge.Commands.(*commands.Processor).AddHandlers(cmdSyncChats, cmdEmojiPack, cmdUpgrade) } func (tg *TelegramConnector) Start(ctx context.Context) error {