In this tutorial, we are going to use the CSV file that we generated in Scraping Telegram Members tutorial to send bulk messages to our scraped Telegram group members using Telegram API and Python Telethon library. So if you did not already checked that, visit this tutorial and learn how to get this file. Basically we will feed our new Python script with that CSV file to read usernames or user IDs from it and send a message to them.
Get Telegram API Key
As stated in the previous tutorial you need to get your Telegram API credentials to be able to use the API. So don’t hesitate and check the previous tutorial and use the guide to get your own Telegram API credentials, or simply follow these steps:
• Sign up for Telegram using any application.
• Log in to your Telegram core: https://my.telegram.org.
• Go to ‘API development tools’ and fill out the form.
• You will get basic addresses as well as the api_id and api_hash parameters required for user authorization.
Install Telethon
Also you need to install Telethon using pip.
1 2 |
python -m pip install telethon |
Note: If you are on Linux or Mac, you might need to use sudo before pip to avoid permissions issues.
Let’s get started.
Create Client Object and Login
Whenever you want to use Telethon, first step should be logging into the API. So you have to create a client object and check if it’s already authorized otherwise ask for an OTP password.
So create your client object first.
1 2 3 4 5 6 |
from telethon.sync import TelegramClient api_id = 123456 api_hash = 'YOUR_API_HASH' phone = '+111111111111' client = TelegramClient(phone, api_id, api_hash) |
Connect and check if the client is authorized. Otherwise prompt the user to enter the code they received from Telegram.
1 2 3 4 5 |
client.connect() if not client.is_user_authorized(): client.send_code_request(phone) client.sign_in(phone, input('Enter the code: ')) |
Read Members from CSV File
We are passing the file name in the sys.argv parameters. sys.argv is a list in Python, which contains the command-line arguments passed to the script.
So if you run python sendMessage.py users.csv in the command line sys.argv will return a list like this:
1 2 |
['sendMessage.py', 'users.csv'] |
As you can see, the first item in the list is the name of the script and the second item is the name of our CSV file. So we can access the file name with sys.argv[1] .
Now you have the name (or path) of our CSV file and you can use Python’s csv module to read the file and create a list of users.
Import the required modules
1 2 3 |
import sys import csv |
Create a dictionary for every user and append that to our user list.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
input_file = sys.argv[1] users = [] with open(input_file, encoding='UTF-8') as f: rows = csv.reader(f,delimiter=",",lineterminator="\n") next(rows, None) for row in rows: user = {} user['username'] = row[0] user['id'] = int(row[1]) user['access_hash'] = int(row[2]) user['name'] = row[3] users.append(user) |
Note: You need to cast the user id and access hash to integer type.
Note: We skip the first row in the CSV file (header) using the next function.
Prompt to Send by User ID or Username
As I mentioned in the previous tutorial, not all telegram members have a username. Also, access hash for every user is different for every Telegram account. It means that if you scrape users with a Telegram account and you want to send messages with another account then you cannot use those access hashes to get the users. But you can use usernames. To solve this problem and avoid errors we will ask your Python script user whether he/she wants to use Telegram username or user ID to send the messages.
1 2 |
mode = int(input("Enter 1 to send by user ID or 2 to send by username: ")) |
Send Messages
Now, you have all the requirements to start sending messages.
Create a list of messages and randomly select one of them to send to a user. Also, format the message to include the name of the user.
1 2 |
messages = ["Hello {}, How are you?", "Hi {}, What's up?", "Hey {}, do you want to gotrained?"] |
Now, loop through every user and send a message. Consider that if you send messages too quickly you will get a PeerFloodError from Telegram. So we will handle this error using a try, except block and exit the program if it happened. Otherwise the account might get banned from Telegram because of spamming. Also, add a sleep time between each message to avoid flood error.
We are going to do it step by step.
Loop through every user and get the receiver entity depending on the “mode” entered before.
1 2 3 4 5 6 7 8 9 10 11 12 |
from telethon.tl.types import InputPeerUser for user in users: if mode == 2: if user['username'] == "": continue receiver = client.get_input_entity(user['username']) elif mode == 1: receiver = InputPeerUser(user['id'],user['access_hash']) else: print("Invalid Mode. Exiting.") sys.exit() |
Select a message from message list randomly.
1 2 3 |
import random message = random.choice(messages) |
Format the message with user’s name and send it.
1 2 |
client.send_message(receiver, message.format(user['name']) |
The complete code block for sending messages including exception handling will look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
from telethon.tl.types import InputPeerUser from telethon.errors.rpcerrorlist import PeerFloodError import random SLEEP_TIME = 30 for user in users: if mode == 2: if user['username'] == "": continue receiver = client.get_input_entity(user['username']) elif mode == 1: receiver = InputPeerUser(user['id'],user['access_hash']) else: print("Invalid Mode. Exiting.") client.disconnect() sys.exit() message = random.choice(messages) try: print("Sending Message to:", user['name']) client.send_message(receiver, message.format(user['name'])) print("Waiting {} seconds".format(SLEEP_TIME)) time.sleep(SLEEP_TIME) except PeerFloodError: print("Getting Flood Error from telegram. Script is stopping now. Please try again after some time.") client.disconnect() sys.exit() except Exception as e: print("Error:", e) print("Trying to continue...") continue |
Project Source Code for Messaging Telegram Members Tutorial
Here is the completed code for this tutorial.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
from telethon.sync import TelegramClient from telethon.tl.types import InputPeerUser from telethon.errors.rpcerrorlist import PeerFloodError import sys import csv import random import time api_id = 123456 api_hash = 'YOUR_API_HASH' phone = '+111111111111' SLEEP_TIME = 30 client = TelegramClient(phone, api_id, api_hash) client.connect() if not client.is_user_authorized(): client.send_code_request(phone) client.sign_in(phone, input('Enter the code: ')) input_file = sys.argv[1] users = [] with open(input_file, encoding='UTF-8') as f: rows = csv.reader(f,delimiter=",",lineterminator="\n") next(rows, None) for row in rows: user = {} user['username'] = row[0] user['id'] = int(row[1]) user['access_hash'] = int(row[2]) user['name'] = row[3] users.append(user) mode = int(input("Enter 1 to send by user ID or 2 to send by username: ")) messages= ["Hello {}, How are you?", "Hi {}, What's up?", "Hey {}, do you want to gotrained?"] for user in users: if mode == 2: if user['username'] == "": continue receiver = client.get_input_entity(user['username']) elif mode == 1: receiver = InputPeerUser(user['id'],user['access_hash']) else: print("Invalid Mode. Exiting.") client.disconnect() sys.exit() message = random.choice(messages) try: print("Sending Message to:", user['name']) client.send_message(receiver, message.format(user['name'])) print("Waiting {} seconds".format(SLEEP_TIME)) time.sleep(SLEEP_TIME) except PeerFloodError: print("Getting Flood Error from telegram. Script is stopping now. Please try again after some time.") client.disconnect() sys.exit() except Exception as e: print("Error:", e) print("Trying to continue...") continue client.disconnect() print("Done. Message sent to all users.") |
I speak Python!
Majid Alizadeh is a freelance developer specialized in web development, web scraping and automation. He provides high quality and sophisticated software for his clients. Beside Python he works with other languages like Ruby, PHP and JS as well.
very good sample, I enjoy it. thank you
How to Handle Flooderror in this program?
Telegram is sensitive and if one of the users reported abuse, this is a problem.
This error means you are too many send message to telegram users. Telegram bans your account for 1×24 hour
hi GoTrained,
How to solve “An invalid Peer was used. Make sure to pass the right peer type (caused by SendMessageRequest).
Thanks
try to send the message with user id and An invalid peer was used will show up