Search code examples
pythonbotstelegramtelegram-botpython-telegram-bot

Python Telegram Bot Chat.ban_member() issues


I'm working with Python Telegram Bot https://python-telegram-bot.readthedocs.io/en/stable/telegram.chat.html and trying to build my first bot on telegram.

I've followed the example https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/chatmemberbot.py as a template

I want to add a functionality that if a user is not in the list, the bot should kick him out but I'm having some issues implementing this function. My code is as follows:

#!/usr/bin/env python
# pylint: disable=C0116,W0613
# This program is dedicated to the public domain under the CC0 license.

"""
Simple Bot to handle '(my_)chat_member' updates.
Greets new users & keeps track of which chats the bot is in.
Usage:
Press Ctrl-C on the command line or send a signal to the process to stop the
bot.
"""

import logging
from typing import Tuple, Optional

from telegram import Update, Chat, ChatMember, ParseMode, ChatMemberUpdated
from telegram.ext import (
    Updater,
    CommandHandler,
    CallbackContext,
    ChatMemberHandler,
)

# Enable logging
logging.basicConfig(
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
)

logger = logging.getLogger(__name__)

def checkUsers(update: Update, context: CallbackContext, chat: Chat) -> None:
    """Greets new users in chats and announces when someone leaves"""

    cause_name = update.chat_member.from_user.mention_html()
    member_name = update.chat_member.new_chat_member.user.mention_html()
    
    member = update.chat_member.new_chat_member.user.username
    userId = update.chat_member.new_chat_member.user.id
    print(userId)
    
    approvedMembers = ["Jack", "shaamsCat"]
    
    if member in approvedMembers :
        update.effective_chat.send_message(
            f"{member_name} was added by {cause_name}. Welcome!",
            parse_mode=ParseMode.HTML,
        )
    elif member not in approvedMembers : 
        update.effective_chat.send_message(
            f"{member_name} is not on the list!",
            parse_mode=ParseMode.HTML,
        ),
                
    chat.ban_member(userId)
       

def main() -> None:
    """Start the bot."""
    # Create the Updater and pass it your bot's token.
    updater = Updater("TOKEN")

    # Get the dispatcher to register handlers
    dispatcher = updater.dispatcher

    # Handle members joining/leaving chats.
    dispatcher.add_handler(ChatMemberHandler(checkUsers, ChatMemberHandler.CHAT_MEMBER))

    # Start the Bot
    # We pass 'allowed_updates' handle *all* updates including `chat_member` updates
    # To reset this, simply pass `allowed_updates=[]`
    updater.start_polling(allowed_updates=Update.ALL_TYPES)

    # Run the bot until you press Ctrl-C or the process receives SIGINT,
    # SIGTERM or SIGABRT. This should be used most of the time, since
    # start_polling() is non-blocking and will stop the bot gracefully.
    updater.idle()


if __name__ == "__main__":
    main()

And I receive the following error in that case:

TypeError: checkUsers() missing 1 required positional argument: 'chat'

If I change the function checkUsers() function to look like this:

def checkUsers(update: Update, context: CallbackContext) -> None:
"""Greets new users in chats and announces when someone leaves"""

cause_name = update.chat_member.from_user.mention_html()
member_name = update.chat_member.new_chat_member.user.mention_html()

member = update.chat_member.new_chat_member.user.username
userId = update.chat_member.new_chat_member.user.id
print(userId)

approvedMembers = ["Jack", "shaamsCat"]

if member in approvedMembers :
    update.effective_chat.send_message(
        f"{member_name} was added by {cause_name}. Welcome!",
        parse_mode=ParseMode.HTML,
    )
elif member not in approvedMembers : 
    update.effective_chat.send_message(
        f"{member_name} is not on the list!",
        parse_mode=ParseMode.HTML,
    ),
            
Chat.ban_member(userId)
   

Then the error is:

TypeError: ban_member() missing 1 required positional argument: 'user_id'

And if I pass no arguments to Chat.ban_member() then the arguments missing looks like follows:

TypeError: ban_member() missing 2 required positional arguments: 'self' and 'user_id'

I'll appreaciate any help, I'm sure it's going to be any fundamental knowledge I'm missing, I will be honest and tell you I did just start working with Python some days ago, so be nice please!!

Thank you!


Solution

  • Handler callbacks must have exactly two positional arguments - that's just how python-telegram-bot is designed. That's why your first approach doesn't work.

    Moreover, Chat.ban_member is a bounded method, not a class/static method. Chat is a class, not an instance of that class, so Chat.ban_member(user_id) can't work either. You need an instance of the Chat class to call that method. In your case probably update.chat_member.chat or update.effective_chat (the latter being a shortcut for the former).


    Disclaimer: I'm currently the maintainer of python-telegram-bot.