mirror of
https://github.com/NomaDamas/k-skill.git
synced 2026-06-24 02:04:11 +00:00
Add Korean bus booking skills
This commit is contained in:
parent
91eeaf607a
commit
37cbcdb6dd
9 changed files with 723 additions and 0 deletions
|
|
@ -22,6 +22,8 @@ Claude Code, Codex, OpenCode, OpenClaw/ClawHub 등 각종 코딩 에이전트
|
|||
| --- | --- | --- | --- | --- |
|
||||
| SRT 예매 | `srt-booking` | SRT 열차 조회, 예약, 예약 확인, 취소 | 필요 | [SRT 예매 가이드](docs/features/srt-booking.md) |
|
||||
| KTX 예매 | `ktx-booking` | KTX/Korail 열차 조회, 예약, 예약 확인, 취소 | 필요 | [KTX 예매 가이드](docs/features/ktx-booking.md) |
|
||||
| 고속버스 예매 | `express-bus-booking` | KOBUS 고속버스 배차·좌석·요금 조회와 결제 직전 handoff | 불필요(결제 수동) | [고속버스 예매 가이드](docs/features/express-bus-booking.md) |
|
||||
| 시외버스 예매 | `intercity-bus-booking` | 티머니 시외버스 배차·좌석·요금 조회와 결제 직전 handoff | 불필요(결제 수동) | [시외버스 예매 가이드](docs/features/intercity-bus-booking.md) |
|
||||
| 자연휴양림 빈 객실 조회 | `foresttrip-vacancy` | 공식 숲나들e 자연휴양림 예약 가능 객실 조회 자동화 (예약/결제 제외) | 필요 | [자연휴양림 빈 객실 조회 가이드](docs/features/foresttrip-vacancy.md) |
|
||||
| 카카오톡 Mac CLI | `kakaotalk-mac` | macOS에서 카카오톡 대화 조회, 검색, 메시지 전송 | 불필요 | [카카오톡 Mac CLI 가이드](docs/features/kakaotalk-mac.md) |
|
||||
| 서울 지하철 도착정보 조회 | `seoul-subway-arrival` | 서울 지하철 역 기준 실시간 도착 예정 열차 확인 | 불필요 | [서울 지하철 도착정보 가이드](docs/features/seoul-subway-arrival.md) |
|
||||
|
|
@ -119,6 +121,8 @@ Claude Code, Codex, OpenCode, OpenClaw/ClawHub 등 각종 코딩 에이전트
|
|||
|
||||
- [SRT 예매](docs/features/srt-booking.md)
|
||||
- [KTX 예매](docs/features/ktx-booking.md)
|
||||
- [고속버스 예매](docs/features/express-bus-booking.md)
|
||||
- [시외버스 예매](docs/features/intercity-bus-booking.md)
|
||||
- [자연휴양림 빈 객실 조회](docs/features/foresttrip-vacancy.md)
|
||||
- [카카오톡 Mac CLI](docs/features/kakaotalk-mac.md)
|
||||
- [서울 지하철 도착정보 조회](docs/features/seoul-subway-arrival.md)
|
||||
|
|
|
|||
40
docs/features/express-bus-booking.md
Normal file
40
docs/features/express-bus-booking.md
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# 고속버스 예매 가이드
|
||||
|
||||
## 이 기능으로 할 수 있는 일
|
||||
|
||||
- KOBUS 고속버스 터미널/노선 후보 확인
|
||||
- 배차 시간표, 버스 등급, 잔여석, 요금 확인
|
||||
- 좌석 선택 단계 진입 가능 여부 확인
|
||||
- 필요한 경우 임시 좌석 선점 후 공식 결제정보 입력 페이지로 handoff
|
||||
- 진행하지 않을 때 임시 선점 해제
|
||||
|
||||
## 먼저 필요한 것
|
||||
|
||||
- 별도 사용자 계정/비밀번호는 기본 조회·좌석 단계에서 필요하지 않음
|
||||
- 결제는 공식 KOBUS 페이지에서 사용자가 직접 진행
|
||||
- 브라우저 자동화보다 `https://www.kobus.co.kr` 공식 HTTP 흐름을 우선 사용
|
||||
|
||||
## 입력값
|
||||
|
||||
- 출발 터미널
|
||||
- 도착 터미널
|
||||
- 날짜: `YYYYMMDD`
|
||||
- 희망 시간대
|
||||
- 인원 수와 좌석 선호
|
||||
|
||||
## 기본 흐름
|
||||
|
||||
1. 쿠키 jar를 만들고 KOBUS 메인/예매 페이지를 열어 세션을 시작한다.
|
||||
2. `POST /mrs/readRotLinInf.ajax` 로 터미널/노선 코드를 확인한다.
|
||||
3. `POST /mrs/alcnSrch.do` 로 배차를 조회한다.
|
||||
4. 결과 HTML의 `fnSatsChc(...)` 인자를 파싱해 후보를 정리한다.
|
||||
5. 선택 후보는 `POST /mrs/satschc.do` 로 좌석/요금 단계 진입을 확인한다.
|
||||
6. 사용자가 원하면 `POST /mrs/setPcpy.ajax` 로 임시 선점 후 공식 결제정보 입력 페이지 링크를 제공한다.
|
||||
7. 사용자가 진행하지 않으면 `POST /mrs/cancPcpy.ajax` 로 선점을 해제한다.
|
||||
|
||||
## 주의할 점
|
||||
|
||||
- 결제 자동화는 포함하지 않는다. 공식 페이지의 결제 직전 단계까지 보조하는 assisted checkout 흐름이다.
|
||||
- KOBUS 모바일 페이지는 좁은 화면에서 `/mblIdx.do` 로 리다이렉트할 수 있어 helper 링크 caveat를 확인한다.
|
||||
- KOBUS 터미널 코드는 티머니 시외버스 코드와 다르므로 혼용하지 않는다.
|
||||
- stateless POST보다 쿠키와 referer를 유지하는 흐름이 안정적이다.
|
||||
38
docs/features/intercity-bus-booking.md
Normal file
38
docs/features/intercity-bus-booking.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# 시외버스 예매 가이드
|
||||
|
||||
## 이 기능으로 할 수 있는 일
|
||||
|
||||
- 티머니 시외버스 터미널/노선 후보 확인
|
||||
- 배차 시간표, 운수사, 잔여석, 요금 확인
|
||||
- 좌석/요금 단계 진입 가능 여부 확인
|
||||
- 공식 카드정보 입력 페이지로 handoff
|
||||
|
||||
## 먼저 필요한 것
|
||||
|
||||
- 별도 사용자 계정/비밀번호는 기본 조회·좌석 단계에서 필요하지 않음
|
||||
- 결제는 공식 티머니 시외버스 페이지에서 사용자가 직접 진행
|
||||
- 브라우저 자동화보다 `https://intercitybus.tmoney.co.kr` 공식 HTTP 흐름을 우선 사용
|
||||
|
||||
## 입력값
|
||||
|
||||
- 출발 터미널
|
||||
- 도착 터미널
|
||||
- 날짜: `YYYYMMDD`
|
||||
- 희망 시간대
|
||||
- 인원 수와 좌석 선호
|
||||
|
||||
## 기본 흐름
|
||||
|
||||
1. 쿠키 jar를 만들고 티머니 시외버스 페이지를 열어 세션을 시작한다.
|
||||
2. `POST /otck/readAlcnList.do` 로 배차를 조회한다.
|
||||
3. 결과의 `readSasFeeInf(...)` 인자를 파싱해 후보를 정리한다.
|
||||
4. 선택 후보는 `POST /otck/readSatsFee.do` 로 좌석/요금 단계 진입을 확인한다.
|
||||
5. 사용자가 원하면 `POST /otck/readPcpySats.do` 로 공식 카드정보 입력 페이지에 진입하도록 handoff한다.
|
||||
6. 뒤로가기/취소성 이동으로 좌석 선택 단계에 복귀해 임시 선점을 해제할 수 있는지 확인한다.
|
||||
|
||||
## 주의할 점
|
||||
|
||||
- 결제 자동화는 포함하지 않는다. 공식 페이지의 결제 직전 단계까지 보조하는 assisted checkout 흐름이다.
|
||||
- 티머니 시외버스 터미널 코드는 KOBUS 고속버스 코드와 다르므로 혼용하지 않는다.
|
||||
- 일부 표면은 `txbus` 계열 URL과 연결될 수 있지만, 검증된 기본 URL은 `intercitybus.tmoney.co.kr` 이다.
|
||||
- stateless POST보다 쿠키와 referer를 유지하는 흐름이 안정적이다.
|
||||
|
|
@ -47,6 +47,8 @@ npx --yes skills add <owner/repo> \
|
|||
--skill hwp \
|
||||
--skill rhwp-edit \
|
||||
--skill rhwp-advanced \
|
||||
--skill express-bus-booking \
|
||||
--skill intercity-bus-booking \
|
||||
--skill foresttrip-vacancy \
|
||||
--skill kbo-results \
|
||||
--skill kbl-results \
|
||||
|
|
@ -104,6 +106,8 @@ npx --yes skills add <owner/repo> \
|
|||
--skill k-skill-setup \
|
||||
--skill srt-booking \
|
||||
--skill ktx-booking \
|
||||
--skill express-bus-booking \
|
||||
--skill intercity-bus-booking \
|
||||
--skill foresttrip-vacancy \
|
||||
--skill korean-law-search \
|
||||
--skill real-estate-search \
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ bash scripts/check-setup.sh
|
|||
|
||||
- [SRT 예매 가이드](features/srt-booking.md)
|
||||
- [KTX 예매 가이드](features/ktx-booking.md)
|
||||
- [고속버스 예매 가이드](features/express-bus-booking.md)
|
||||
- [시외버스 예매 가이드](features/intercity-bus-booking.md)
|
||||
- [자연휴양림 빈 객실 조회 가이드](features/foresttrip-vacancy.md)
|
||||
- [서울 지하철 도착정보 가이드](features/seoul-subway-arrival.md)
|
||||
- [한국 날씨 조회 가이드](features/korea-weather.md)
|
||||
|
|
|
|||
201
express-bus-booking/SKILL.md
Normal file
201
express-bus-booking/SKILL.md
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
---
|
||||
name: express-bus-booking
|
||||
description: Search and assist Korean 고속버스/KOBUS bookings using official HTTP/API-first flows; use for 고속버스 예매, 시간표, 좌석 조회, 임시 선점, and official checkout-entry handoff.
|
||||
license: MIT
|
||||
metadata:
|
||||
category: travel
|
||||
locale: ko-KR
|
||||
phase: v1
|
||||
---
|
||||
|
||||
# Express Bus Booking (KOBUS)
|
||||
|
||||
## Overview
|
||||
|
||||
Use this skill for Korean 고속버스 / KOBUS timetable lookup and reservation assistance. The preferred workflow is HTTP/API-first: resolve routes, query timetables, inspect remaining seats and fares, and only use browser automation when endpoint discovery or an official web-only step blocks progress.
|
||||
|
||||
This skill is intentionally separate from 시외버스. KOBUS terminal codes, route structures, and checkout pages differ from Tmoney 시외버스. Use `intercity-bus-booking` for 시외버스/Tmoney flows.
|
||||
|
||||
## When to Use
|
||||
|
||||
- The user asks for `고속버스 예매`, `고속버스 시간표`, `고속버스 예약`, `프리미엄 고속버스`, or `우등 고속버스`.
|
||||
- The route is clearly a KOBUS 고속버스 route or the user names KOBUS/코버스/고속버스통합예매.
|
||||
- The user wants assisted reservation up to seat selection, temporary hold, or a payment-entry link.
|
||||
|
||||
Do **not** use this for:
|
||||
|
||||
- 시외버스/Tmoney routes — use `intercity-bus-booking`.
|
||||
- Final card submission or payment without explicit, narrowly scoped confirmation.
|
||||
- Blind browser automation before trying the official HTTP flow.
|
||||
|
||||
## Core Principles
|
||||
|
||||
- Use official KOBUS surfaces: `https://www.kobus.co.kr`.
|
||||
- Keep a cookie jar and reuse referers. Stateless one-off POSTs are less reliable.
|
||||
- Prefer desktop User-Agent and HTTP/1.1 during probing if the server behaves differently under HTTP/2.
|
||||
- Default scope is assisted manual checkout: lookup, candidate presentation, seat-stage readiness, temporary seat hold, and official payment-entry page handoff.
|
||||
- Do not submit card fields, agree to terms, or complete payment unless the user explicitly confirms that exact action.
|
||||
|
||||
## Known HTTP Flow
|
||||
|
||||
See `references/kobus-http-flow.md` for session-proven endpoint details and parameter examples.
|
||||
|
||||
### 1. Start a Session
|
||||
|
||||
Fetch either the main page or route/search page with cookies enabled:
|
||||
|
||||
```text
|
||||
GET https://www.kobus.co.kr/main.do
|
||||
GET https://www.kobus.co.kr/mrs/rotinf.do
|
||||
```
|
||||
|
||||
Use a realistic desktop User-Agent and a cookie jar.
|
||||
|
||||
### 2. Resolve Route / Terminal Candidates
|
||||
|
||||
```text
|
||||
POST /mrs/readRotLinInf.ajax
|
||||
```
|
||||
|
||||
The response is JSON and can include `rotInfList`, `tfrInfList`, `len`, and `codeYn`. Prefer code-confirmed routes over display-name matching because terminal names are not always unique.
|
||||
|
||||
### 3. Query Timetable
|
||||
|
||||
```text
|
||||
POST /mrs/alcnSrch.do
|
||||
```
|
||||
|
||||
Typical fields include:
|
||||
|
||||
```text
|
||||
deprCd=010
|
||||
arvlCd=700
|
||||
pathDvs=sngl
|
||||
pathStep=1
|
||||
deprDtm=YYYYMMDD
|
||||
busClsCd=0
|
||||
rtrpChc=1
|
||||
timeLinkMin=00
|
||||
timeLinkMax=23
|
||||
```
|
||||
|
||||
Parse the returned HTML for schedule rows/cards and `fnSatsChc(...)` onclick arguments. Respect `mrsPsbYn=N` or any equivalent booking-disabled marker.
|
||||
|
||||
### 4. Enter Seat / Fare Stage
|
||||
|
||||
```text
|
||||
POST /mrs/satschc.do
|
||||
```
|
||||
|
||||
Send the original search form fields plus selected values from `fnSatsChc(...)`, commonly including:
|
||||
|
||||
```text
|
||||
deprTime
|
||||
alcnDeprTime
|
||||
alcnDeprTrmlNo
|
||||
alcnArvlTrmlNo
|
||||
indVBusClsCd
|
||||
cacmCd
|
||||
dcDvsCd
|
||||
prvtBbizEmpAcmtRt
|
||||
chldSftySatsYn
|
||||
dsprSatsYn
|
||||
```
|
||||
|
||||
The response should include `form#satsChcFrm` and hidden fare/seat values such as `adltFee`, `rmnSatsNum`, `totSatsNum`, and terminal/time fields.
|
||||
|
||||
### 5. Temporary Seat Hold
|
||||
|
||||
```text
|
||||
POST /mrs/setPcpy.ajax
|
||||
```
|
||||
|
||||
Submit the `satsChcFrm` hidden fields plus selected seat/count fields. A successful response includes:
|
||||
|
||||
```text
|
||||
MSG_CD=S0000
|
||||
pcpyNoAll
|
||||
satsNoAll
|
||||
ESTM_AMT
|
||||
DC_AMT
|
||||
TISSU_AMT
|
||||
```
|
||||
|
||||
Treat the hold as short-lived. If testing, if the user does not proceed, or if a new seat is chosen, release it explicitly.
|
||||
|
||||
### 6. Release Temporary Hold
|
||||
|
||||
```text
|
||||
POST /mrs/cancPcpy.ajax
|
||||
```
|
||||
|
||||
Use the same relevant form fields plus the returned `pcpyNoAll` and `satsNoAll`. A successful response returns `MSG_CD=S0000`.
|
||||
|
||||
## Checkout-Entry Link Helper
|
||||
|
||||
A plain official checkout URL is not enough because KOBUS expects a POST body containing the selected schedule, seat, fare, and hold identifiers. The practical user-facing pattern is:
|
||||
|
||||
1. Create the temporary hold server-side via `setPcpy.ajax`.
|
||||
2. Generate a short helper page that auto-submits a POST form to the official KOBUS checkout endpoint.
|
||||
3. Send the helper link to the user.
|
||||
4. The user completes card/payment fields manually on the official KOBUS page.
|
||||
|
||||
Desktop action:
|
||||
|
||||
```text
|
||||
https://www.kobus.co.kr/mrs/stplcfmpym.do
|
||||
```
|
||||
|
||||
Mobile-friendly action:
|
||||
|
||||
```text
|
||||
https://www.kobus.co.kr/mrs/stplcfmpym.do?keep=/mrs/pay
|
||||
```
|
||||
|
||||
The POST body should include the original seat form fields plus returned hold values such as `pcpyNoAll`, `satsNoAll`, `estmAmt`, `dcAmt`, `tissuAmt`, and `nonMbrsYn=Y` when using a non-member checkout flow.
|
||||
|
||||
## Mobile Redirect Caveat
|
||||
|
||||
KOBUS common JavaScript can redirect narrow/mobile screens to `/mblIdx.do` unless `location.href` contains a mobile-allowed path fragment such as `/mrs/pay`. In testing, posting to:
|
||||
|
||||
```text
|
||||
/mrs/stplcfmpym.do?keep=/mrs/pay
|
||||
```
|
||||
|
||||
preserved the same checkout POST body while making the final browser URL contain `/mrs/pay`, avoiding the client-side mobile-main redirect condition. Use this variant for Discord/mobile users, but still verify with the user because in-app browsers may add their own quirks.
|
||||
|
||||
If mobile still lands on the homepage, recommend opening the helper link in a normal external browser or desktop browser. Do not keep retrying holds indefinitely; cancel stale holds.
|
||||
|
||||
## Suggested Output Format
|
||||
|
||||
Keep candidate lists concise and actionable:
|
||||
|
||||
```text
|
||||
고속버스 서울경부 → 부산 / 2026-05-09
|
||||
1. 00:30 심야우등 / 천일고속 / 잔여 10석 / 성인 47,600원
|
||||
2. 13:50 우등 / ...
|
||||
```
|
||||
|
||||
When a hold/checkout helper is created, state that the next step opens the official KOBUS payment page and that payment remains manual.
|
||||
|
||||
For Discord/mobile, provide links as normal text links, not fenced code blocks, so the user can tap them directly.
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
1. **Mixing KOBUS and Tmoney codes.** KOBUS terminal codes are not Tmoney 시외버스 terminal codes.
|
||||
2. **Assuming a cart exists.** KOBUS does not expose a shopping-cart style hold list in the tested web flow. The realistic UX is temporary seat hold plus checkout-entry handoff.
|
||||
3. **Ignoring hold cleanup.** Always cancel test holds or abandoned holds with `cancPcpy.ajax`.
|
||||
4. **Treating lookup success as payment permission.** Lookup, seat-stage entry, and temporary hold are not authorization to submit payment.
|
||||
5. **Mobile homepage redirects.** Use the `?keep=/mrs/pay` helper action for mobile; otherwise KOBUS JS may send the user to `/mblIdx.do`.
|
||||
6. **Browser automation too early.** Try direct HTTP first. Use browser tooling only to discover changed endpoints or verify final user-facing behavior.
|
||||
|
||||
## Verification Checklist
|
||||
|
||||
- [ ] Route/terminal codes were resolved from KOBUS, not guessed.
|
||||
- [ ] Timetable was queried with cookies and a realistic User-Agent.
|
||||
- [ ] Candidate output includes date, departure/arrival terminals, time, class/operator when available, fare, and remaining seats.
|
||||
- [ ] Seat-stage response contains expected hidden fields before attempting a hold.
|
||||
- [ ] Temporary hold success was confirmed with `MSG_CD=S0000` before sending a checkout helper link.
|
||||
- [ ] Stale/test holds were cancelled with `cancPcpy.ajax`.
|
||||
- [ ] Payment/card fields were left for the user unless they explicitly confirmed otherwise.
|
||||
- [ ] Mobile helper links use the `/mrs/pay` marker variant when sent to mobile-heavy platforms.
|
||||
157
express-bus-booking/references/kobus-http-flow.md
Normal file
157
express-bus-booking/references/kobus-http-flow.md
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
# KOBUS HTTP/API Probe Notes
|
||||
|
||||
Session-proven on 2026-05-08. Goal: avoid browser automation where possible.
|
||||
|
||||
## Base
|
||||
|
||||
```text
|
||||
https://www.kobus.co.kr
|
||||
```
|
||||
|
||||
Use a desktop User-Agent, HTTP/1.1 if needed, a cookie jar, and referers.
|
||||
|
||||
## Tested Flow
|
||||
|
||||
### Route / Terminal Candidates
|
||||
|
||||
```text
|
||||
POST /mrs/readRotLinInf.ajax
|
||||
```
|
||||
|
||||
Observed JSON keys:
|
||||
|
||||
```text
|
||||
tfrLen
|
||||
tfrInfList
|
||||
len
|
||||
codeYn
|
||||
rotInfList
|
||||
```
|
||||
|
||||
One probe returned about 1,208 route records in `rotInfList`.
|
||||
|
||||
### Timetable
|
||||
|
||||
```text
|
||||
POST /mrs/alcnSrch.do
|
||||
```
|
||||
|
||||
Example tested route/date:
|
||||
|
||||
```text
|
||||
서울경부(010) -> 부산(700), 2026-05-09
|
||||
```
|
||||
|
||||
Observed result:
|
||||
|
||||
```text
|
||||
42 schedule links/cards
|
||||
25 selectable seat snippets
|
||||
first selectable: 00:30 / 천일고속 / 심야우등 / 10 seats
|
||||
```
|
||||
|
||||
Typical POST fields:
|
||||
|
||||
```text
|
||||
deprCd=010
|
||||
arvlCd=700
|
||||
pathDvs=sngl
|
||||
pathStep=1
|
||||
deprDtm=YYYYMMDD
|
||||
busClsCd=0
|
||||
rtrpChc=1
|
||||
timeLinkMin=00
|
||||
timeLinkMax=23
|
||||
```
|
||||
|
||||
Parse `fnSatsChc(...)` onclick values for the next step. Example:
|
||||
|
||||
```text
|
||||
fnSatsChc('20260509','003000','003000','010','700','3','07','0','Y','N','010','700','N','N','N','N')
|
||||
```
|
||||
|
||||
### Seat / Fare Stage
|
||||
|
||||
```text
|
||||
POST /mrs/satschc.do
|
||||
```
|
||||
|
||||
Send the original `alcnSrchFrm` hidden fields plus selected values from `fnSatsChc(...)`, including values such as:
|
||||
|
||||
```text
|
||||
deprTime=003000
|
||||
alcnDeprTime=003000
|
||||
alcnDeprTrmlNo=010
|
||||
alcnArvlTrmlNo=700
|
||||
indVBusClsCd=3
|
||||
cacmCd=07
|
||||
dcDvsCd=0
|
||||
prvtBbizEmpAcmtRt=N
|
||||
chldSftySatsYn=N
|
||||
dsprSatsYn=N
|
||||
```
|
||||
|
||||
Observed response contained `form#satsChcFrm` and hidden values:
|
||||
|
||||
```json
|
||||
{
|
||||
"deprTime": "003000",
|
||||
"alcnDeprTrmlNo": "010",
|
||||
"alcnArvlTrmlNo": "700",
|
||||
"adltFee": "47600",
|
||||
"rmnSatsNum": "10",
|
||||
"totSatsNum": "28"
|
||||
}
|
||||
```
|
||||
|
||||
### Temporary Hold
|
||||
|
||||
```text
|
||||
POST /mrs/setPcpy.ajax
|
||||
```
|
||||
|
||||
Observed successful response markers:
|
||||
|
||||
```text
|
||||
MSG_CD=S0000
|
||||
pcpyNoAll
|
||||
satsNoAll
|
||||
ESTM_AMT
|
||||
DC_AMT
|
||||
TISSU_AMT
|
||||
```
|
||||
|
||||
### Hold Cancellation
|
||||
|
||||
```text
|
||||
POST /mrs/cancPcpy.ajax
|
||||
```
|
||||
|
||||
Observed success marker:
|
||||
|
||||
```text
|
||||
MSG_CD=S0000
|
||||
```
|
||||
|
||||
### Checkout Entry
|
||||
|
||||
```text
|
||||
POST /mrs/stplcfmpym.do
|
||||
```
|
||||
|
||||
The POST body must include the selected schedule/seat form values plus temporary hold identifiers and fare amounts. A helper page can auto-submit this form to the official KOBUS endpoint.
|
||||
|
||||
For mobile browsers, use:
|
||||
|
||||
```text
|
||||
POST /mrs/stplcfmpym.do?keep=/mrs/pay
|
||||
```
|
||||
|
||||
This preserves the POST body while placing `/mrs/pay` in `location.href`, which avoids a KOBUS client-side mobile redirect condition observed in the common JavaScript.
|
||||
|
||||
## Interpretation
|
||||
|
||||
- Login was not required for route lookup, timetable lookup, seat-selection-page entry, temporary hold, or checkout-entry page display in the tested flow.
|
||||
- Page HTML can include login or `grecaptchaToken` forms, but these did not block the tested lookup/seat-stage path.
|
||||
- Final payment should remain a manual, explicitly confirmed stage.
|
||||
- KOBUS mobile behavior is less stable than desktop because common JavaScript can redirect narrow screens to the mobile main page.
|
||||
160
intercity-bus-booking/SKILL.md
Normal file
160
intercity-bus-booking/SKILL.md
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
---
|
||||
name: intercity-bus-booking
|
||||
description: Search and assist Korean 시외버스/Tmoney bookings using official HTTP/API-first flows; use for 시외버스 예매, 시간표, 좌석/요금 조회, and official checkout-entry handoff.
|
||||
license: MIT
|
||||
metadata:
|
||||
category: travel
|
||||
locale: ko-KR
|
||||
phase: v1
|
||||
---
|
||||
|
||||
# Intercity Bus Booking (Tmoney 시외버스)
|
||||
|
||||
## Overview
|
||||
|
||||
Use this skill for Korean 시외버스 timetable lookup and reservation assistance via the official Tmoney intercity bus site. Prefer HTTP/API-first flows for route lookup, timetable search, fare/seat-stage entry, and checkout-entry handoff.
|
||||
|
||||
Keep 시외버스 separate from 고속버스. Tmoney terminal codes and POST flows are different from KOBUS 고속버스. Use `express-bus-booking` for KOBUS routes.
|
||||
|
||||
## When to Use
|
||||
|
||||
- The user asks for `시외버스 예매`, `시외버스 시간표`, `시외버스 예약`, or a known 시외버스 route.
|
||||
- The user names 티머니/Tmoney/시외버스 통합예매.
|
||||
- The task is to present timetable candidates, check remaining seats/fares, or assist up to the official card-information page.
|
||||
|
||||
Do **not** use this for:
|
||||
|
||||
- 고속버스/KOBUS routes — use `express-bus-booking`.
|
||||
- Final card submission or payment unless the user explicitly confirms the exact action.
|
||||
- Browser automation as the first option when HTTP endpoints are available.
|
||||
|
||||
## Core Principles
|
||||
|
||||
- Use official Tmoney 시외버스 surfaces: `https://intercitybus.tmoney.co.kr`.
|
||||
- Use cookies, referers, and a normal browser User-Agent.
|
||||
- Default scope is lookup and assisted manual checkout: timetable, fare/seat stage, selected-seat temporary hold, and official card-information page handoff.
|
||||
- Do not submit card fields, final payment, or irreversible reservation steps without explicit confirmation.
|
||||
- If a test or user-abandoned hold is created, use the official cancellation/back flow when available.
|
||||
|
||||
## Known HTTP Flow
|
||||
|
||||
See `references/tmoney-intercity-http-flow.md` for session-proven endpoint details and parameter examples.
|
||||
|
||||
### 1. Start a Session
|
||||
|
||||
Fetch a landing or booking-entry page with cookies enabled:
|
||||
|
||||
```text
|
||||
GET https://intercitybus.tmoney.co.kr/
|
||||
GET https://intercitybus.tmoney.co.kr/otck/trmlInfEnty.do
|
||||
```
|
||||
|
||||
### 2. Query Timetable
|
||||
|
||||
```text
|
||||
POST /otck/readAlcnList.do
|
||||
```
|
||||
|
||||
Typical fields include:
|
||||
|
||||
```text
|
||||
depr_Trml_Cd=0511601
|
||||
arvl_Trml_Cd=2482701
|
||||
depr_Trml_Nm=동서울
|
||||
arvl_Trml_Nm=속초
|
||||
ig=1
|
||||
im=0
|
||||
ic=0
|
||||
iv=0
|
||||
depr_Dt=YYYYMMDD
|
||||
depr_Time=000000
|
||||
```
|
||||
|
||||
Parse schedule buttons/rows. The next-stage parameters are often embedded in `readSasFeeInf(...)` onclick arguments.
|
||||
|
||||
### 3. Enter Fare / Seat-Count Stage
|
||||
|
||||
```text
|
||||
POST /otck/readSatsFee.do
|
||||
```
|
||||
|
||||
Send selected values from `readSasFeeInf(...)` plus passenger counts and original search fields. The response should include `form#readPcpySats` and hidden values such as:
|
||||
|
||||
```text
|
||||
rot_Id
|
||||
alcn_Sqno
|
||||
depr_Trml_Cd
|
||||
arvl_Trml_Cd
|
||||
depr_Time
|
||||
igFee
|
||||
imFee
|
||||
icFee
|
||||
total
|
||||
```
|
||||
|
||||
### 4. Temporary Hold and Card-Information Entry
|
||||
|
||||
```text
|
||||
POST /otck/readPcpySats.do
|
||||
```
|
||||
|
||||
Submit the `readPcpySats` hidden fields plus selected seat/count fields, commonly including:
|
||||
|
||||
```text
|
||||
pcpy_Num
|
||||
sats_No
|
||||
bus_Tck_Knd_Cd
|
||||
cty_Bus_Dc_Knd_Cd
|
||||
dcrt_Dvs_Cd
|
||||
rtrp_Depr_Dt
|
||||
```
|
||||
|
||||
A successful response lands on the official `카드정보 입력` page and includes a temporary seat hold identifier such as `sats_Pcpy_Id`.
|
||||
|
||||
## Checkout-Entry Link Helper
|
||||
|
||||
A helper-served HTML page can auto-submit a POST form directly to:
|
||||
|
||||
```text
|
||||
https://intercitybus.tmoney.co.kr/otck/readPcpySats.do
|
||||
```
|
||||
|
||||
This creates the hold in the user's browser/session and opens the official Tmoney card-information page. The user should manually finish payment on the official page.
|
||||
|
||||
For Discord/mobile, provide helper links as normal text links rather than fenced code blocks so the user can tap them.
|
||||
|
||||
## Mobile and In-App Browser Notes
|
||||
|
||||
Tmoney 시외버스 is more mobile-tolerant than KOBUS in the tested flow: an iPhone Safari-style mobile User-Agent returned the official `카드정보 입력` page with `sats_Pcpy_Id` present.
|
||||
|
||||
However, in-app browser User-Agents can behave differently or fail if the same seat/hold payload is replayed. If a Discord/Android in-app test returns a generic error such as `발행을 실패하였습니다`, do not assume route lookup is broken. Recreate a fresh hold payload, retry once in an external browser, and cancel stale holds.
|
||||
|
||||
## Suggested Output Format
|
||||
|
||||
Keep candidate lists concise:
|
||||
|
||||
```text
|
||||
시외버스 동서울 → 속초 / 2026-05-09
|
||||
1. 06:05 우등 / 금강고속 / 잔여 8석 / 성인 21,300원
|
||||
2. ...
|
||||
```
|
||||
|
||||
When a checkout-entry helper is created, say that it opens the official Tmoney card-information page and that payment remains manual.
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
1. **Mixing terminal code systems.** Tmoney 시외버스 codes are not KOBUS codes.
|
||||
2. **Assuming checkout-entry equals final payment.** `readPcpySats.do` can open the card-information page, but final payment remains a separate manual step.
|
||||
3. **Replaying stale hold payloads.** A repeated POST for the same route/seat can fail or create confusing results. Generate a fresh seat-stage payload for real use.
|
||||
4. **Skipping cancellation/back flow.** Use the official cancellation/back form (`pcpyCanc=C` via `readSatsFee.do` when available) for abandoned holds.
|
||||
5. **Overusing browser automation.** Use browser only for endpoint discovery or visual verification after HTTP probing.
|
||||
|
||||
## Verification Checklist
|
||||
|
||||
- [ ] Route/terminal codes were resolved from Tmoney 시외버스, not guessed or copied from KOBUS.
|
||||
- [ ] Timetable response was parsed for schedule rows/buttons and next-stage parameters.
|
||||
- [ ] Fare/seat-stage response contains `form#readPcpySats` and expected hidden fields.
|
||||
- [ ] Checkout-entry response contains `카드정보 입력` and a hold identifier such as `sats_Pcpy_Id` before reporting success.
|
||||
- [ ] Stale/test holds were released through the official cancellation/back flow where possible.
|
||||
- [ ] Payment/card submission was left to the user unless explicitly confirmed.
|
||||
- [ ] Mobile links are provided as tappable text links on Discord/mobile platforms.
|
||||
117
intercity-bus-booking/references/tmoney-intercity-http-flow.md
Normal file
117
intercity-bus-booking/references/tmoney-intercity-http-flow.md
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
# Tmoney 시외버스 HTTP/API Probe Notes
|
||||
|
||||
Session-proven on 2026-05-08. Goal: avoid browser automation where possible.
|
||||
|
||||
## Base
|
||||
|
||||
```text
|
||||
https://intercitybus.tmoney.co.kr
|
||||
```
|
||||
|
||||
Use a normal browser User-Agent, cookie jar, and referers.
|
||||
|
||||
## Tested Flow
|
||||
|
||||
### Timetable
|
||||
|
||||
```text
|
||||
POST /otck/readAlcnList.do
|
||||
```
|
||||
|
||||
Example tested route/date:
|
||||
|
||||
```text
|
||||
동서울(0511601) -> 속초(2482701), 2026-05-09
|
||||
```
|
||||
|
||||
Observed result:
|
||||
|
||||
```text
|
||||
14 reservation buttons/schedules
|
||||
```
|
||||
|
||||
Typical POST fields:
|
||||
|
||||
```text
|
||||
depr_Trml_Cd=0511601
|
||||
arvl_Trml_Cd=2482701
|
||||
depr_Trml_Nm=동서울
|
||||
arvl_Trml_Nm=속초
|
||||
ig=1
|
||||
im=0
|
||||
ic=0
|
||||
iv=0
|
||||
depr_Dt=YYYYMMDD
|
||||
depr_Time=000000
|
||||
```
|
||||
|
||||
The next-stage values are embedded in `readSasFeeInf(...)` onclick calls. Example prefix:
|
||||
|
||||
```text
|
||||
readSasFeeInf('RT201603150047276','1','20260509','1','0511601','2482701','동서울','속초','060500','C004','IDP','금강고속','우등','1','0','0','8','28', ...)
|
||||
```
|
||||
|
||||
### Fare / Seat-Count Stage
|
||||
|
||||
```text
|
||||
POST /otck/readSatsFee.do
|
||||
```
|
||||
|
||||
Send selected values from `readSasFeeInf(...)` plus passenger counts and original search fields.
|
||||
|
||||
Observed response contained `form#readPcpySats` and hidden values:
|
||||
|
||||
```json
|
||||
{
|
||||
"rot_Id": "RT201603150047276",
|
||||
"alcn_Sqno": "1",
|
||||
"depr_Trml_Cd": "0511601",
|
||||
"arvl_Trml_Cd": "2482701",
|
||||
"depr_Time": "060500",
|
||||
"igFee": "21300",
|
||||
"imFee": "17000",
|
||||
"icFee": "10700",
|
||||
"total": "21300"
|
||||
}
|
||||
```
|
||||
|
||||
### Temporary Hold / Card-Information Entry
|
||||
|
||||
```text
|
||||
POST /otck/readPcpySats.do
|
||||
```
|
||||
|
||||
Send `readPcpySats` hidden fields plus selected seat fields:
|
||||
|
||||
```text
|
||||
pcpy_Num
|
||||
sats_No
|
||||
bus_Tck_Knd_Cd
|
||||
cty_Bus_Dc_Knd_Cd
|
||||
dcrt_Dvs_Cd
|
||||
rtrp_Depr_Dt
|
||||
```
|
||||
|
||||
Observed success markers:
|
||||
|
||||
```text
|
||||
카드정보 입력
|
||||
sats_Pcpy_Id
|
||||
```
|
||||
|
||||
### Cancellation / Back Flow
|
||||
|
||||
A POST back to `/otck/readSatsFee.do` with `pcpyCanc=C` and the hold fields returned to seat selection and appeared to release the temporary hold in testing.
|
||||
|
||||
## Mobile Notes
|
||||
|
||||
- iPhone Safari-style mobile User-Agent returned HTTP 200 with `카드정보 입력` and `sats_Pcpy_Id` present.
|
||||
- A replayed Discord/Android in-app User-Agent test returned a generic `발행을 실패하였습니다` page. Because the same seat/hold payload had already been used, treat this as a stale/replayed hold caveat rather than proof that mobile is unsupported.
|
||||
- For real use, generate a fresh hold payload, send a helper link, and ask the user to open it in an external browser if an in-app browser fails.
|
||||
|
||||
## Interpretation
|
||||
|
||||
- Login was not required for timetable lookup, fare/seat-stage entry, or card-information page entry in the tested flow.
|
||||
- CAPTCHA was not observed in the tested flow.
|
||||
- Payment/card-info submission is separate and should not be automated without explicit confirmation.
|
||||
- Terminal codes are Tmoney-specific and must not be mixed with KOBUS codes.
|
||||
Loading…
Add table
Add a link
Reference in a new issue