AydosJs/railway-bot
GitHub: AydosJs/railway-bot
基于乌兹别克斯坦铁路网站原生 API 的余票监控与自动占座工具,附带完整的未公开 API 逆向文档。
Stars: 0 | Forks: 0
# 乌兹别克斯坦铁路订票机器人 — 针对 eticket.railway.uz 的座位监控与自动占座工具
监控 **eticket.railway.uz**(O'zbekiston Temir Yo'llari)上你指定路线的火车票,并在有空座的瞬间将其锁定,同时向你的手机发送链接,让你可以躺在床上完成支付。
基于该网站原生的 JSON API 构建 — 在关键路径上**没有浏览器自动化,没有 Selenium,没有 Playwright**。一次轮询就是一个 HTTP 请求;抢座也只需一次调用。包含[**完整的 eticket.railway.uz 未公开 API 参考文档**](API.md),如果你打算基于该网站开发其他工具,这可能是本仓库最有用的部分。
   
## 问题背景
热门乌兹别克路线的火车票 — 比如塔什干(Toshkent) → 努库斯(Nukus)、塔什干 → 布哈拉(Buxoro),或者旺季时任何前往撒马尔罕(Samarqand)的车票 — 往往在放票的一小时内就售罄。不过座位会重新出现:源于退票、铁路部门释放的锁定票,或是他人锁定超时的票。它们随机出现,通常在凌晨 3 点,并且几分钟内就会再次消失。
因此,该机器人每约 8 秒进行一次轮询。当有足够的座位同时出现时,它会自动**锁定** — 就像你在网站上点击 *Davom etish* 时发出的请求一样 — 这会将座位锁定约 11 分钟,并阻止其他买家购买。然后它会通过 Telegram 向你发送消息和链接。你在手机上打开链接,输入你的 Uzcard/Humo 卡号和短信验证码,然后就可以继续睡觉了。
**该机器人绝不会自动支付。** 它只负责锁定,该操作可逆且会自动过期。支付步骤始终由真人来决定。
## 功能特性
- **座位监控** — 轮询一个或多个日期,支持按车次和车厢席别进行筛选
- **感知团队的选座算法** — 优先选择整个空余包厢,否则选择最能满足你下铺需求的最紧凑座位集群(毕竟没人想让奶奶睡上铺)
- **自动锁定** — 只需一次 API 调用,从而在速度上战胜通过点击 UI 购票的人
- **手机支付** — 从你自己的机器上提供的移动端支付页面
- **实时锁定倒计时** — 来自服务器的绝对截止时间,绝非猜测
- **一键释放** — 如果你改变主意,可立即释放座位
- **Telegram 提醒** — 涵盖启动、匹配、锁定、失败通知以及定期的“存活确认”消息
- **支持重启恢复** — 如果进程在夜间中断,它会自动恢复监控
- **后续票务处理** — 支付成功后,可查看乘客信息、座位、PDF 以及用于核验的二维码链接
## 快速开始
```
git clone https://github.com/AydosJs/railway-bot.git
cd railway-bot
npm install
```
创建 `.env.local` 文件:
```
RAILWAY_USERNAME=998XXXXXXXXX # your eticket.railway.uz phone login
RAILWAY_PASSWORD=your-password
TELEGRAM_BOT_TOKEN=... # from @BotFather
TELEGRAM_CHAT_ID=... # from @userinfobot
# PUBLIC_URL=https://your-tunnel # 仅当您将 dashboard 暴露到您的 wifi 之外时
```
然后执行:
```
npm run build
npm run overnight # caffeinate + next start, so the Mac doesn't sleep through the drop
```
打开 `http://localhost:3000`,设置你的路线、日期和乘客信息,勾选 **Auto-grab**,然后点击
**Start watching**。
乘客姓名会与你铁路账户中保存的乘客列表进行匹配,因此请先在那里添加好所有人。如果姓名不匹配,机器人会向你发送警报而不会锁定座位 — 它绝不会因为拼写错误而给陌生人订票。
## 工作原理
```
lib/railway.ts typed API client — auth, search, seat maps, hold, cancel, payment
lib/seatpick.ts which seats to take
lib/monitor.ts the poll loop and the grab
lib/paywatch.ts the payment-status WebSocket
app/dashboard.tsx control panel
app/pay/ the phone payment flow
scripts/ the capture tooling used to reverse-engineer all of it
```
三个发现让事情变得比预期简单,均已记录在 [API.md](API.md) 中:
1. **CSRF 可自行生成。** 服务器只检查 `X-XSRF-TOKEN` 是否与 `XSRF-TOKEN` cookie 匹配 — 你自己生成的 UUID 也是可以接受的。不需要浏览器会话。
2. **登录接口没有验证码。** 登录*页面*有验证码,但
`POST /api/v1/auth/login` 可以直接接收用户名和密码并返回 JWT。
3. **银行卡支付是纯 JSON 交互。** 没有托管结账页,没有 iframe,也没有重定向:
`payme/do-payment` → `payme/create-card` (卡号 + MM/YY) → `payme/verify-card` (短信验证码),
结果通过 `wss://eticket.railway.uz/ws` 推送。这就是为什么支付不必在执行锁定的机器上进行 — 本应用自己托管了卡片表单。
## 通过手机支付
服务器绑定到 `0.0.0.0`,因此局域网内的任何设备都可以访问它。Telegram 消息中包含
`http://<你的局域网IP>:3000/pay/` 的链接。点击它,你就能看到座位、价格、实时倒计时,然后依次输入卡号 → 短信验证码 → 完成。不在家?可以通过隧道(如 ngrok、Tailscale、Cloudflare)指向 3000 端口,并设置 `PUBLIC_URL`。
银行卡详细信息会直接转发到铁路支付 API,绝不接触磁盘 — 活动日志中只会显示卡号的后四位。
## API 参考
[**API.md**](API.md) 记录了从实际网站上抓取的所有接口:搜索、座位分布图、已存乘客信息、订单/锁定生命周期、锁定截止时间与取消机制、完整的 Payme 银行卡处理流程,以及状态 WebSocket 协议。每个条目都注明了其验证方式。如果你打算基于 eticket.railway.uz 开发任何内容,请从这里开始 — 它能为你省下开发此项目所花的一周时间。
## 免责声明
自动订票可能违反该网站的服务条款。编写此程序仅是为了给一个购买四张车票的家庭提供便利,并非用于倒卖或大规模应用。
- 请将轮询保持在 8 秒或更慢的速度(UI 强制设定的最低下限为 5 秒)。
- 锁定是切实有效的:它会将座位绑定到你的账户,并显示在你的订单列表中。未支付的锁定将在约 11 分钟后过期;**Release** (释放) 功能可立即解除绑定。
- Auto-grab (自动抢票) 默认是关闭的。启用它始终需要你主动点击确认。
- 不要使用此工具囤积票源。还有其他人需要那些铺位。
本项目按“原样”提供,仅供学习和个人使用。你对如何使用它负全责。
## 许可证
MIT — 详见 [LICENSE](LICENSE)。
关键词:乌兹别克斯坦铁路 API, eticket.railway.uz, O'zbekiston Temir Yo'llari, UTY, UZ
铁路火车票, 塔什干 努库斯 撒马尔罕 布哈拉 火车票 (poyezd chiptasi), 火车票机器人, 座位
余票监控, 订票提醒, Afrosiyob 订票, Payme API 集成, Uzcard Humo 支付,
逆向工程 API, Next.js TypeScript 自动化。
标签:API逆向, TypeScript, 安全插件, 抢票工具, 监控自动化, 自动化攻击, 自动化机器人