尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證TrenBot
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
📖 FUNCIONAMIENTO.md — cómo funciona por dentro: arquitectura, qué avisos manda y cuándo, las trampas de cada API, qué se auto-repara y qué hacer si algo falla. Empieza por ahí. Vigila la disponibilidad de billetes (trenes y vuelos) y te avisa por Telegram • Mac en cuanto aparece una plaza — ideal para trenes agotados que dependen de cancelaciones de última hora.檢視完整 README ↗
📖 FUNCIONAMIENTO.md — cómo funciona por dentro: arquitectura, qué avisos manda y cuándo, las trampas de cada API, qué se auto-repara y qué hacer si algo falla. Empieza por ahí.
Vigila la disponibilidad de billetes (trenes y vuelos) y **te avisa por Telegram
/callar./pausa, /seguir, /apagar).Uso personal. No abuses de la frecuencia: sondear demasiado rápido puede hacer que un operador te limite o bloquee la IP. 30 s es un buen equilibrio.
| Operador | Estado | Cómo funciona |
|---|---|---|
| Renfe | ✅ Probado | Backend de venta (protocolo DWR). AVE, Alvia, MD, Avlo… con disponibilidad real. |
| Ouigo España | ✅ Probado | API de su web (token + journeysearch). |
| Iryo (ILSA) | 🧪 Experimental | Sin backend público conocido. Adaptador preparado, pendiente de implementar (ver más abajo). |
| Ryanair | ✅ Probado | API de disponibilidad real de su web. Precio por pasajero, plazas restantes y enlace directo al vuelo. |
| Wizz Air | ✅ Probado | API de su web (be.wizzair.com). Necesita el token de verificación que entrega la propia sesión. |
| Vuelos (Amadeus) | ⚠️ Sin usar | Requiere API key. No sirve para Ryanair ni Wizz: las low cost no publican inventario en Amadeus. Se mantiene por si hace falta una aerolínea tradicional. |
cd ~/Desktop/BotViajes
python3 -m venv venv
./venv/bin/pip install -r requirements.txt
Configura tus secretos:
cp .env.example .env # pega tu token y chat_id de Telegram
cp config.example.yaml config.yaml # define qué rutas vigilar
/newbot → te da el token..env.Comprueba que llega:
./venv/bin/python run.py --test-telegram
El bot puede avisar en un grupo (y a la vez en tu chat privado):
@usuario → añádelo../venv/bin/python run.py --chat-ids
Los grupos tienen id negativo (p. ej. -1001234567890).
Si sale 409 Conflict, es que el bucle de Actions (o un
bot.py) ya está leyendo los mensajes: párralo un momento, o añade @RawDataBot al grupo y mira elchat.idque responde.
telegram_chat_id: "TU_ID,-1001234567890" en config.yamlTELEGRAM_CHAT_ID con el mismo formato.Notas:
TELEGRAM_CHAT_ID (es la lista de chats autorizados). En grupos, Telegram
activa el modo privacidad: el bot solo ve los mensajes que empiezan por /, así
que usa /lista o /lista@TuBot — ambos funcionan./vigilar desde el grupo avisa en ese grupo.
Las de config.yaml/watches.yaml avisan a todos los destinos configurados.watches.yaml no guarda chats.Alta gratis en https://developers.amadeus.com → crea una app → copia
API Key y Secret en .env (AMADEUS_API_KEY, AMADEUS_API_SECRET).
El entorno test es gratis pero con datos limitados; para tiempo real fino
cambia AMADEUS_ENV=production (requiere activar la app en producción).
run.py)Edita config.yaml con tus rutas y lanza:
./venv/bin/python run.py # vigilancia continua
./venv/bin/python run.py --once # una comprobación y muestra el estado
bot.py)Arranca el bot y gestiona las vigilancias chateando:
./venv/bin/python bot.py
Comandos:
/vigilar <proveedores>; <origen>; <destino>; <fecha>; [hora]; [precio_max]
/lista ver rutas vigiladas
/estado ¿vigilando o en pausa?
/borrar <id> quitar una ruta
/callar callar los avisos que están sonando (sigue vigilando)
/pausa dejar de vigilar y de avisar, sin apagarse
/seguir volver a vigilar
/apagar si apagarse del todo
/ayuda
Hay dos niveles, porque no son lo mismo:
| Comando | Qué hace | Cómo se deshace |
|---|---|---|
/callar | Calla el aviso que está sonando ahora. Sigue vigilando. | Solo, al cambiar el estado del tren |
/pausa | Deja de consultar a los operadores y de avisar. El bot sigue escuchando. | /seguir, desde Telegram |
/apagar si | Termina el proceso y desactiva el workflow para que el cron no lo relance. | Solo desde el ordenador (ver abajo) |
/stop es sinónimo de /pausa (es lo que la gente espera que haga).
La pausa se guarda en watches.yaml, así que sobrevive al relevo del job: si
pausas y 5 h después entra un job nuevo, arranca en pausa. Ojo: en pausa el job
sigue vivo para poder oír /seguir, o sea que sigue gastando minutos de Actions.
Si quieres que no gaste nada, usa /apagar si.
Para volver a encenderlo tras /apagar:
gh workflow enable vigilar.yml
gh workflow run vigilar.yml # sin esto esperarías al cron (≤5 min)
Y el equivalente manual del apagado, desde el ordenador:
gh workflow disable vigilar.yml # 1º, o el cron lo relanza en 5 min
gh run cancel $(gh run list --workflow=vigilar.yml --status=in_progress --json databaseId -q '.[0].databaseId')
Ejemplos (los campos se separan con ; porque los nombres llevan espacios):
/vigilar renfe; Alicante; Albacete; 15/03/2027; 16:55
/vigilar trenes; Madrid; Valencia; 20/03/2027; ; 30
/vigilar amadeus; MAD; BCN; 25/03/2027
trenes = renfe + ouigo + iryo. vuelos = ryanair + wizz + vueling + transavia + tuifly + mercado. Hora vacía = cualquier salida.
En vuelos hay un campo más al final, el número de pasajeros, y conviene ponerlo: en las low cost el precio por persona sube si la tarifa barata ya no tiene asientos para todo el grupo, así que buscar para 1 y viajar 2 da un precio que no existe.
/vigilar vuelos; ALC; BTS; 09/10/2026; 09:35; 60; 2
Las vigilancias de vuelo se sondean solas cada 15 minutos, no cada 30 segundos: Ryanair y Wizz cortan con 429/503 si se les insiste. Además de avisar cuando el precio baja del tope, el bot avisa de cualquier bajada de 3 € o más.
Los dos modos comparten la misma watchlist (
watches.json) y puedes usarlos a la vez.
cd ~/Desktop/BotViajes
nohup ./venv/bin/python bot.py >> botviajes.log 2>&1 &
tail -f botviajes.log # ver actividad
pkill -f bot.py # pararlo
El repo trae un workflow (.github/workflows/vigilar.yml) que vigila cada 60 s
en los servidores de GitHub, gratis y sin tarjeta. Cada ejecución es un job largo
que sondea en bucle ~5h33m; un cron de respaldo cada 5 min + la regla de
concurrencia relevan al siguiente job casi sin huecos.
TELEGRAM_BOT_TOKEN y TELEGRAM_CHAT_ID.watches.yaml (versionado, sin secretos). Edítalo
en github.com (✏️ → Commit) o en local + git push.watches.yaml al
arrancar, así que un cambio no surte efecto hasta el siguiente relevo (hasta
~5h). Para aplicarlo ya: Actions → run en curso → Cancel; el siguiente
arranca en ≤5 min con la watchlist nueva.LOOP_INTERVAL a "30" en el workflow para sondear cada 30 s.Límites honestos: es un uso agresivo de Actions (job casi 24/7, zona gris de sus términos); GitHub desactiva los cron tras 60 días sin actividad en el repo (haz un push de vez en cuando) y podría limitarlo si detecta abuso. Sin bot interactivo aquí (rutas por archivo).
Guía completa paso a paso: DEPLOY_ORACLE.md
(VM gratis para siempre + servicio systemd que arranca solo). Los avisos de
Mac se desactivan en servidor (MAC_ALERTS=0); el canal es Telegram.
Hay montado un caso concreto: una persona, ida y vuelta desde Alicante, solo vuelo directo. Las reglas completas, los avisos que manda y las trampas de cada aerolínea están en FUNCIONAMIENTO.md.
Corre solo en GitHub Actions: no hace falta tener el ordenador encendido. El bot commitea los precios al repo y, como Vercel está conectado a él, ese mismo commit republica el panel. No hay ningún token de Vercel en el proyecto.
rutas.json — los itinerarios: tramos de avión, saltos en tren o bus y el día a día.watches.yaml — qué vuelos se vigilan (esto es lo que lee la nube).actualizar_web.py — genera web/datos.json reaprovechando los precios que
ya consultó el bot, así la web y Telegram dicen exactamente lo mismo.publicar.py — sube los datos al repo, que es lo que dispara el despliegue.monitor.py — el mismo bucle para ejecutarlo en el Mac. Normalmente
parado: tenerlo a la vez que la nube duplicaría avisos y consultas.probar_avisos.py — las pruebas. Ocho casos, todos deben salir en verde.research/ — cómo se llegó a esas combinaciones: barrido de las 91 rutas de
Ryanair y de los mercados de Wizz desde Alicante, horarios reales, conexiones
por tierra contrastadas con horarios de verdad y el cruce con Google Flights../venv/bin/python run.py --once # una pasada y enseña el estado
./venv/bin/python probar_avisos.py # las pruebas
./venv/bin/python actualizar_web.py # regenerar los datos de la web
./venv/bin/python publicar.py # subirlos (Vercel despliega solo)
Panel con las combinaciones, el desglose de cada tramo con su duración y rango de
precios, el día a día y los botones de compra:
https://viaje-octubre.vercel.app (proyecto viaje-octubre, directorio raíz
web, conectado a este repositorio).
Ryanair y Wizz cotizan en la moneda del país de salida: un Pardubice→Alicante
llega en coronas checas y un Budapest→Alicante en forintos. botviajes/fx.py lo
pasa a euros con el cambio oficial diario del BCE, para poder comparar con el tope.
En Renfe un tren puede estar completo=false y aun así no poder comprarse: solo
queda la plaza reservada a movilidad reducida. Eso es lo que la web muestra como
Agotado / "tren completo, sin plazas disponibles".
El dato fiable no es el soloPlazaH del nivel del tren (Renfe solo lo rellena
a veces), sino el flag soloPlazasH de cada tarifa dentro de
tarifasDisponibles. La regla que usa providers/renfe.py: hay plaza si queda
al menos una tarifa con soloPlazasH=false; si todas son de plaza H, agotado.
El precio que se anuncia es el de la tarifa más barata comprable, no
tarifaMinima (que puede ser justo la de la plaza H).
Cuidado con dos campos que no sirven para esto: plazaH por tarifa aparece a
true en trenes con sitio de sobra, y plazaHDisponible/operativo no
distinguen. El aviso salta cuando se libera una plaza normal.
En Ouigo/Amadeus, disponible = el viaje aparece con precio.
botviajes/
models.py # Offer (una oferta de viaje)
notifier.py # avisos: Telegram + Mac (sonido/voz/notificación/abre web)
engine.py # watchlist, sondeo, avisos repetidos, /stop, persistencia
providers/
base.py # interfaz Provider + resolución de estaciones
renfe.py # ✅
ouigo.py # ✅
iryo.py # 🧪 stub
amadeus.py # ✈️ vuelos
data/ # tablas de estaciones (Renfe, Ouigo)
run.py # modo config
bot.py # modo bot interactivo
providers/iryo.py y rellena search() para llamar a ese endpoint y
devolver una lista de Offer (con available=True/False).providers/__init__.py.Licencia MIT. Uso personal y responsable.