connector: handle supergroup upgrades (#118)
Co-authored-by: Tulir Asokan <tulir@maunium.net>
This commit is contained in:
@@ -82,6 +82,8 @@ type TelegramConfig struct {
|
||||
AlwaysCustomEmojiReaction bool `yaml:"always_custom_emoji_reaction"`
|
||||
|
||||
SavedMessagesAvatar id.ContentURIString `yaml:"saved_message_avatar"`
|
||||
|
||||
AlwaysTombstoneOnSupergroupMigration bool `yaml:"always_tombstone_on_supergroup_migration"`
|
||||
}
|
||||
|
||||
func (c TelegramConfig) ShouldBridge(participantCount int) bool {
|
||||
@@ -120,6 +122,7 @@ func upgradeConfig(helper up.Helper) {
|
||||
helper.Copy(up.Bool, "sync", "direct_chats")
|
||||
helper.Copy(up.Bool, "always_custom_emoji_reaction")
|
||||
helper.Copy(up.Str, "saved_message_avatar")
|
||||
helper.Copy(up.Bool, "always_tombstone_on_supergroup_migration")
|
||||
}
|
||||
|
||||
func (tg *TelegramConnector) GetConfig() (example string, data any, upgrader up.Upgrader) {
|
||||
|
||||
@@ -88,3 +88,6 @@ always_custom_emoji_reaction: false
|
||||
|
||||
# The avatar to use for the Telegram Saved Messages chat
|
||||
saved_message_avatar: mxc://nevarro.space/ZzzyOSDZfyGjKRRbyDPTweAA
|
||||
|
||||
# Create a new room and tombstone the old one when upgrading rooms
|
||||
always_tombstone_on_supergroup_migration: false
|
||||
|
||||
@@ -534,8 +534,39 @@ func (t *TelegramClient) onUpdateNewMessage(ctx context.Context, entities tg.Ent
|
||||
return err
|
||||
}
|
||||
|
||||
// case *tg.MessageActionChatMigrateTo:
|
||||
case *tg.MessageActionChatMigrateTo:
|
||||
log.Debug().Int64("channel_id", action.ChannelID).Msg("MessageActionChatMigrateTo")
|
||||
newPortalKey := t.makePortalKeyFromID(ids.PeerTypeChannel, action.ChannelID)
|
||||
if err := t.migrateChat(ctx, eventMeta.PortalKey, newPortalKey); err != nil {
|
||||
log.Err(err).Msg("Failed to migrate chat to channel")
|
||||
return err
|
||||
}
|
||||
res := t.main.Bridge.QueueRemoteEvent(t.userLogin, &simplevent.Message[any]{
|
||||
EventMeta: eventMeta.
|
||||
WithPortalKey(newPortalKey).
|
||||
WithStreamOrder(0).
|
||||
WithType(bridgev2.RemoteEventMessage),
|
||||
ID: ids.GetMessageIDFromMessage(msg),
|
||||
ConvertMessageFunc: func(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, data any) (*bridgev2.ConvertedMessage, error) {
|
||||
return &bridgev2.ConvertedMessage{
|
||||
Parts: []*bridgev2.ConvertedMessagePart{
|
||||
{
|
||||
Type: event.EventMessage,
|
||||
Content: &event.MessageEventContent{
|
||||
MsgType: event.MsgNotice,
|
||||
Body: "Upgraded this group to a supergroup",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
})
|
||||
if err := resultToError(res); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// case *tg.MessageActionChannelMigrateFrom:
|
||||
|
||||
// case *tg.MessageActionPinMessage:
|
||||
// case *tg.MessageActionHistoryClear:
|
||||
// case *tg.MessageActionGameScore:
|
||||
@@ -579,6 +610,37 @@ func (t *TelegramClient) onUpdateNewMessage(ctx context.Context, entities tg.Ent
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TelegramClient) migrateChat(ctx context.Context, oldPortalKey, newPortalKey networkid.PortalKey) error {
|
||||
if t.main.Config.AlwaysTombstoneOnSupergroupMigration {
|
||||
newPortal, err := t.main.Bridge.GetPortalByKey(ctx, newPortalKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get new portal for chat migration: %w", err)
|
||||
}
|
||||
info, err := t.GetChatInfo(ctx, newPortal)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get chat info for new portal: %w", err)
|
||||
}
|
||||
err = newPortal.CreateMatrixRoom(ctx, t.userLogin, info)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create Matrix room for new portal: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
result, portal, err := t.main.Bridge.ReIDPortal(ctx, oldPortalKey, newPortalKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to re-ID portal: %w", err)
|
||||
} else if result == bridgev2.ReIDResultSourceReIDd || result == bridgev2.ReIDResultTargetDeletedAndSourceReIDd {
|
||||
// If the source portal is re-ID'd, we need to sync metadata and participants.
|
||||
// If the source is deleted, then it doesn't matter, any existing target will already be correct
|
||||
info, err := t.GetChatInfo(ctx, portal)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get chat info for new portal: %w", err)
|
||||
}
|
||||
portal.UpdateInfo(ctx, info, t.userLogin, nil, time.Time{})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TelegramClient) getEventSender(msg interface {
|
||||
GetOut() bool
|
||||
GetFromID() (tg.PeerClass, bool)
|
||||
|
||||
Reference in New Issue
Block a user