To detect when a bot is added to a group, listen for my_chat_member updates where the status transitions from a non-member state to a member state.
In aiogram 3.x, you can use several levels of abstraction for these transitions:
- Manual Transition: Define specific sets of states using bitwise operators. Use
>> to indicate the direction of the transition (from old to new). Use + or - to modify the is_member flag for the RESTRICTED status.- Example:
(KICKED | LEFT | -RESTRICTED) >> (+RESTRICTED | MEMBER | ADMINISTRATOR)
- Predefined Sets: Use
IS_NOT_MEMBER >> IS_MEMBER to catch any transition from a non-member state to a member state. - Convenience Constant: Use
JOIN_TRANSITION for the most common 'added to chat' scenario.
Important Note on Group Conversion: When a standard group is converted into a supergroup, it may trigger a my_chat_member update as if the bot were being added to a new chat. To avoid duplicate logic, check if the incoming message contains a non-empty migrate_to_chat_id field.
# Option 1: Manual (Detailed)
from aiogram.filters.chat_member_updated import ChatMemberUpdatedFilter, KICKED, LEFT, MEMBER, RESTRICTED, ADMINISTRATOR, CREATOR
@router.my_chat_member(ChatMemberUpdatedFilter(
member_status_changed=(KICKED | LEFT | -RESTRICTED) >> (+RESTRICTED | MEMBER | ADMINISTRATOR | CREATOR)
))
# Option 2: Using IS_NOT_MEMBER / IS_MEMBER
from aiogram.filters.chat_member_updated import ChatMemberUpdatedFilter, IS_NOT_MEMBER, IS_MEMBER
@router.my_chat_member(ChatMemberUpdatedFilter(IS_NOT_MEMBER >> IS_MEMBER))
# Option 3: Using JOIN_TRANSITION (Recommended)
from aiogram.filters.chat_member_updated import ChatMemberUpdatedFilter, JOIN_TRANSITION
@router.my_chat_member(ChatMemberUpdatedFilter(JOIN_TRANSITION))