Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
A script to help you migrate your whole WhatsApp chat history with a person to Telegram
import os
import re
import shutil
# A script to help you migrate your whole WhatsApp chat history with a person to Telegram
# Instructions
# 1. Install "Backup WhatsApp Chats" extenstion to Chrome
# 2. Buy a license
# 3. Open WhatsApp web and select the chat to export
# 4. Open the plugin, choose export type 'HTML', choose to download unresolved media
# 5. Download and extract the zip file to data/exported
# 6. Open the plugin again and choose export type 'Text'
# 7. Download the text file to data/exported as well
# 8. Edit CHAT_NAME and SELF_NAME constants below
# 9. Create output directory at data/converted
# 10. Run 'python'
# 11. Copy the contents of data/converted to your phone
# 12. Open your favorite file browser, select all files and share them to Telegram
# -> Telegram should now ask you where to import the messages
# 13. Select the target chat and hit import
# Issues
# - For some reason, the current day is skipped during export
# - For some reason, copying the output files to the phone via USB will cause media files to not be imported. Instead, I uploaded them to Nextcloud, then synced them on the phone using the Nextcloud app and then shared them to Telegram using a file manager. The trick is probably to somehow get this ( method to return null, so that the shared media documents are added to documentsUrisArray instead of documentsPathsArray.
# Relevant code in Telegram for Android
# -
# -
# -
# Constants
CHAT_NAME = 'John Doe' # change this
SELF_NAME = 'Jane Doe' # change this
INPUT_DIR = './data/exported'
OUTPUT_DIR = './data/converted'
OUTPUT_FILE = f'WhatsApp Chat mit {CHAT_NAME}.txt'
DATE_REGEX = '(\d{4}/\d{2}/\d{2}), (\d{2}:\d{2}:\d{2})'
MEDIA_FILE_REGEX = '.+\.(jpg|jpeg|png|mp4|oga|webp)$'
MEDIA_INDICATOR = '<Media omitted>'
MEDIA_TARGET_SUFFIX = '(Datei angehängt)'
# Methods
def read_messages():
lines = []
file_name = f'{INPUT_DIR}/{CHAT_NAME}.txt'
print(f'reading {file_name}')
with open(file_name, 'r') as f:
while True:
line = f.readline()
if not line:
if re.match(LINE_REGEX, line):
elif not re.match(DATE_REGEX, line) and len(lines) > 0:
lines[-1] += line
print(f'read {len(lines)} messages')
return lines
def find_media():
return [f for f in os.listdir(INPUT_DIR) if re.match(MEDIA_FILE_REGEX, f, re.IGNORECASE)]
def extract_datetime(message):
date_match =, message)
date_components ='/')
time_components =':')
return date_components, time_components
def replace_media_refs(messages):
new_messages = [m for m in messages]
media_files = find_media()
print(f'found {len(media_files)} media files')
for i, m in enumerate(new_messages):
if not MEDIA_INDICATOR in m:
date_components, time_components = extract_datetime(m)
media_prefix = f'{"_".join(date_components)}_{"".join(time_components)}'
media_candidates = [f for f in media_files if f.startswith(media_prefix)]
if len(media_candidates) == 0:
print(f'warning: did not find matching media file for message at {media_prefix}')
new_messages[i] = m.replace(MEDIA_INDICATOR, f'{media_candidates[0]} {MEDIA_TARGET_SUFFIX}')
return new_messages
def write_messages(messages):
out_file_name = f'{OUTPUT_DIR}/{OUTPUT_FILE}'
print(f'saving messages to {out_file_name}')
with open(out_file_name, 'w') as f:
for m in messages:
# dc, tc = extract_datetime(m)
# m = re.sub(DATE_REGEX, f'{dc[2]}.{dc[1]}.{dc[0][2:]}, {":".join(tc[:2])}', m) if dc and tc else m
def copy_media():
for f in find_media():
shutil.copy2(f'{INPUT_DIR}/{f}', f'{OUTPUT_DIR}/{f}')
if __name__ == '__main__':
print('reading messages')
messages = read_messages()
print('replacing media references')
messages = replace_media_refs(messages)
print('saving output')
print('copying media')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment