🤬
  • ■ ■ ■ ■ ■
    .gitignore
    1 1  *.session
    2 2  telepathy_files/
    3 3  .idea/
     4 +.venv/
    4 5  *.session-journal
    5 6  *.csv
  • ■ ■ ■ ■ ■ ■
    src/telepathy/config/config.ini
     1 +[telepathy]
     2 +telepathy_files = ./telepathy_files/
     3 +json_file = json_files
     4 +login = login.txt
     5 +log_file = log.csv
     6 +export_file = export.csv
     7 +location = locations
  • ■ ■ ■ ■ ■ ■
    src/telepathy/const.py
    skipped 5 lines
    6 6  __status__ = "Development"
    7 7   
    8 8  user_agent = [
    9  - 
    10 9   # Chrome
    11 10   "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36",
    12 11   "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36",
    skipped 5 lines
    18 17   "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36",
    19 18   "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
    20 19   "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
    21  - 
    22 20   # Firefox
    23 21   "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)",
    24 22   "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
    skipped 8 lines
    33 31   "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)",
    34 32   "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)",
    35 33   "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
    36  - 
    37 34   # Safari
    38 35   "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) RockMelt/0.9.50.549 Chrome/10.0.648.205 Safari/534.16"
    39 36   "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.18 (KHTML, like Gecko) Chrome/11.0.661.0 Safari/534.18"
    skipped 18 lines
    58 55   "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.9 (KHTML, like Gecko) Chrome/7.0.531.0 Safari/534.9"
    59 56   "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Iron/0.2.152.0 Safari/13657880.525",
    60 57  ]
     58 + 
     59 +telepathy_file = "./telepathy_files/"
     60 +json_file = telepathy_file + "json_files/"
     61 +login = telepathy_file + "login.txt"
     62 +log_file = telepathy_file + "log.csv"
     63 +export_file = telepathy_file + "export.csv"
     64 + 
  • src/telepathy/telepathy.py
    Diff is too large to be displayed.
  • ■ ■ ■ ■ ■ ■
    src/telepathy/utils.py
    1 1  from colorama import Fore, Style
    2 2  from googletrans import Translator
    3  -from telepathy.const import __version__, user_agent
     3 +from src.telepathy.const import __version__, user_agent
    4 4  import requests
    5 5  import textwrap
    6 6  from bs4 import BeautifulSoup
    7 7  import random
     8 +import os
     9 + 
    8 10   
    9 11  def createPlaceholdeCls():
    10 12   class Object(object):
    11 13   pass
     14 + 
    12 15   a = Object()
    13 16   return a
     17 + 
    14 18   
    15 19  def print_banner():
    16 20   print(
    skipped 6 lines
    23 27   /_/ \___/_/\___/ .___/\__,_/\__/_/ /_/\__, /
    24 28   /_/ /____/
    25 29   -- An OSINT toolkit for investigating Telegram chats.
    26  - -- Developed by @jordanwildon | Version """ + __version__ + """.
    27  - """ + Style.RESET_ALL
     30 + -- Developed by @jordanwildon | Version """
     31 + + __version__
     32 + + """.
     33 + """
     34 + + Style.RESET_ALL
    28 35   )
     36 + 
    29 37   
    30 38  def parse_tg_date(dd):
    31 39   year = str(format(dd.year, "02d"))
    skipped 5 lines
    37 45   date = year + "-" + month + "-" + day
    38 46   mtime = hour + ":" + minute + ":" + second
    39 47   timestamp = date + "T" + mtime + "+00:00"
    40  - return {"timestamp":timestamp, "date":date, "mtime":mtime}
     48 + return {"timestamp": timestamp, "date": date, "mtime": mtime}
    41 49   
    42 50   
    43 51  def populate_user(user, group_or_chat):
    skipped 47 lines
    91 99   "message_text": mess_txt,
    92 100   }
    93 101   
     102 + 
    94 103  def process_description(desc, user_lang):
    95 104   if desc is not None:
    96 105   desc_txt = '"' + desc + '"'
    skipped 19 lines
    116 125   "description_text": desc_txt,
    117 126   }
    118 127   
    119  -def color_print_green(first_string,second_string):
    120  - print(
    121  - Fore.GREEN
    122  - + first_string
    123  - + Style.RESET_ALL
    124  - + second_string
    125  - )
     128 + 
     129 +def color_print_green(first_string, second_string):
     130 + print(Fore.GREEN + first_string + Style.RESET_ALL + second_string)
     131 + 
    126 132   
    127 133  def parse_html_page(url):
    128 134   s = requests.Session()
    skipped 7 lines
    136 142   group_description = ""
    137 143   total_participants = ""
    138 144   try:
    139  - name = soup.find(
    140  - "div", {"class": ["tgme_page_title"]}
    141  - ).text
     145 + name = soup.find("div", {"class": ["tgme_page_title"]}).text
    142 146   except:
    143 147   name = "Not found"
    144 148   try:
    145  - group_description = soup.find(
    146  - "div", {"class": ["tgme_page_description"]}
    147  - ).text
    148  - descript = Fore.GREEN + "Description: " + Style.RESET_ALL+ group_description
     149 + group_description = (
     150 + soup.find("div", {"class": ["tgme_page_description"]})
     151 + .getText(separator="\n")
     152 + .replace("\n", " ")
     153 + )
     154 + # descript = Fore.GREEN + "Description: " + Style.RESET_ALL + group_description
    149 155   except:
    150 156   group_description = "None"
    151  - descript = Fore.GREEN + "Description: " + Style.RESET_ALL+ group_description
    152  - 
     157 + # descript = Fore.GREEN + "Description: " + Style.RESET_ALL + group_description
    153 158   try:
    154  - group_participants = soup.find(
    155  - "div", {"class": ["tgme_page_extra"]}
    156  - ).text
     159 + group_participants = soup.find("div", {"class": ["tgme_page_extra"]}).text
    157 160   sep = "members"
    158 161   stripped = group_participants.split(sep, 1)[0]
    159 162   total_participants = (
    skipped 4 lines
    164 167   )
    165 168   except:
    166 169   total_participants = "Not found"
    167  - 
    168  - return {"name":name,"group_description":group_description, "total_participants":total_participants}
     170 + return {
     171 + "name": name,
     172 + "group_description": group_description,
     173 + "total_participants": total_participants,
     174 + }
    169 175   
    170 176   
    171 177  def generate_textwrap(text_string, size=70):
    skipped 5 lines
    177 183   subsequent_indent=" ",
    178 184   )
    179 185   
     186 + 
    180 187  def print_shell(type, obj):
     188 + if type == "bot":
     189 + color_print_green(" [+] ", "Bot details for " + str(obj.id))
     190 + color_print_green(f" ├ Username: @{str(obj.username)}")
     191 + color_print_green(f" ├ Name: {str(obj.first_name)}")
     192 + color_print_green(f" └ Link: https://t.me/{str(obj.username)}")
     193 + print("\n")
     194 + color_print_green(" [+] ", "User related details for bot " + str(obj.id))
     195 + color_print_green(f" ├ User id: @{str(obj.user_id)}")
     196 + color_print_green(f" ├ User username: @{str(obj.user_username)}")
     197 + color_print_green(f" ├ User name: {str(obj.user_first_name)}")
     198 + color_print_green(f" └ Link: https://t.me/{str(obj.user_username)}")
     199 + 
    181 200   if type == "user":
    182 201   color_print_green(" [+] ", "User details for " + obj.target)
     202 + color_print_green(" ├ Id: ", str(obj.id))
    183 203   color_print_green(" ├ Username: ", str(obj.username))
    184 204   color_print_green(" ├ Name: ", str(obj.user_full_name))
    185 205   color_print_green(" ├ Verification: ", str(obj.verified))
    186 206   color_print_green(" ├ Photo ID: ", str(obj.user_photo))
    187 207   color_print_green(" ├ Phone number: ", str(obj.phone))
    188  - color_print_green(
    189  - " ├ Access hash: ", str(obj.access_hash)
    190  - )
     208 + color_print_green(" Access hash: ", str(obj.access_hash))
    191 209   color_print_green(" ├ Language: ", str(obj.lang_code))
    192 210   color_print_green(" ├ Bot: ", str(obj.bot))
    193 211   color_print_green(" ├ Scam: ", str(obj.scam))
    skipped 13 lines
    207 225   
    208 226   d_wrapper = generate_textwrap("Description:")
    209 227   td_wrapper = generate_textwrap("Translated Description:")
    210  - 
    211 228   color_print_green(" ┬ Chat details", "")
    212 229   color_print_green(" ├ Title: ", str(obj.title))
    213 230   color_print_green(" ├ ", d_wrapper.fill(obj.group_description))
    214 231   if obj.translated_description != obj.group_description:
    215 232   color_print_green(" ├ ", td_wrapper.fill(obj.translated_description))
    216  - color_print_green(
    217  - " ├ Total participants: ", str(obj.total_participants)
    218  - )
     233 + color_print_green(" ├ Total participants: ", str(obj.total_participants))
    219 234   
    220 235   if type == "group_recap":
    221 236   color_print_green(
    skipped 9 lines
    231 246   color_print_green(" ├ Chat type: ", str(obj.chat_type))
    232 247   color_print_green(" ├ Chat id: ", str(obj.id))
    233 248   color_print_green(" ├ Access hash: ", str(obj.access_hash))
    234  - if type == "channel_recap":
     249 + if type == "channel_recap":
    235 250   scam_status = str(obj.scam)
    236 251   color_print_green(" ├ Scam: ", str(scam_status))
    237 252   color_print_green(" ├ First post date: ", str(obj.first_post))
    238 253   if type == "group_recap":
    239  - color_print_green(
    240  - " ├ Memberlist saved to: ", obj.memberlist_filename
    241  - )
    242  - color_print_green(
    243  - " └ Restrictions: ", (str(obj.group_status))
    244  - )
     254 + color_print_green(" ├ Memberlist saved to: ", obj.memberlist_filename)
     255 + color_print_green(" └ Restrictions: ", (str(obj.group_status)))
    245 256   
    246 257   if type == "group_stat":
    247 258   color_print_green(" [+] Chat archive saved", "")
    248 259   color_print_green(" ┬ Chat statistics", "")
    249  - color_print_green(
    250  - " ├ Number of messages found: ", str(obj.messages_found)
    251  - )
    252  - color_print_green(
    253  - " ├ Top poster 1: ", str(obj.poster_one)
    254  - )
    255  - color_print_green(
    256  - " ├ Top poster 2: ", str(obj.poster_two)
    257  - )
    258  - color_print_green(
    259  - " ├ Top poster 3: ", str(obj.poster_three)
    260  - )
    261  - color_print_green(
    262  - " ├ Top poster 4: ", str(obj.poster_four)
    263  - )
    264  - color_print_green(
    265  - " ├ Top poster 5: ", str(obj.poster_five)
    266  - )
    267  - color_print_green(
    268  - " ├ Total unique posters: ", str(obj.unique_active)
    269  - )
    270  - color_print_green(
    271  - " └ Archive saved to: ", str(obj.file_archive)
    272  - )
     260 + color_print_green(" ├ Number of messages found: ", str(obj.messages_found))
     261 + color_print_green(" ├ Top poster 1: ", str(obj.poster_one))
     262 + color_print_green(" ├ Top poster 2: ", str(obj.poster_two))
     263 + color_print_green(" ├ Top poster 3: ", str(obj.poster_three))
     264 + color_print_green(" ├ Top poster 4: ", str(obj.poster_four))
     265 + color_print_green(" ├ Top poster 5: ", str(obj.poster_five))
     266 + color_print_green(" ├ Total unique posters: ", str(obj.unique_active))
     267 + color_print_green(" └ Archive saved to: ", str(obj.file_archive))
    273 268   return
    274 269   
    275 270   if type == "channel_stat":
    276 271   color_print_green(" [+] Channel archive saved", "")
    277 272   color_print_green(" ┬ Channel statistics", "")
    278  - color_print_green(
    279  - " ├ Number of messages found: ", str(obj.messages_found)
    280  - )
    281  - color_print_green(
    282  - " └ Archive saved to: ", str(obj.file_archive)
    283  - )
     273 + color_print_green(" ├ Number of messages found: ", str(obj.messages_found))
     274 + color_print_green(" └ Archive saved to: ", str(obj.file_archive))
    284 275   return
    285 276   
    286 277   if type == "reply_stat":
    skipped 12 lines
    299 290   " └ Active members list who replied to messages, saved to: ",
    300 291   str(obj.reply_memberlist_filename),
    301 292   )
    302  - color_print_green(
    303  - " Top replier 1: ", str(obj.replier_one)
    304  - )
    305  - color_print_green(
    306  - " ├ Top replier 2: ", str(obj.replier_two)
    307  - )
    308  - color_print_green(
    309  - " ├ Top replier 3: ", str(obj.replier_three)
    310  - )
    311  - color_print_green(
    312  - " ├ Top replier 4: ", str(obj.replier_four)
    313  - )
    314  - color_print_green(
    315  - " ├ Top replier 5: ", str(obj.replier_five)
    316  - )
    317  - color_print_green(
    318  - " └ Total unique repliers: ", str(obj.replier_unique)
    319  - )
     293 + color_print_green(" ┬ Top replier 1: ", str(obj.replier_one))
     294 + color_print_green(" Top replier 2: ", str(obj.replier_two))
     295 + color_print_green(" ├ Top replier 3: ", str(obj.replier_three))
     296 + color_print_green(" ├ Top replier 4: ", str(obj.replier_four))
     297 + color_print_green(" ├ Top replier 5: ", str(obj.replier_five))
     298 + color_print_green(" └ Total unique repliers: ", str(obj.replier_unique))
    320 299   
    321 300   if type == "forwarder_stat":
    322 301   color_print_green(" [+] Forward scrape complete", "")
    323 302   color_print_green(" ┬ Statistics", "")
    324  - color_print_green(
    325  - " ├ Forwarded messages found: ", str(obj.forward_count)
    326  - )
     303 + color_print_green(" ├ Forwarded messages found: ", str(obj.forward_count))
    327 304   color_print_green(
    328 305   " ├ Forwards from active public chats: ",
    329 306   str(obj.forwards_found),
    skipped 3 lines
    333 310   " ├ Forwards from private (or now private) chats: ",
    334 311   str(obj.private_count),
    335 312   )
    336  - color_print_green(
    337  - " ├ Unique forward sources: ", str(obj.unique_forwards)
    338  - )
    339  - color_print_green(
    340  - " ├ Top forward source 1: ", str(obj.forward_one)
    341  - )
    342  - color_print_green(
    343  - " ├ Top forward source 2: ", str(obj.forward_two)
    344  - )
    345  - color_print_green(
    346  - " ├ Top forward source 3: ", str(obj.forward_three)
    347  - )
    348  - color_print_green(
    349  - " ├ Top forward source 4: ", str(obj.forward_four)
    350  - )
    351  - color_print_green(
    352  - " ├ Top forward source 5: ", str(obj.forward_five)
    353  - )
     313 + color_print_green(" ├ Unique forward sources: ", str(obj.unique_forwards))
     314 + color_print_green(" ├ Top forward source 1: ", str(obj.forward_one))
     315 + color_print_green(" ├ Top forward source 2: ", str(obj.forward_two))
     316 + color_print_green(" ├ Top forward source 3: ", str(obj.forward_three))
     317 + color_print_green(" ├ Top forward source 4: ", str(obj.forward_four))
     318 + color_print_green(" ├ Top forward source 5: ", str(obj.forward_five))
    354 319   color_print_green(" └ Edgelist saved to: ", obj.edgelist_file)
     320 + 
     321 + 
     322 +def create_path(path_d):
     323 + if not os.path.exists(path_d):
     324 + os.makedirs(path_d)
     325 + return path_d
     326 + 
     327 + 
     328 +def create_file_report(save_dir, name, type, extension, file_time, append_time=True):
     329 + _time_append = ""
     330 + if append_time:
     331 + _time_append = "_" + file_time
     332 + return os.path.join(
     333 + "{}".format(save_dir), "{}{}_{}.{}".format(name, _time_append, type, extension)
     334 + )
     335 + 
     336 + 
     337 +def clean_private_invite(url):
     338 + if type(url) is not int:
     339 + if "https://t.me/+" in url:
     340 + return url.replace("https://t.me/+", "https://t.me/joinchat/")
     341 + return url
     342 + 
     343 + 
     344 +def evaluate_reactions(message, create=False):
     345 + total_reactions = 0
     346 + reactions = {}
     347 + if not create and message.reactions:
     348 + reactions_l = message.reactions.results
     349 + for idx, i in enumerate(reactions_l):
     350 + total_reactions = total_reactions + i.count
     351 + reactions["thumbs_up"] = i.count if i.reaction == "👍" else 0
     352 + reactions["thumbs_down"] = i.count if i.reaction == "👎" else 0
     353 + reactions["heart"] = i.count if i.reaction == "❤️" else 0
     354 + reactions["fire"] = i.count if i.reaction == "🔥" else 0
     355 + reactions["smile_with_hearts"] = i.count if i.reaction == "🥰" else 0
     356 + reactions["clap"] = i.count if i.reaction == "👏" else 0
     357 + reactions["smile"] = i.count if i.reaction == "😁" else 0
     358 + reactions["thinking"] = i.count if i.reaction == "🤔" else 0
     359 + reactions["exploding_head"] = i.count if i.reaction == "🤯" else 0
     360 + reactions["scream"] = i.count if i.reaction == "😱" else 0
     361 + reactions["angry"] = i.count if i.reaction == "🤬" else 0
     362 + reactions["single_tear"] = i.count if i.reaction == "😢" else 0
     363 + reactions["party_popper"] = i.count if i.reaction == "🎉" else 0
     364 + reactions["starstruck"] = i.count if i.reaction == "🤩" else 0
     365 + reactions["vomiting"] = i.count if i.reaction == "🤮" else 0
     366 + reactions["poop"] = i.count if i.reaction == "💩" else 0
     367 + reactions["praying"] = i.count if i.reaction == "🙏" else 0
     368 + else:
     369 + reactions["total_reactions"] = "N/A"
     370 + reactions["thumbs_up"] = "N/A"
     371 + reactions["thumbs_down"] = "N/A"
     372 + reactions["heart"] = "N/A"
     373 + reactions["fire"] = "N/A"
     374 + reactions["smile_with_hearts"] = "N/A"
     375 + reactions["clap"] = "N/A"
     376 + reactions["smile"] = "N/A"
     377 + reactions["thinking"] = "N/A"
     378 + reactions["exploding_head"] = "N/A"
     379 + reactions["scream"] = "N/A"
     380 + reactions["angry"] = "N/A"
     381 + reactions["single_tear"] = "N/A"
     382 + reactions["party_popper"] = "N/A"
     383 + reactions["starstruck"] = "N/A"
     384 + reactions["vomiting"] = "N/A"
     385 + reactions["poop"] = "N/A"
     386 + reactions["praying"] = "N/A"
     387 + return total_reactions, reactions
     388 + 
  • ■ ■ ■ ■ ■ ■
    tests/test_telepathy.py
     1 +import pytest
     2 +from src.telepathy.telepathy import Group_Chat_Analisys, Telepathy_cli
     3 +import asyncio
     4 + 
     5 + 
     6 +@pytest.fixture
     7 +def detail_to_group_basic():
     8 + return {
     9 + "target": "@test15",
     10 + "comprehensive": False,
     11 + "media": False,
     12 + "forwards": False,
     13 + "user": False,
     14 + "export": False,
     15 + "bot": None,
     16 + "location": None,
     17 + "alt": None,
     18 + "json": False,
     19 + "replies": False,
     20 + "translate": False,
     21 + "triangulate_membership": False,
     22 + }
     23 + 
     24 +def test_channel_group_basic(detail_to_group_basic):
     25 + tele_cli = Telepathy_cli(
     26 + detail_to_group_basic["target"],
     27 + detail_to_group_basic["comprehensive"],
     28 + detail_to_group_basic["media"],
     29 + detail_to_group_basic["forwards"],
     30 + detail_to_group_basic["user"],
     31 + detail_to_group_basic["bot"],
     32 + detail_to_group_basic["location"],
     33 + detail_to_group_basic["alt"],
     34 + detail_to_group_basic["json"],
     35 + detail_to_group_basic["export"],
     36 + detail_to_group_basic["replies"],
     37 + detail_to_group_basic["translate"],
     38 + detail_to_group_basic["triangulate_membership"],
     39 + )
     40 + group_chan = Group_Chat_Analisys(
     41 + target=detail_to_group_basic["target"],
     42 + client=tele_cli.client,
     43 + log_file=tele_cli.log_file,
     44 + filetime=tele_cli.filetime,
     45 + replies=tele_cli.reply_analysis,
     46 + forwards=tele_cli.forwards_check,
     47 + comprehensive=tele_cli.comp_check,
     48 + media=tele_cli.media_archive,
     49 + json=tele_cli.json_check,
     50 + translate=tele_cli.translate_check,
     51 + )
     52 + 
     53 + loop = asyncio.new_event_loop()
     54 + asyncio.set_event_loop(loop)
     55 + loop.run_until_complete(tele_cli.client.connect())
     56 + loop.run_until_complete(group_chan.retrieve_self_history(None))
     57 + assert group_chan.history_count > 0
     58 + 
Please wait...
Page is in error, reload to recover