Skip to main content
The ingestion step is the entry point of the pipeline. An operator exports a WhatsApp chat log and uploads it through the web UI. The file is validated, then passed to the parsing engine.

Daily cut-off windows

Press clippings are collected in three windows per day. Each window represents a distinct export-and-upload cycle:
WindowCoverage period
MorningOvernight coverage through the start of the business day
MiddayMorning session through noon
AfternoonFull-day close
Upload promptly at each cut-off so officials receive timely digests. Late uploads delay the dispatch for the corresponding category panels.

Exporting from WhatsApp

1

Open the monitored group

In WhatsApp (mobile or desktop), navigate to the press clipping group managed by the monitoring team.
2

Open group settings

Tap the group name to open the group info screen.
3

Export chat without media

Scroll to the bottom and select Export chat. When prompted, choose Without media. This produces a .txt file containing only message text and metadata.
4

Transfer the file

Move the exported .txt file to the device you use to access the system (email, cloud storage, USB, etc.).
Always export without media. Including media produces a ZIP archive that the system cannot process, and upload will fail with a file-type error.

Uploading the file

Navigate to the ingestion view in the app. The Upload area accepts a single .txt file per session.

onFileSelected() handler

When you select a file, the onFileSelected() handler runs the following checks before proceeding:
  1. No-file check — if input.files is empty (no file was selected), an error message is stored and processing halts.
  2. MIME type check — the file must have type text/plain. Any other type triggers an error message and halts processing.
  3. Content read — the handler reads the file using the browser’s FileReader API and, on success, calls parseContent() with the raw text.
onFileSelected(event: Event): void {
  this.dataService.setLoading();
  const input = event.target as HTMLInputElement;
  if (!input.files?.length) {
    this.errorMessage = 'No se seleccionó ningún archivo.';
    return;
  }
  this.newAgrupadas = [];

  const file = input.files[0];
  if (file.type !== 'text/plain') {
    this.errorMessage = 'Por favor, selecciona un archivo .txt';
    return;
  }

  const reader = new FileReader();
  reader.onload = (e) => {
    const content = reader.result as string;
    this.parseContent(content);
  };
  reader.onerror = () => {
    this.errorMessage = 'Error al leer el archivo.';
  };
  reader.readAsText(file);
  this.dataService.setLoaded();
}
Only .txt files are supported. The MIME type must be text/plain.

Error states

If the file picker is opened and closed without selecting a file, input.files?.length is falsy. The handler sets errorMessage to 'No se seleccionó ningún archivo.' and stops processing. Nothing is uploaded.
If you select a file whose MIME type is not text/plain — for example, a .zip export that includes media, or a .pdf — the handler sets errorMessage to 'Por favor, selecciona un archivo .txt' and stops. The file is not read and parseContent() is never called. Select the correct WhatsApp text-only export and try again.
If the browser’s FileReader encounters an I/O error while reading, the reader.onerror callback sets errorMessage to 'Error al leer el archivo.'. This can happen if the file is locked by another process or the device storage is unavailable. Try exporting and transferring the file again.

What happens after upload

Once a valid file is read, parseContent() is invoked with the full text content. This triggers the parsing engine, which splits the log into individual messages, extracts structured fields from each one, and populates the ingestion view with the results.

Parsing

How the raw text is split into structured message objects.

Categorization

How parsed messages are matched to government areas using keywords.

Build docs developers (and LLMs) love