Created
February 28, 2026 19:11
-
-
Save lucabased/0d231c317dc768c9e460c2ad4842862c to your computer and use it in GitHub Desktop.
Paste Threema Chat Export logs into a readable format
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!doctype html> | |
| <html lang="de"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width,initial-scale=1"> | |
| <title>Threema Export Viewer</title> | |
| <style> | |
| body{ | |
| margin:0; | |
| background:#0f172a; | |
| font-family:system-ui,-apple-system,Segoe UI,Roboto; | |
| color:white; | |
| display:flex; | |
| flex-direction:column; | |
| height:100vh; | |
| } | |
| header{ | |
| padding:12px 16px; | |
| background:#111827; | |
| font-weight:600; | |
| } | |
| textarea{ | |
| width:100%; | |
| height:180px; | |
| background:#0b1220; | |
| color:#fff; | |
| border:none; | |
| padding:12px; | |
| resize:none; | |
| font-family:monospace; | |
| } | |
| button{ | |
| padding:10px 14px; | |
| border:none; | |
| background:#2563eb; | |
| color:white; | |
| cursor:pointer; | |
| } | |
| .chat{ | |
| flex:1; | |
| overflow:auto; | |
| padding:20px; | |
| display:flex; | |
| flex-direction:column; | |
| gap:12px; | |
| } | |
| .row{ | |
| display:flex; | |
| } | |
| .row.in{ justify-content:flex-start; } | |
| .row.out{ justify-content:flex-end; } | |
| .bubble{ | |
| max-width:75%; | |
| padding:10px 14px; | |
| border-radius:16px; | |
| line-height:1.4; | |
| word-break:break-word; | |
| } | |
| .in .bubble{ | |
| background:#1f2937; | |
| border-top-left-radius:6px; | |
| } | |
| .out .bubble{ | |
| background:#1d4ed8; | |
| border-top-right-radius:6px; | |
| } | |
| .meta{ | |
| font-size:11px; | |
| opacity:.6; | |
| margin-top:6px; | |
| text-align:right; | |
| } | |
| .system{ | |
| text-align:center; | |
| font-size:12px; | |
| opacity:.6; | |
| margin:10px 0; | |
| } | |
| .file{ | |
| margin-top:8px; | |
| padding:8px; | |
| border-radius:10px; | |
| background:rgba(255,255,255,0.1); | |
| font-size:13px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header>Threema Chat Export Viewer</header> | |
| <textarea id="input" placeholder="Hier Threema-Export einfügen..."></textarea> | |
| <button onclick="parseChat()">Chat anzeigen</button> | |
| <div class="chat" id="chat"></div> | |
| <script> | |
| function parseChat(){ | |
| const raw = document.getElementById("input").value; | |
| const chat = document.getElementById("chat"); | |
| chat.innerHTML = ""; | |
| const lines = raw.split("\n").filter(l=>l.trim() !== ""); | |
| const regex = /^(>>>|<<<)\s(.+?)\sum\s(.+?)\sMEZ:\s?(.*)$/; | |
| lines.forEach(line=>{ | |
| const match = line.match(regex); | |
| if(!match) return; | |
| const directionSymbol = match[1]; | |
| const date = match[2]; | |
| const time = match[3]; | |
| let content = match[4]; | |
| // Systemmeldung erkennen | |
| if(content.includes("Perfect Forward Secrecy")){ | |
| const sys = document.createElement("div"); | |
| sys.className = "system"; | |
| sys.textContent = date + " " + time + " – " + content; | |
| chat.appendChild(sys); | |
| return; | |
| } | |
| const row = document.createElement("div"); | |
| row.className = "row " + (directionSymbol === ">>>" ? "out" : "in"); | |
| const bubble = document.createElement("div"); | |
| bubble.className = "bubble"; | |
| // Datei erkennen | |
| if(content.startsWith("Datei")){ | |
| const fileMatch = content.match(/Datei \((.*?)\)(?:, Untertitel: (.*))?/); | |
| bubble.innerHTML = "<strong>📎 Datei</strong>"; | |
| const fileDiv = document.createElement("div"); | |
| fileDiv.className = "file"; | |
| fileDiv.textContent = fileMatch ? fileMatch[1] : ""; | |
| bubble.appendChild(fileDiv); | |
| if(fileMatch && fileMatch[2]){ | |
| const caption = document.createElement("div"); | |
| caption.style.marginTop="6px"; | |
| caption.textContent = fileMatch[2]; | |
| bubble.appendChild(caption); | |
| } | |
| } else { | |
| bubble.textContent = content; | |
| } | |
| const meta = document.createElement("div"); | |
| meta.className="meta"; | |
| meta.textContent = date + " " + time; | |
| bubble.appendChild(meta); | |
| row.appendChild(bubble); | |
| chat.appendChild(row); | |
| }); | |
| chat.scrollTop = chat.scrollHeight; | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment