Welcome Chat Members With Your Own bot

Yep. There are a lot of Telegram bots out there for welcoming new chat members. But welcoming them with your own Telegram bot hits different. Want to feel it? — Here's the guide.

What You Should Know

If you've already read the first article, Build Your First Telegram Bot with Python — For Absolute Beginners, you're good to go. Otherwise, I recommend you check that out first.

What Will You Learn Here?

Through the process of building this Telegram bot, you'll learn to use pyrogram.filters to filter incoming updates and navigate through update objects. Sounds complex? — That's why you're here. Just hold tight.

Skill 01 - Navigating Through Updates

This is one of the most important and frequently used skills when building a Telegram bot. We'll use the echo bot from the previous article to practice this skill. You can get the full code from here.

Let's print the message object and figure out what we can extract from it.

from pyrogram import Client


bot = Client(
    name='examplebot',           # pass whatever name (bot name, your name, etc)
    api_id=12345,                # pass your API_ID (as an int or a str)
    api_hash='your api hash',    # pass your API_HASH (as a str)
    bot_token='your bot token'   # pass your BOT_TOKEN (as a str)
)


@bot.on_message()
def echo(client,message):
    print(message)

bot.run()

Run your Python file and send a text message to the bot. You should see something like this:

{
    "_": "Message",
    "id": 123,
    "from_user": {
        "_": "User",
        "id": 111111111,
        "is_self": false,
        "is_contact": false,
        "is_mutual_contact": false,
        "is_deleted": false,
        "is_bot": false,
        "is_verified": false,
        "is_restricted": false,
        "is_scam": false,
        "is_fake": false,
        "is_support": false,
        "is_premium": false,
        "first_name": "John",
        "status": "UserStatus.RECENTLY",
        "username": "john_doe",
        "language_code": "en",
        "dc_id": 1,
        "photo": {
            "_": "ChatPhoto",
            "small_file_id": "AQADexampleSmallFileID123",
            "small_photo_unique_id": "AgADexampleSmallID",
            "big_file_id": "AQADexampleBigFileID123",
            "big_photo_unique_id": "AgADexampleBigID"
        }
    },
    "date": "2025-01-01 12:00:00",
    "chat": {
        "_": "Chat",
        "id": -1001234567890,
        "type": "ChatType.GROUP",
        "is_creator": false,
        "title": "Example Group Chat",
        "photo": {
            "_": "ChatPhoto",
            "small_file_id": "AQADgroupSmallPhotoID",
            "small_photo_unique_id": "AgADgroupSmall",
            "big_file_id": "AQADgroupBigPhotoID",
            "big_photo_unique_id": "AgADgroupBig"
        },
        "dc_id": 1,
        "has_protected_content": false,
        "members_count": 10,
        "permissions": {
            "_": "ChatPermissions",
            "can_send_messages": true,
            "can_send_media_messages": true,
            "can_send_other_messages": true,
            "can_send_polls": true,
            "can_add_web_page_previews": true,
            "can_change_info": true,
            "can_invite_users": true,
            "can_pin_messages": true
        }
    },
    "mentioned": false,
    "scheduled": false,
    "from_scheduled": false,
    "has_protected_content": false,
    "text": "Hello, world!",
    "outgoing": false
}

If you can use this update object wisely, you’ll be able to create a more alive and interactive connection between your bot and users. In the previous article, we extracted the message text like this.

    text = message.text

To be honest, I don't know how to explain this in a simpler way without making the article unnecessarily long. So I’ll give you some examples instead. Study them with the message object shown above — you’ll pick it up quickly.

Code SnippetExample ResultDescription
message.text"Hello, world!"The text content of the message
message.from_user.first_name"John"Sender's first name
message.from_user.username"john_doe"Sender's username
message.from_user.id111111111Telegram user ID of the sender
message.chat.title"Example Group Chat"Title of the group/channel chat
message.chat.id-1001234567890Unique chat ID

Nobody teaches this. I haven't seen anyone even mention it. It's that simple. I think I care about you more than I should :)

Challenge 01

To build confidence in this skill, try this quick challenge — Replace the echo message with a custom reply using these values.

    custom_reply = (
        f'**Name:** {firstname}\n',
        f'**ID:** {user_id}\n',
        f'**Username**: {username}\n',
        f'**Text:** {text}\n',
        f'**Date & Time:** {datetime}'
    )

View the answer here.

Skill 02 – Filter Incoming Updates with pyrogram.filters

Did you try sending a non text message to our Echo bot? — If you did, I appreciate it. You should always try to break your own code and fix it. Because if you don't, your users will.

Alright, what happened? — you'll get a big error message. There are many ways to solve this — from try-except blocks to using pyrogram.filters.

Challenge 02

Okay, you might have already guessed what the challenge is. Handle the error by implementing a simple logic inside the echo function. You'll find the answer on my Github. (Hint: Use skill one)

Drop a comment if you have trouble understanding the solution.

Why we need pyrogram.filters

What did we do by implementing a simple logic inside the echo function? — An update can be anything: a text message, sticker, photo, voice note, etc. To solve the error, we simply replied only if the message had text. Simple.

You can filter updates for anything you need — only commands, only group messages, only messages from admins — just by writing some logic inside your function.
But once your project grows, it’s only a matter of time before things get messy.

That’s where pyrogram.filters comes in.

How to Use pyrogram.filters

Let’s solve the same issue using filters instead of manual checks. First, import it:

from pyrogram import Client, filters

Now, apply a text filter to the echo function.

@bot.on_message(filters.text)
def echo(client,message):
    text = message.text
    message.reply(text)

Now your echo function only gets called for text messages. Problem solved :)

Most Useful pyrogram.filters

FilterDescription
filters.command("...")Triggers on specific bot commands like /start, /help, etc.
filters.textFilters plain text messages (no media).
filters.privateFilters messages sent in private chats.
filters.group / supergroupFilters messages sent in group chats.
filters.replyFilters messages that are replies to other messages.
filters.photoFilters photo messages.
filters.user(user_id)Filters messages sent by a specific user or list of users.
filters.new_chat_membersFilter service messages for new chat members.

Full list in the official Pyrogram docs

The Welcome Function

Alright, now for the main part. And it’s easy. You already have all the pieces — just put them together.

Our bot will need to listen for new chat member updates and send a welcome message.

Note: You won’t get new member updates in private chats. Create a test group, add your bot, and make it an admin.

Welcome New Chat Members

You probably already know which filter we're going to use for this. If not — scroll up, check the table, and take a guess.

@bot.on_message(filters.new_chat_members)
def welcome(client, message):
    message.reply('Hi, welcome to the chat!')

The welcome function will be called whenever a new member joins the group.
You can greet them with any welcome message you like — and use Skill 01 to make it feel more alive.

from pyrogram import Client, filters


bot = Client(
    name='examplebot',           # pass whatever name (bot name, your name, etc)
    api_id=12345,                # pass your API_ID (as a int or str)
    api_hash='your api hash',    # pass your API_HASH (as a str)
    bot_token='your bot token'   # pass your BOT_TOKEN (as a str)
)


@bot.on_message(filters.new_chat_members)
def welcome(client, message):
    message.reply('Hi, welcome to the chat!')



bot.run()

Run your Python file, add a user to your group — and your bot will welcome them warmly.

Final Thoughts

You’ve just learned how to filter incoming updates and welcome new members with your own Telegram bot using Pyrogram. If you’ve ever wondered how bots run 24/7 — it’s because they are hosted. I can write an article on that if you're interested, though I don't have plans to do it soon. Drop a comment if you want it earlier — I’ll make it happen.

You can subscribe to the newsletter to get new articles delivered straight to your inbox the moment I post them. Follow me on GitHub for more contents— and maybe Instagram too.

You can support my effort by reacting to and commenting on this article. Share it with someone who would find it valuable.

References

10
Subscribe to my newsletter

Read articles from Beenuka Hettiarachchi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Beenuka Hettiarachchi
Beenuka Hettiarachchi