尚未检测到更新。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.