¿Alguna vez has explicado un proceso completo por WhatsApp enviando capturas de pantalla, notas de voz y mensajes de texto… y pensaste: “Ojalá pudiera convertir esto en un tutorial sin tener que redactarlo todo desde cero”? 🤔💡
Cuando exportas un chat con archivos multimedia, WhatsApp te entrega un archivo .zip desordenado: un archivo .txt por un lado, carpetas llenas de fotos sueltas por otro, y audios en formato .opus que son imposibles de leer en un documento.
¡Hoy vamos a solucionar eso! 🚀 Veremos cómo transformar ese .zip en un PDF interactivo y visual con:
- 📸 Imágenes incrustadas en el lugar exacto donde se enviaron.
- 🎙️ Audios transcritos automáticamente a texto usando Inteligencia Artificial local.
- 📄 Diseño limpio estilo WhatsApp listo para que una IA (como Gemini o ChatGPT) lo lea y redacte un tutorial profesional en segundos.
🛠️ ¿Qué necesitamos?
Solo necesitas tu computadora (preferiblemente con Linux o terminal) y unas pocas herramientas gratuitas:
- Python 3 instalado.
- FFmpeg (para procesar los archivos de audio).
- faster-whisper (un modelo de IA local ultrarrápido que convierte voz a texto sin enviar tus audios a internet).
🚀 Paso 1: Preparar el entorno
Para evitar conflictos de librerías en sistemas modernos, abrimos la terminal y preparamos nuestro entorno virtual en un par de comandos:
Bash
# 1. Instalar herramientas base
sudo apt update && sudo apt install -y ffmpeg python3-pip python3-venv
# 2. Crear y activar un entorno virtual
python3 -m venv env_whatsapp
source env_whatsapp/bin/activate
# 3. Instalar la IA de transcripción
pip install faster-whisper
🔒 Dato clave de privacidad:
faster-whispercorre 100% en tu procesador. Tus conversaciones privadas nunca salen de tu máquina.
🐍 Paso 2: El script mágico
Creamos un archivo llamado exportar_chat_completo.py y pegamos un script que haga tres tareas automáticas:
- Leer el archivo
.txty armar las burbujas de diálogo. - Detectar las imágenes
.jpgo.pngy convertirlas a Base64 para que queden incrustadas directamente dentro del HTML. - Detectar las notas de voz
.opus, transcribirlas con Whisper e insertar el texto dentro de la conversación.
Código del script:
Python
#!/usr/bin/env python3
import sys, os, re, zipfile, base64, html, tempfile
from faster_whisper import WhisperModel
if len(sys.argv) < 2:
print("Uso: python exportar_chat_completo.py <archivo.zip>")
sys.exit(1)
zip_path = sys.argv[1]
output_html = "chat_completo.html"
print("🧠 Cargando modelo de transcripción...")
whisper_model = WhisperModel("base", device="cpu", compute_type="int8")
with zipfile.ZipFile(zip_path, 'r') as z:
file_list = z.namelist()
txt_name = [f for f in file_list if f.endswith('.txt')][0]
chat_content = z.read(txt_name).decode('utf-8-sig', errors='replace')
# Regex para extraer mensajes
msg_pattern = re.compile(r"^\[?(\d{1,2}/\d{1,2}/\d{2,4},?\s+\d{1,2}:\d{2}(?::\d{2})?(?:\s+[ap]\.?\s?m\.?)?)\]?\s*(?:-\s*)?([^:]+):\s*(.*)$", re.IGNORECASE)
messages, senders, current_msg = [], set(), None
for line in chat_content.splitlines():
match = msg_pattern.match(line)
if match:
if current_msg: messages.append(current_msg)
dt, sender, text = match.groups()
senders.add(sender.strip())
current_msg = {'time': dt.strip(), 'sender': sender.strip(), 'text': text.strip()}
elif current_msg:
current_msg['text'] += "\n" + line
if current_msg: messages.append(current_msg)
primary_sender = list(senders)[0] if senders else ""
img_pattern = re.compile(r"([\w\-\.]+\.(?:jpg|jpeg|png|webp))", re.IGNORECASE)
audio_pattern = re.compile(r"([\w\-\.]+\.(?:opus|m4a|mp3|ogg))", re.IGNORECASE)
bubbles = []
print(f"📦 Procesando {len(messages)} mensajes...")
for idx, msg in enumerate(messages, start=1):
is_me = (msg['sender'] == primary_sender)
bubble_cls = "bubble outgoing" if is_me else "bubble incoming"
raw_text = msg['text']
# Incrustar fotos en Base64
imgs_html = ""
for img_name in img_pattern.findall(raw_text):
target = [f for f in file_list if f.endswith(img_name)]
if target:
data = base64.b64encode(z.read(target[0])).decode('utf-8')
imgs_html += f'<div class="img-box"><img src="data:image/jpeg;base64,{data}" /></div>'
# Transcribir audios con IA
audios_html = ""
for aud_name in audio_pattern.findall(raw_text):
target = [f for f in file_list if f.endswith(aud_name)]
if target:
print(f"🎙️ Transcribiendo audio: {aud_name}...")
with tempfile.NamedTemporaryFile(suffix=os.path.splitext(aud_name)[1], delete=False) as tmp:
tmp.write(z.read(target[0]))
tmp_p = tmp.name
try:
segs, _ = whisper_model.transcribe(tmp_p, language="es")
txt = " ".join([s.text for s in segs]).strip() or "(Audio sin voz clara)"
except:
txt = "(Error en transcripción)"
finally:
if os.path.exists(tmp_p): os.remove(tmp_p)
audios_html += f'<div class="audio-box"><strong>🎙️ Transcripción:</strong> "{html.escape(txt)}"</div>'
clean_text = html.escape(raw_text).replace('\n', '<br>')
bubbles.append(f"""
<div class="{bubble_cls}">
<div class="sender">{html.escape(msg['sender'])}</div>
{imgs_html}
{audios_html}
<div class="txt">{clean_text}</div>
<div class="time">{html.escape(msg['time'])}</div>
</div>
""")
# Estilos CSS listos para imprimir a PDF
html_doc = f"""<!DOCTYPE html><html><head><meta charset="utf-8">
<style>
body {{ background: #efeae2; font-family: sans-serif; display: flex; justify-content: center; padding: 20px; }}
.chat {{ width: 100%; max-width: 780px; display: flex; flex-direction: column; gap: 8px; }}
.bubble {{ max-width: 75%; padding: 8px 12px; border-radius: 8px; font-size: 14px; display: flex; flex-direction: column; }}
.incoming {{ background: #fff; align-self: flex-start; }}
.outgoing {{ background: #d9fdd3; align-self: flex-end; }}
.sender {{ font-weight: bold; font-size: 11px; color: #128c7e; margin-bottom: 3px; }}
.outgoing .sender {{ display: none; }}
.img-box img {{ max-width: 100%; border-radius: 6px; margin: 5px 0; }}
.audio-box {{ background: rgba(0,0,0,0.05); border-left: 3px solid #00a884; padding: 6px 10px; margin: 5px 0; font-style: italic; }}
.time {{ font-size: 10px; color: #667781; align-self: flex-end; margin-top: 4px; }}
@media print {{ body {{ background: white; }} .bubble {{ page-break-inside: avoid; border: 1px solid #ccc; }} }}
</style></head><body><div class="chat">{''.join(bubbles)}</div></body></html>"""
with open(output_html, "w", encoding="utf-8") as f:
f.write(html_doc)
print(f"🎉 ¡Listo! Archivo '{output_html}' generado con éxito.")
⚡ Paso 3: Ejecutar y exportar a PDF
- Corre el script con tu chat:Bash
python exportar_chat_completo.py "MiChatExportado.zip" - Abre el archivo generado (
chat_completo.html) en tu navegador favorito. - Presiona Ctrl + P (Imprimir).
- Elige Guardar como PDF y asegúrate de marcar la casilla “Gráficos de fondo” para que conserve los colores originales.
🧠 Paso 4: La magia de la IA para armar tu tutorial
¡Ahora viene lo mejor! Sube tu nuevo archivo PDF a una IA multimodal y dale esta instrucción:
“Actúa como redactor técnico y diseñador instruccional. Analiza este documento PDF que contiene capturas, mensajes y transcripciones de notas de voz. Descarta las charlas casuales y crea un tutorial paso a paso numerado, explicando cada acción y detallando qué se observa en cada captura de pantalla para guiar al usuario.”
En cuestión de segundos tendrás un manual técnico o una guía de uso impecable, estructurada y sin haber pasado horas transcribiendo audios ni acomodando capturas en Word. 🎯👏
¿Qué te parece este flujo de trabajo? ¡Pruébalo con tu próxima explicación técnica y cuéntanos en los comentarios cómo te fue! 👇💬