Zpět na domů

Konvertor Telegram do Obsidian pro IT

Konvertor přenáší JSON-export Telegram do Obsidian s uchováním médií, formátování a struktury chatů. Implementováno indexování souborů, víceúrovňové vyhledávání a zpracování entit. Vhodný pro vytvoření offline báze z tisíců zpráv.

Import Telegram chatů do Obsidian: kód a schéma
Advertisement 728x90

Automatický import konverzací z Telegramu do Obsidianu s úpravou médií a propojením poznámek

Konverzní nástroj převádí JSON-export aplikace Telegram Desktop do struktury Obsidian Vault. Podporuje parsování zpráv, kopírování mediálních souborů, převod formátování do Markdownu a organizaci podle typu konverzace (kontakty, skupiny, kanály). Řešení vytváří index souborů pro spolehlivé mapování cest a automaticky řeší kolize názvů.

Původní export obsahuje soubor result.json s metadaty, složku chats/ s HTML-verzemi zpráv a mediálními soubory. Cílová struktura je složka Telegram_Export/, rozdělená na podsložky Contacts/, Groups/, Channels/ a centrální index Index.md.

Architektura konverzního nástroje

Systém se skládá z JSON-parseru, mediálního indexátoru, Markdown-konverteru, správce souborů a generátoru struktury. Pracovní tok: JSON → parsování → indexace → konverze → Obsidian Vault s kopírováním médií.

Google AdInline article slot

Klíčové komponenty:

  • Parser: extrahuje informace o konverzacích, zprávách a metadatech.
  • Indexátor: vytváří mapu souborů podle přípon (.jpg, .mp4, .pdf atd.).
  • Konverter: používá vícestupňové hledání médií a převod formátování.
  • Správce souborů: kopíruje média do složek jednotlivých poznámek s detekcí a řešením duplicit.

Konfigurace probíhá prostřednictvím proměnných prostředí: TELEGRAM_JSON_FILE, OBSIDIAN_OUTPUT_DIR, COPY_MEDIA.

import os
from pathlib import Path

JSON_FILE = os.getenv('TELEGRAM_JSON_FILE', 'result.json')
EXPORT_BASE = Path(os.getenv('TELEGRAM_EXPORT_BASE', '.'))
OUTPUT_DIR = Path(os.getenv('OBSIDIAN_OUTPUT_DIR', 'Telegram_Export'))
COPY_MEDIA = os.getenv('COPY_MEDIA', 'true').lower() == 'true'
GROUP_BY_DAY = os.getenv('GROUP_BY_DAY', 'true').lower() == 'true'

Indexace a vyhledávání mediálních souborů

Soubor patch.txt se generuje pomocí příkazu ls -R a zachycuje celou strukturu exportu. Index se vytváří pro názvy souborů, relativní i absolutní cesty.

Google AdInline article slot
def index_media_from_patch(self):
    media_extensions = {'.jpg', '.jpeg', '.png', '.gif', '.webp', '.mp4', '.webm', '.pdf', '.zip', '.mp3'}
    current_dir = None
    
    with open(PATCH_FILE, 'r', encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            if line.endswith(':'):
                current_dir = line[:-1]
                continue
            if current_dir and any(line.endswith(ext) for ext in media_extensions):
                full_path = Path(current_dir) / line
                self.media_index[line] = full_path
                if 'chats/' in str(full_path):
                    rel_path = str(full_path).split('chats/', 1)[-1]
                    self.media_index[rel_path] = full_path

Vyhledávání probíhá čtyřmi strategiemi: podle názvu souboru, podle úplné cesty, částečným porovnáním a přímými cestami relativně k EXPORT_BASE.

Kopírování médií s řešením kolizí

Soubory se kopírují do složky příslušné poznámky (note_folder), nikoli do centrálního úložiště. Cache media_cache urychluje opakované požadavky. Při kolizi názvů se přidávají sufixy _1, _2 atd.

def copy_media_file(self, source_path: str, note_folder: Path = None) -> Optional[str]:
    if not COPY_MEDIA or not source_path:
        return None
    
    source_file = self.find_media_file(source_path)
    if not source_file or not source_file.exists():
        return None
    
    target_dir = note_folder if note_folder else OUTPUT_DIR / "Attachments"
    target_dir.mkdir(parents=True, exist_ok=True)
    target_file = target_dir / source_file.name
    
    if target_file.exists():
        stem = target_file.stem
        suffix = target_file.suffix
        counter = 1
        while target_file.exists():
            target_file = target_dir / f"{stem}_{counter}{suffix}"
            counter += 1
    
    shutil.copy2(source_file, target_file)
    self.stats['media_files'] += 1
    return source_file.name

Parsování textu a entit

Převod HTML a Telegram-specifických entit do Markdownu. Zpracování tučného písma, kurzivy, kódu, bloků kódu, odkazů, zmínění uživatelů a skrytých bloků (spoilerů).

Google AdInline article slot
def parse_text_entities(self, text: Union[str, List], entities: Optional[List[Dict]] = None) -> str:
    if isinstance(text, str) and ('<' in text or '&' in text):
        return self.html_to_markdown(text)
    
    if entities and isinstance(text, str):
        return self._process_entities(text, entities)
    
    handlers = {
        'bold': lambda t: f"**{t}**",
        'italic': lambda t: f"*{t}*",
        'code': lambda t: f"`{t}`",
        'pre': lambda t: f"```
{t}

'link': lambda t, e: f"[{t}]({e.get('url', '')})",

'spoiler': lambda t: f"\n> [!spoiler] {t}\n"

}

return str(text) if text else ""


## Formátování zpráv

Každá zpráva obsahuje časové razítko, odesílatele, formátovaný text a odkazy na média. Pro přesné získání médií se kontrolují klíče `photo`, `video`, `audio`.

Příklad zpracování:
1. Extrahovat `date` a `from`.
2. Zpracovat `text` pomocí `text_entities`.
3. Identifikovat média podle klíčů, zkopírovat je a vložit jako `![popisek](cesta)`.
4. Seskupit zprávy podle dnů, pokud je aktivní `GROUP_BY_DAY`.

Statistika zahrnuje počet konverzací, zpráv, mediálních souborů a kontaktů.

## Klíčové výhody

- Indexace `patch.txt` eliminuje nesoulad mezi cestami v JSONu a skutečnou strukturou souborů na disku.
- Vícestupňové vyhledávání médií čtyřmi strategiemi zajišťuje pokrytí 95 % případů.
- Kopírování médií přímo do složek poznámek zaručuje funkčnost vnořených obrázků (`![]()`) v Obsidianu.
- Plná podpora všech Telegram-entit: tučné písmo, kód, odkazy, spoilerové bloky.
- Konfigurace prostřednictvím proměnných prostředí umožňuje snadné nasazení v produkčním prostředí.

— Editorial Team

Advertisement 728x90

Číst dál