├── .version ├── .gitignore ├── scraper.py ├── smsbot.py ├── README.md ├── add2group.py └── setup.py /.version: -------------------------------------------------------------------------------- 1 | 1.0 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /scraper.py: -------------------------------------------------------------------------------- 1 | from telethon.sync import TelegramClient 2 | from telethon.tl.functions.messages import GetDialogsRequest 3 | from telethon.tl.types import InputPeerEmpty 4 | import os, sys 5 | import configparser 6 | import csv 7 | import time 8 | 9 | re="\033[1;31m" 10 | gr="\033[1;32m" 11 | cy="\033[1;36m" 12 | 13 | def banner(): 14 | print(f""" 15 | {re}Ꮆ尺闩爪{cy}丂⼕尺闩尸🝗尺 16 | 17 | version : 1.0 18 | github.com/muneebwanee 19 | """) 20 | 21 | cpass = configparser.RawConfigParser() 22 | cpass.read('config.data') 23 | 24 | try: 25 | api_id = cpass['cred']['id'] 26 | api_hash = cpass['cred']['hash'] 27 | phone = cpass['cred']['phone'] 28 | client = TelegramClient(phone, api_id, api_hash) 29 | except KeyError: 30 | os.system('clear') 31 | banner() 32 | print(re+"[!] run python3 setup.py first !!\n") 33 | sys.exit(1) 34 | 35 | client.connect() 36 | if not client.is_user_authorized(): 37 | client.send_code_request(phone) 38 | os.system('clear') 39 | banner() 40 | client.sign_in(phone, input(gr+'[+] Enter the OTP code sent to your Telegram: '+re)) 41 | 42 | os.system('clear') 43 | banner() 44 | chats = [] 45 | last_date = None 46 | chunk_size = 200 47 | groups=[] 48 | 49 | result = client(GetDialogsRequest( 50 | offset_date=last_date, 51 | offset_id=0, 52 | offset_peer=InputPeerEmpty(), 53 | limit=chunk_size, 54 | hash = 0 55 | )) 56 | chats.extend(result.chats) 57 | 58 | for chat in chats: 59 | try: 60 | if chat.megagroup== True: 61 | groups.append(chat) 62 | except: 63 | continue 64 | 65 | print(gr+'[+] Choose a group to scrape members :'+re) 66 | i=0 67 | for g in groups: 68 | print(gr+'['+cy+str(i)+gr+']'+cy+' - '+ g.title) 69 | i+=1 70 | 71 | print('') 72 | g_index = input(gr+"[+] Enter a Number : "+re) 73 | target_group=groups[int(g_index)] 74 | 75 | print(gr+'[+] Fetching Members...') 76 | time.sleep(1) 77 | all_participants = [] 78 | all_participants = client.get_participants(target_group, aggressive=True) 79 | 80 | print(gr+'[+] Saving In file...') 81 | time.sleep(1) 82 | with open("members.csv","w",encoding='UTF-8') as f: 83 | writer = csv.writer(f,delimiter=",",lineterminator="\n") 84 | writer.writerow(['username','user id', 'access hash','name','group', 'group id']) 85 | for user in all_participants: 86 | if user.username: 87 | username= user.username 88 | else: 89 | username= "" 90 | if user.first_name: 91 | first_name= user.first_name 92 | else: 93 | first_name= "" 94 | if user.last_name: 95 | last_name= user.last_name 96 | else: 97 | last_name= "" 98 | name= (first_name + ' ' + last_name).strip() 99 | writer.writerow([username,user.id,user.access_hash,name,target_group.title, target_group.id]) 100 | print(gr+'[+] Members scraped successfully.') 101 | -------------------------------------------------------------------------------- /smsbot.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python3 2 | from telethon.sync import TelegramClient 3 | from telethon.tl.types import InputPeerUser 4 | from telethon.errors.rpcerrorlist import PeerFloodError 5 | import configparser 6 | import os, sys 7 | import csv 8 | import random 9 | import time 10 | 11 | re="\033[1;31m" 12 | gr="\033[1;32m" 13 | cy="\033[1;36m" 14 | SLEEP_TIME = 30 15 | 16 | class main(): 17 | 18 | def banner(): 19 | 20 | print(f""" 21 | {re}Ꮆ尺闩爪 丂⼕尺闩尸🝗尺{cy} 22 | version : 1.0 23 | github.com/muneebwanee 24 | """) 25 | 26 | def send_sms(): 27 | try: 28 | cpass = configparser.RawConfigParser() 29 | cpass.read('config.data') 30 | api_id = cpass['cred']['id'] 31 | api_hash = cpass['cred']['hash'] 32 | phone = cpass['cred']['phone'] 33 | except KeyError: 34 | os.system('clear') 35 | main.banner() 36 | print(re+"[!] run python3 setup.py first !!\n") 37 | sys.exit(1) 38 | 39 | client = TelegramClient(phone, api_id, api_hash) 40 | 41 | client.connect() 42 | if not client.is_user_authorized(): 43 | client.send_code_request(phone) 44 | os.system('clear') 45 | main.banner() 46 | client.sign_in(phone, input(gr+'[+] Enter the code: '+re)) 47 | 48 | os.system('clear') 49 | main.banner() 50 | input_file = sys.argv[1] 51 | users = [] 52 | with open(input_file, encoding='UTF-8') as f: 53 | rows = csv.reader(f,delimiter=",",lineterminator="\n") 54 | next(rows, None) 55 | for row in rows: 56 | user = {} 57 | user['username'] = row[0] 58 | user['id'] = int(row[1]) 59 | user['access_hash'] = int(row[2]) 60 | user['name'] = row[3] 61 | users.append(user) 62 | print(gr+"[1] send sms by user ID\n[2] send sms by username ") 63 | mode = int(input(gr+"Input : "+re)) 64 | 65 | message = input(gr+"[+] Enter Your Message : "+re) 66 | 67 | for user in users: 68 | if mode == 2: 69 | if user['username'] == "": 70 | continue 71 | receiver = client.get_input_entity(user['username']) 72 | elif mode == 1: 73 | receiver = InputPeerUser(user['id'],user['access_hash']) 74 | else: 75 | print(re+"[!] Invalid Mode. Exiting.") 76 | client.disconnect() 77 | sys.exit() 78 | try: 79 | print(gr+"[+] Sending Message to:", user['name']) 80 | client.send_message(receiver, message.format(user['name'])) 81 | print(gr+"[+] Waiting {} seconds".format(SLEEP_TIME)) 82 | time.sleep(SLEEP_TIME) 83 | except PeerFloodError: 84 | print(re+"[!] Getting Flood Error from telegram. \n[!] Script is stopping now. \n[!] Please try again after some time.") 85 | client.disconnect() 86 | sys.exit() 87 | except Exception as e: 88 | print(re+"[!] Error:", e) 89 | print(re+"[!] Trying to continue...") 90 | continue 91 | client.disconnect() 92 | print("Done. Message sent to all users.") 93 | 94 | 95 | 96 | main.send_sms() 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
11 | Telegram Scraper 12 |
13 | 14 | --- 15 | 16 | # `Example:` 17 | 18 | 23 | 24 | --- 25 | 26 | ## • API Setup 27 | * Go to http://my.telegram.org and log in. 28 | * Click on API development tools and fill the required fields. 29 | * put app name you want & select other in platform Example : 30 | * copy "api_id" & "api_hash" after clicking create app ( will be used in setup.py ) 31 | 32 | ## • How To Install and Use 33 | 34 | `$ pkg install -y git python` 35 | 36 | `$ git clone https://github.com/muneebwanee/GramScraper.git` 37 | 38 | `$ cd GramScraper` 39 | 40 | * Install requierments 41 | 42 | `$ python3 setup.py -i` 43 | 44 | * setup configration file ( apiID, apiHASH ) 45 | 46 | `$ python3 setup.py -c` 47 | 48 | * To Genrate User Data 49 | 50 | `$ python3 scraper.py` 51 | 52 | * ( members.csv is default if you changed name use it ) 53 | * Send Bulk sms To Collected Data 54 | 55 | `$ python3 smsbot.py members.csv` 56 | 57 | * Update Tool 58 | 59 | `$ python3 setup.py -u` 60 | 61 | --- 62 | 63 | 72 | -------------------------------------------------------------------------------- /add2group.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python3 2 | from telethon.sync import TelegramClient 3 | from telethon.tl.functions.messages import GetDialogsRequest 4 | from telethon.tl.types import InputPeerEmpty, InputPeerChannel, InputPeerUser 5 | from telethon.errors.rpcerrorlist import PeerFloodError, UserPrivacyRestrictedError 6 | from telethon.tl.functions.channels import InviteToChannelRequest 7 | import configparser 8 | import os, sys 9 | import csv 10 | import traceback 11 | import time 12 | import random 13 | 14 | re="\033[1;31m" 15 | gr="\033[1;32m" 16 | cy="\033[1;36m" 17 | 18 | def banner(): 19 | print(f""" 20 | {re}Ꮆ尺闩爪{cy}丂⼕尺闩尸🝗尺 21 | 22 | version : 1.0 23 | """) 24 | 25 | cpass = configparser.RawConfigParser() 26 | cpass.read('config.data') 27 | 28 | try: 29 | api_id = cpass['cred']['id'] 30 | api_hash = cpass['cred']['hash'] 31 | phone = cpass['cred']['phone'] 32 | client = TelegramClient(phone, api_id, api_hash) 33 | except KeyError: 34 | os.system('clear') 35 | banner() 36 | print(re+"[!] run python3 setup.py first !!\n") 37 | sys.exit(1) 38 | 39 | client.connect() 40 | if not client.is_user_authorized(): 41 | client.send_code_request(phone) 42 | os.system('clear') 43 | banner() 44 | client.sign_in(phone, input(gr+'[+] Enter the code: '+re)) 45 | 46 | os.system('clear') 47 | banner() 48 | input_file = sys.argv[1] 49 | users = [] 50 | with open(input_file, encoding='UTF-8') as f: 51 | rows = csv.reader(f,delimiter=",",lineterminator="\n") 52 | next(rows, None) 53 | for row in rows: 54 | user = {} 55 | user['username'] = row[0] 56 | user['id'] = int(row[1]) 57 | user['access_hash'] = int(row[2]) 58 | user['name'] = row[3] 59 | users.append(user) 60 | 61 | chats = [] 62 | last_date = None 63 | chunk_size = 200 64 | groups=[] 65 | 66 | result = client(GetDialogsRequest( 67 | offset_date=last_date, 68 | offset_id=0, 69 | offset_peer=InputPeerEmpty(), 70 | limit=chunk_size, 71 | hash = 0 72 | )) 73 | chats.extend(result.chats) 74 | 75 | for chat in chats: 76 | try: 77 | if chat.megagroup== True: 78 | groups.append(chat) 79 | except: 80 | continue 81 | 82 | i=0 83 | for group in groups: 84 | print(gr+'['+cy+str(i)+gr+']'+cy+' - '+group.title) 85 | i+=1 86 | 87 | print(gr+'[+] Choose a group to add members') 88 | g_index = input(gr+"[+] Enter a Number : "+re) 89 | target_group=groups[int(g_index)] 90 | 91 | target_group_entity = InputPeerChannel(target_group.id,target_group.access_hash) 92 | 93 | print(gr+"[1] add member by user ID\n[2] add member by username ") 94 | mode = int(input(gr+"Input : "+re)) 95 | n = 0 96 | 97 | for user in users: 98 | n += 1 99 | if n % 50 == 0: 100 | time.sleep(1) 101 | try: 102 | print ("Adding {}".format(user['id'])) 103 | if mode == 1: 104 | if user['username'] == "": 105 | continue 106 | user_to_add = client.get_input_entity(user['username']) 107 | elif mode == 2: 108 | user_to_add = InputPeerUser(user['id'], user['access_hash']) 109 | else: 110 | sys.exit(re+"[!] Invalid Mode Selected. Please Try Again.") 111 | client(InviteToChannelRequest(target_group_entity,[user_to_add])) 112 | print(gr+"[+] Waiting for 5-10 Seconds...") 113 | time.sleep(random.randrange(5, 10)) 114 | except PeerFloodError: 115 | print(re+"[!] Getting Flood Error from telegram. \n[!] Script is stopping now. \n[!] Please try again after some time.") 116 | except UserPrivacyRestrictedError: 117 | print(re+"[!] The user's privacy settings do not allow you to do this. Skipping.") 118 | except: 119 | traceback.print_exc() 120 | print(re+"[!] Unexpected Error") 121 | continue 122 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python3 2 | # code by : github.com/muneebwanee 3 | 4 | """ 5 | 6 | you can re run setup.py 7 | if you have added some wrong value 8 | 9 | """ 10 | re="\033[1;31m" 11 | gr="\033[1;32m" 12 | cy="\033[1;36m" 13 | 14 | import os, sys 15 | import time 16 | 17 | def banner(): 18 | os.system('clear') 19 | print(f""" 20 | {re}丂{cy}🝗セㄩ尸 21 | """) 22 | 23 | def requirements(): 24 | def csv_lib(): 25 | banner() 26 | print(gr+'['+cy+'+'+gr+']'+cy+' this may take some time ...') 27 | os.system(""" 28 | pip3 install cython numpy pandas 29 | python3 -m pip install cython numpy pandas 30 | """) 31 | banner() 32 | print(gr+'['+cy+'+'+gr+']'+cy+' it will take upto 10 min to install csv merge.') 33 | input_csv = input(gr+'['+cy+'+'+gr+']'+cy+' do you want to enable csv merge (y/n): ').lower() 34 | if input_csv == "y": 35 | csv_lib() 36 | else: 37 | pass 38 | print(gr+"[+] Installing requierments ...") 39 | os.system(""" 40 | pip3 install telethon requests configparser 41 | python3 -m pip install telethon requests configparser 42 | touch config.data 43 | """) 44 | banner() 45 | print(gr+"[+] requierments Installed.\n") 46 | 47 | 48 | def config_setup(): 49 | import configparser 50 | banner() 51 | cpass = configparser.RawConfigParser() 52 | cpass.add_section('cred') 53 | xid = input(gr+"[+] enter api ID : "+re) 54 | cpass.set('cred', 'id', xid) 55 | xhash = input(gr+"[+] enter hash ID : "+re) 56 | cpass.set('cred', 'hash', xhash) 57 | xphone = input(gr+"[+] enter phone number : "+re) 58 | cpass.set('cred', 'phone', xphone) 59 | setup = open('config.data', 'w') 60 | cpass.write(setup) 61 | setup.close() 62 | print(gr+"[+] setup complete !") 63 | 64 | def merge_csv(): 65 | import pandas as pd 66 | import sys 67 | banner() 68 | file1 = pd.read_csv(sys.argv[2]) 69 | file2 = pd.read_csv(sys.argv[3]) 70 | print(gr+'['+cy+'+'+gr+']'+cy+' merging '+sys.argv[2]+' & '+sys.argv[3]+' ...') 71 | print(gr+'['+cy+'+'+gr+']'+cy+' big files can take some time ... ') 72 | merge = file1.merge(file2, on='username') 73 | merge.to_csv("output.csv", index=False) 74 | print(gr+'['+cy+'+'+gr+']'+cy+' saved file as "output.csv"\n') 75 | 76 | def update_tool(): 77 | import requests as r 78 | banner() 79 | source = r.get("https://raw.githubusercontent.com/muneebwanee/GramScraper/main/.version") 80 | if source.text == '1.0': 81 | print(gr+'['+cy+'+'+gr+']'+cy+' alredy latest version') 82 | else: 83 | print(gr+'['+cy+'+'+gr+']'+cy+' removing old files ...') 84 | os.system('rm *.py');time.sleep(3) 85 | print(gr+'['+cy+'+'+gr+']'+cy+' getting latest files ...') 86 | os.system(""" 87 | curl -s -O https://raw.githubusercontent.com/muneebwanee/GramScraper/main/add2group.py 88 | curl -s -O https://raw.githubusercontent.com/muneebwanee/GramScraper/main/scraper.py 89 | curl -s -O https://raw.githubusercontent.com/muneebwanee/GramScraper/main/setup.py 90 | curl -s -O https://raw.githubusercontent.com/muneebwanee/GramScraper/main/smsbot.py 91 | chmod 777 *.py 92 | """);time.sleep(3) 93 | print(gr+'\n['+cy+'+'+gr+']'+cy+' update compled.\n') 94 | 95 | try: 96 | if any ([sys.argv[1] == '--config', sys.argv[1] == '-c']): 97 | print(gr+'['+cy+'+'+gr+']'+cy+' selected module : '+re+sys.argv[1]) 98 | config_setup() 99 | elif any ([sys.argv[1] == '--merge', sys.argv[1] == '-m']): 100 | print(gr+'['+cy+'+'+gr+']'+cy+' selected module : '+re+sys.argv[1]) 101 | merge_csv() 102 | elif any ([sys.argv[1] == '--update', sys.argv[1] == '-u']): 103 | print(gr+'['+cy+'+'+gr+']'+cy+' selected module : '+re+sys.argv[1]) 104 | update_tool() 105 | elif any ([sys.argv[1] == '--install', sys.argv[1] == '-i']): 106 | requirements() 107 | elif any ([sys.argv[1] == '--help', sys.argv[1] == '-h']): 108 | banner() 109 | print("""$ python3 setup.py -m file1.csv file2.csv 110 | 111 | ( --config / -c ) setup api configration 112 | ( --merge / -m ) merge 2 .csv files in one 113 | ( --update / -u ) update tool to latest version 114 | ( --install / -i ) install requirements 115 | ( --help / -h ) show this msg 116 | """) 117 | else: 118 | print('\n'+gr+'['+re+'!'+gr+']'+cy+' unknown argument : '+ sys.argv[1]) 119 | print(gr+'['+re+'!'+gr+']'+cy+' for help use : ') 120 | print(gr+'$ python3 setup.py -h'+'\n') 121 | except IndexError: 122 | print('\n'+gr+'['+re+'!'+gr+']'+cy+' no argument given : '+ sys.argv[1]) 123 | print(gr+'['+re+'!'+gr+']'+cy+' for help use : ') 124 | print(gr+'['+re+'!'+gr+']'+cy+' https://github.com/muneebwanee/GramScraper#-how-to-install-and-use') 125 | print(gr+'$ python3 setup.py -h'+'\n') 126 | --------------------------------------------------------------------------------