DEV Community

Kayabyte
Kayabyte

Posted on Edited on

Parsing WhatsApp chat exports: what real files taught me

A WhatsApp "Export chat" file looks easy: one line per message, a date, a name, some text. I wrote a parser for it, then ran it on 28 real exports from public open-source repos plus generated files across 40+ locale and platform profiles. Several of my assumptions didn't hold. Here's what can trip you up.

The date order isn't in the file

An export has no header saying whether 03/04/25 is 3 April or 4 March. It follows the phone's settings at export time.

You can often work it out, but only from the whole file:

  • If any first field is above 12, the file is day-first.
  • If any second field is above 12, it's month-first.
  • A 4-digit first field means year-month-day.

A short chat from the first 12 days of a month can stay truly ambiguous. In that case the only honest thing to do is ask the person, and remember the answer for that file's hash. Guessing is the one bug you'll never see in testing, and in my use case the dates matter a lot.

Don't decide from the first line, because it may not settle the question.

Times have no time zone

The export has local wall-clock times and nothing else. If two people in different zones export the same chat, the timestamps differ. Treat the zone as something the user confirms, and say so in the output.

"Me" isn't recorded

Exports contain display names, and nothing says which one belongs to the person who exported. The file name (WhatsApp Chat with Anna.txt) can suggest the other person in a 1:1 chat. Show it as a suggestion and let the user decide.

There are invisible characters in the text

iPhone exports put a left-to-right mark (U+200E) in front of some lines, like placeholders for omitted media and the notice about end-to-end encryption. That has two consequences:

A notice can parse as a message from a fake person. I had this bug. The text after Name: needs its leading space skipped before you test for the mark, and a marked line that isn't a known placeholder should become a system line. Otherwise "Messages and calls are end-to-end encrypted" turns into a participant.

Bidi overrides can change what a reader sees. WhatsApp writes embeddings and marks itself, and those should stay. U+202D and U+202E can make text display in a different order from how it's stored, so if your output is a document people rely on, show them visibly, as [U+202E].

Encoding and line endings vary

Expect CRLF, a BOM, UTF-16 and invalid UTF-8. Decode defensively, keep going, and report what you couldn't read.

"Message deleted" comes in every language

"This message was deleted", "" and the "edited" suffix are all written in the phone's language. A phrase table gets you far, but it will always be incomplete. When a phrase isn't listed, keep the original text and just don't label it. Never drop a line because you didn't recognise it.

Attachments have their own problem. The text names a file, and the zip might hold two files with the same name in different folders. Match the exact name first and treat anything ambiguous as unavailable, with a note. A wrong photo next to a message is worse than a missing one.

Zip files are input you shouldn't trust

If people hand you exports from someone else, cap entry count, total size and compression ratio. Ignore .., absolute paths, NUL bytes and symlinks. Extract media on demand to a private temp folder.

An export file can be edited

It's plain text, and anyone can change it in a text editor. So don't treat it like a database read. Record the SHA-256 of the file and say plainly in your output that it came from an export. A local iPhone backup is a different source: ChatStorage.sqlite in the domain AppDomainGroup-group.net.whatsapp.WhatsApp.shared, with stanza ids you can use to merge two backups of the same chat.

I don't give legal advice. If this is for a court, what counts as acceptable is a question for your lawyer or the court clerk.

Test on real files

Of the 28 public files, 27 imported, and the last is a deliberate negative with times only. Generated files mostly contain what you already expected, so real ones are worth the effort. There are gaps too: I found no public samples for Arabic, Hebrew, CJK or Russian, so those only have synthetic coverage.

Full disclosure: this parser is part of Exhibitly, my Mac app that turns text messages and WhatsApp chats into PDF and Excel files with a verification page. There's a free preview, and it runs offline. If you only need a one-off and can code, the notes above should get you most of the way.

Written with AI assistance. The findings come from my own review and test notes.

Top comments (0)