Cortesía de opencode XD.

#!/bin/bash
USERNAME="${1:-}"
OUTPUT_DIR="${2:-./instagram_stories}"

if [ -z "$USERNAME" ]; then
    echo "Uso: $0 <nombre_usuario> [directorio_salida]"
    exit 1
fi

URL="https://iqsaved.com/viewer/$USERNAME"
echo "Descargando historias de: $URL"

mkdir -p "$OUTPUT_DIR"
cd "$OUTPUT_DIR"

echo "Iniciando chromium..."
chromium --headless=new --disable-gpu --no-sandbox --remote-debugging-port=9222 "$URL" > /dev/null 2>&1 &
CHROME_PID=$!
sleep 6

WS_URL=$(curl -s http://localhost:9222/json | python3 -c "
import sys, json
pages = json.load(sys.stdin)
target = [p for p in pages if '$USERNAME' in p.get('url','') or 'iqsaved' in p.get('url','')]
if target:
    print(target[0]['webSocketDebuggerUrl'])
" 2>/dev/null)

if [ -z "$WS_URL" ]; then
    echo "Error: No se pudo obtener WebSocket URL"
    kill $CHROME_PID 2>/dev/null
    exit 1
fi

echo "WebSocket: $WS_URL"

WS_DIR="/tmp/ws_cdp"
mkdir -p "$WS_DIR"
cd "$WS_DIR"
npm init -y > /dev/null 2>&1
npm install ws > /dev/null 2>&1

cat > "$WS_DIR/get_stories.js" << 'SCRIPT_EOF'
const WebSocket = require('ws');
const ws = new WebSocket(process.argv[2]);
let cmdId = 0;

function send(method, params) {
    return new Promise((resolve) => {
        const id = ++cmdId;
        ws.send(JSON.stringify({id, method, params}));
        ws.once('message', (data) => resolve(JSON.parse(data)));
    });
}

ws.on('open', async function() {
    console.error('Cargando pagina...');
    await new Promise(r => setTimeout(r, 5000));
    
    console.error('Haciendo scroll...');
    for (let i = 0; i < 20; i++) {
        await send('Runtime.evaluate', {
            expression: 'window.scrollBy(0, 500);'
        });
        await new Promise(r => setTimeout(r, 500));
    }
    
    console.error('Extrayendo imagenes y videos...');
    const r = await send('Runtime.evaluate', {
        expression: 'var imgs = document.querySelectorAll("img"); var results = []; for (var i = 0; i < imgs.length; i++) { var src = imgs[i].dataset.src || imgs[i].src; if (src && src.indexOf("cdn.iqsaved") > -1) { results.push({href: src, type: "img"}); } } var links = document.querySelectorAll("a[href*=\\"cdn.iqsaved\\"]"); for (var j = 0; j < links.length; j++) { if (links[j].href.indexOf(".mp4") > -1) { results.push({href: links[j].href, type: "video"}); } } JSON.stringify(results)'
    });
    
    if (r.result && r.result.result) {
        console.log(r.result.result.value);
    }
    ws.close();
});

ws.on('error', function(e) {
    console.error('Error:', e.message);
    process.exit(1);
});
SCRIPT_EOF

JSON_RESULT=$(cd "$WS_DIR" && node get_stories.js "$WS_URL" 2>/dev/null)

kill $CHROME_PID 2>/dev/null

cd "$OUTPUT_DIR"

echo "$JSON_RESULT" | python3 -c "
import sys, json, subprocess, os, urllib.request

try:
    data = json.load(sys.stdin)
    downloads = data if isinstance(data, list) else data.get('downloads', [])
    
    if not downloads:
        print('No se encontraron descargas')
        sys.exit(0)
    
    print(f'Encontrados {len(downloads)} archivos')
    
    for i, item in enumerate(downloads, 1):
        url = item['href']
        item_type = item.get('type', '')
        
        if item_type == 'video' or '.mp4' in url:
            ext = 'mp4'
        else:
            try:
                req = urllib.request.Request(url, method='HEAD')
                req.add_header('User-Agent', 'Mozilla/5.0')
                resp = urllib.request.urlopen(req, timeout=10)
                content_type = resp.headers.get('Content-Type', '').lower()
                if 'jpeg' in content_type or 'jpg' in content_type:
                    ext = 'jpg'
                elif 'png' in content_type:
                    ext = 'png'
                elif 'video' in content_type or 'mp4' in content_type:
                    ext = 'mp4'
                else:
                    ext = 'bin'
            except:
                ext = 'jpg'
        
        outfile = f'{i}.{ext}'
        
        if os.path.exists(outfile) and os.path.getsize(outfile) > 1000:
            print(f'Omitiendo {outfile} (ya existe)')
            continue
        
        print(f'Descargando {outfile}...')
        subprocess.run(['wget', '-q', '-U', 'Mozilla/5.0', '-O', outfile, url], check=True)
    
    print('Descarga completa!')
except Exception as e:
    print(f'Error: {e}')
    sys.exit(1)
"

echo "Archivos en: $(pwd)"
ls -la