A Tool to download a entire Chat from Telegram to have a handy backup.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

telegramApi.py 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #!/usr/bin/env python3
  2. import configparser
  3. import os
  4. import sys
  5. from datetime import timedelta
  6. from telethon import TelegramClient, events
  7. from telethon.tl.types import User, Channel
  8. def strip(str):
  9. return ''.join(e for e in str if e.isalnum())
  10. def isBot(dialog):
  11. if not isinstance(d.entity, User):
  12. return False
  13. return d.entity.bot
  14. def isChannel(dialog):
  15. return isinstance(dialog, Channel)
  16. def printDialog(id, d):
  17. #print(d)
  18. # print (d.id, " ", d.name," ", d.pinned)
  19. print('{0:2d} | {1:14d} | {2:30} | {3:1}'.format(id, d.id, d.name, d.pinned))
  20. def saveMessage(message, file, dlid, ownid):
  21. out = None
  22. if message.message:
  23. # print(message)
  24. file.write(' <message>\n <date>')
  25. file.write(message.date.strftime("%s"))
  26. file.write('</date>\n <msg>')
  27. file.write(message.message)
  28. file.write('</msg>\n <me>')
  29. file.write(str(int(ownid == message.from_id)))
  30. file.write('</me>\n')
  31. # dl and write media if exist
  32. if message.media != None:
  33. file.write(' <media>')
  34. file.write(str(dlid))
  35. file.write('</media>\n')
  36. out = message
  37. file.write(' </message>\n')
  38. return out
  39. def createFolder(path):
  40. if not os.path.exists(path):
  41. os.makedirs(path)
  42. class DelayedDownload:
  43. """A class to store the data, for other methods to download media later"""
  44. message = None
  45. id = 1
  46. def __init__(self, _id, msg):
  47. self.id = _id
  48. self.message = msg
  49. def downloadChat(dialog, filename, downloadmedia):
  50. print ("selected: ", dialog.name, 'retriving chat!')
  51. chat = client.get_messages(dialog, limit=2000000)
  52. print("retrived ", len(chat), " Messages.")
  53. toDL = [] # list of DelayedDownload
  54. createFolder('out/')
  55. while True:
  56. try:
  57. fout = open('out/' + filename + '.xml', 'x')
  58. break
  59. except FileExistsError:
  60. get = input('Override out/' + filename + '.xml [y/n]?')
  61. if get == 'y' or get == 'Y':
  62. # delete
  63. os.remove('out/' + filename + '.xml')
  64. elif get == 'n' or get == 'N':
  65. # exit
  66. print ("Bye.")
  67. exit(2)
  68. fout.write('<chat>\n')
  69. for c in chat:
  70. dl = saveMessage(c, fout, len(toDL), me.id)
  71. if dl != None:
  72. if dl.media != None:
  73. # here is something to download later
  74. toDL.append(DelayedDownload(len(toDL), c))
  75. fout.write('</chat>\n')
  76. fout.close()
  77. if(downloadmedia):
  78. createFolder('out/media/')
  79. print('Chat structure stored. Downloading Media - this may take a while!')
  80. for dl in toDL:
  81. print ('.', end='')
  82. client.download_media(dl.message, "out/media/" + str(dl.id))
  83. print('\n', len(toDL), " Media Files Downloaded.")
  84. # ==================================
  85. # MAIN program
  86. # read config
  87. try:
  88. config = configparser.ConfigParser()
  89. config.read('config.ini')
  90. api_id = int(config.get('Main', 'api_id'))
  91. api_hash = config.get('Main', 'api_hash')
  92. workers = int(config.get('Main', 'workers'))
  93. session_name = config.get('Main', 'user')
  94. except (configparser.NoSectionError, configparser.NoOptionError, ValueError):
  95. print('invalid config.ini')
  96. exit(3)
  97. # create connection
  98. client = TelegramClient(session_name, api_id, api_hash, update_workers=workers, spawn_read_thread=True)
  99. client.start()
  100. me = client.get_me()
  101. # get dialogs
  102. dialogs = client.get_dialogs(limit=100)
  103. print ("chats loaded. (", len(dialogs), ")")
  104. # print chats
  105. id = 0
  106. # table header
  107. print (
  108. 'ID | Internal ID | Username | pinned\n———+————————————————+————————————————————————————————+———————')
  109. # content
  110. for d in dialogs:
  111. printDialog(id, d)
  112. id = id + 1
  113. get = input("Please Enter Chat ID or all: ")
  114. if get == 'all':
  115. for d in dialogs:
  116. if not isBot(d) and d.entity.id != me.id and not isChannel(d):
  117. downloadChat(d, strip(d.name), False)
  118. elif int(get) < 0 or int(get) >= id:
  119. print ("Unknown Chat ID!")
  120. exit(1)
  121. else:
  122. downloadChat(dialogs[int(get)], 'chat', True)
  123. print ('End.')