Skip to content

Conversation

@Bibo-Joshi
Copy link
Member

As discussed in the dev chat, I added a warning to CC.chat_data about groups migrating to supergroup.
To make handling of the status updates from Telegram possible, I added the dispatcher property to CallbackContext.

If merged, add this section to the wiki:

Chat Migration

If a group chat migrates to supergroup, its chat id will change. Since the chat_data dicts are stored per chat id you'll need to transfer the data to the new id. Here are the two situations you may encounter:

Status Updates sent by Telegram

When a group migrates, Telegram will send an update that just states the new info. In order to catch those, simply define a corresponding handler:

def chat_migration(update, context):
    m = update.message
    dp = context.dispatcher

    # Get old and new chat ids
    old_id = m.chat_id or m.migrate_from_chat_id
    new_id = m.migrate_to_chat_id or m.chat_id

    # transfer data, if old data is still present
    if old_id in dp.chat_data:
        dp.chat_data[new_id].update(dp.chat_data.get(old_id))
        del dp.chat_data[old_id]

...

def main():
    updater = Updater("TOKEN", use_context=True)
    dp = updater.dispatcher

    dp.add_handler(MessageHandler(Filters.status_update.migrate, chat_migration))

...

To be entirely sure that the update will be processed by this handler, either add it first or put it in its own group.

ChatMigrated Errors

If you try e.g. sending a message to the old chat id, Telegram will respond by a Bad Request including the new chat id. You can access it using an error handler:

def error(update, context):
    """Log Errors caused by Updates."""
    logger.warning('Update "%s" caused error "%s"', update, context.error)

    if isinstance(context.error, ChatMigrated):
        new_chat_id = context.error.new_chat_id

Unfortunately, Telegram does not pass along the old chat id, so there is currently no simple way to perform a data transfer like above within the error handler. So make sure, that you catch the status updates! Still, you can wrap your requests into a try-except-clause:

def my_callback(update, context):
    dp = context.dispatcher

    ...

    try:
        context.bot.send_message(chat_id, text)
    except ChatMigrated as e:
        new_id = e.new_chat_id

        # Resend to new chat id
        context.bot.send_message(new_id, text)

        # Transfer data
        if chat_id in dp.chat_data:
            dp.chat_data[new_id].update(dp.chat_data.get(chat_id))
            del dp.chat_data[chat_id]

    ...

@Bibo-Joshi Bibo-Joshi added ⚙️ documentation affected functionality: documentation 📋 pending-review work status: pending-review labels Jan 1, 2020
@Bibo-Joshi Bibo-Joshi added this to the 12.4 milestone Jan 1, 2020
@Bibo-Joshi Bibo-Joshi requested a review from Poolitzer January 1, 2020 15:26
@Bibo-Joshi
Copy link
Member Author

afais codecov wants me to add a test for the new dispatcher property of CallbackContext is that really necessary?

@Bibo-Joshi Bibo-Joshi requested a review from Poolitzer January 19, 2020 15:08
@Poolitzer
Copy link
Member

Poolitzer commented Jan 19, 2020

I am not sure what codecov wants, but if it requires a test, TEST IT. Nothing bad can happen from it.

Copy link
Member

@Poolitzer Poolitzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changes looks good now

@tsnoam tsnoam merged commit 62f514f into master Jan 26, 2020
@tsnoam tsnoam deleted the chat-migrated branch January 26, 2020 20:55
@github-actions github-actions bot locked and limited conversation to collaborators Aug 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

⚙️ documentation affected functionality: documentation 📋 pending-review work status: pending-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants