← Back to Search & Research
Search & Research by @khj809

srt

Korean SRT (Super Rapid Train) search, reservation, and booking management

New
Source Code

SRT Korean Train Service Skill

OpenClaw skill for managing Korean SRT (Super Rapid Train) reservations with search, booking, view, and cancellation capabilities.

Features

  • πŸ” Search trains between stations with real-time seat availability
  • 🎫 Make reservations with automatic rate limiting to protect your account
  • πŸ“‹ View bookings to see all active reservations
  • πŸ—‘οΈ Cancel bookings with confirmation prompts
  • πŸ€– AI-friendly JSON output for programmatic access
  • πŸ›‘οΈ Rate limiting to prevent account blocking (3s between reservations, 5s between searches)
  • ⚠️ Retry protection with maximum 10 attempts per session

Prerequisites

  1. Python 3.10+ installed
  2. SRT account with phone number and password
  3. OpenClaw installed and configured

Configuration

Set your SRT credentials as environment variables:

export SRT_PHONE="010-1234-5678"
export SRT_PASSWORD="your_password"

Add these to your shell profile (~/.zshrc, ~/.bashrc, etc.) for persistence.

Security Note: Avoid committing credentials to version control.

Important: Phone number must include hyphens in the format 010-XXXX-XXXX

Usage

User-Invocable Command

Use the /srt slash command in OpenClaw:

/srt search --departure "μˆ˜μ„œ" --arrival "λΆ€μ‚°" --date "20260217" --time "140000"
/srt reserve --train-id "1"
/srt reserve --retry --timeout-minutes 60
/srt reserve --retry --train-id "1,3,5" --timeout-minutes 60
/srt log -n 30
/srt list
/srt cancel --reservation-id "RES123456"

Natural Language (AI-Orchestrated)

The AI can invoke this skill based on user intent:

Examples:

  • "2μ›” 17일에 μˆ˜μ„œμ—μ„œ λΆ€μ‚° κ°€λŠ” κΈ°μ°¨ κ²€μƒ‰ν•΄μ€˜" (Search trains)
  • "제일 λΉ λ₯Έκ±Έλ‘œ μ˜ˆμ•½ν•΄μ€˜" (Reserve first available)
  • "λ‚΄ μ˜ˆμ•½ ν™•μΈν•΄μ€˜" (List bookings)
  • "λΆ€μ‚° μ˜ˆμ•½ μ·¨μ†Œν•΄μ€˜" (Cancel booking)

Direct CLI Usage

# Search trains
uv run --with SRTrain python3 scripts/srt_cli.py search \
  --departure "μˆ˜μ„œ" \
  --arrival "λΆ€μ‚°" \
  --date "20260217" \
  --time "140000" \
  --passengers "adult=2"

# Make reservation (single attempt)
uv run --with SRTrain python3 scripts/srt_cli.py reserve --train-id "1"

# Make reservation with automatic retry - all trains (background mode recommended)
uv run --with SRTrain python3 scripts/srt_cli.py reserve --retry \
  --timeout-minutes 60 \
  --wait-seconds 10

# Make reservation with automatic retry - specific trains only
uv run --with SRTrain python3 scripts/srt_cli.py reserve --retry \
  --train-id "1,3,5" \
  --timeout-minutes 60 \
  --wait-seconds 10

# Check reservation log
uv run --with SRTrain python3 scripts/srt_cli.py log -n 30

# View bookings
uv run --with SRTrain python3 scripts/srt_cli.py list --format json

# Cancel booking
uv run --with SRTrain python3 scripts/srt_cli.py cancel \
  --reservation-id "RES123456" \
  --confirm

Common Korean Station Names

Main SRT Stations:

  • μˆ˜μ„œ (Suseo) - Seoul SRT station
  • λΆ€μ‚° (Busan)
  • λ™λŒ€κ΅¬ (Dongdaegu) - Daegu
  • λŒ€μ „ (Daejeon)
  • μ²œμ•ˆμ•„μ‚° (Cheonan-Asan)
  • μ˜€μ†‘ (Osong)
  • 광주솑정 (Gwangju-Songjeong)
  • μšΈμ‚° (Ulsan)
  • 포항 (Pohang)
  • κ²½μ£Ό (Gyeongju)
  • κΉ€μ²œκ΅¬λ―Έ (Gimcheon-Gumi)
  • 읡산 (Iksan)
  • μ „μ£Ό (Jeonju)
  • λͺ©ν¬ (Mokpo)
  • μ‹ κ²½μ£Ό (Singyeongju)

Important: Station names MUST be in Korean (Hangul) for the SRT API to work correctly.

Date and Time Formats

  • Date: YYYYMMDD (e.g., 20260217 for February 17, 2026)
  • Time: HHMMSS (e.g., 140000 for 2:00 PM, 093000 for 9:30 AM)

Tools for AI Agent

This skill provides 5 tools for managing SRT train reservations:

1. search_trains

Search for available trains between stations.

Usage:

uv run --with SRTrain python3 scripts/srt_cli.py search \
  --departure "μˆ˜μ„œ" \
  --arrival "λΆ€μ‚°" \
  --date "20260217" \
  --time "120000"

Returns: JSON array of available trains with seat availability

JSON Format:

{
  "success": true,
  "data": [
    {
      "train_id": "1",
      "train_number": "301",
      "train_name": "SRT301",
      "departure_time": "120500",
      "arrival_time": "143000",
      "departure_station": "μˆ˜μ„œ",
      "arrival_station": "λΆ€μ‚°",
      "seat_available": true,
      "general_seat": "μ˜ˆμ•½κ°€λŠ₯",
      "special_seat": "μ˜ˆμ•½κ°€λŠ₯"
    }
  ]
}

2. make_reservation

Reserve trains with optional automatic retry support.

Usage (single attempt):

uv run --with SRTrain python3 scripts/srt_cli.py reserve --train-id "1"

Usage (with retry):

# Try all trains
uv run --with SRTrain python3 scripts/srt_cli.py reserve --retry \
  --timeout-minutes 60 \
  --wait-seconds 10

# Try specific trains only
uv run --with SRTrain python3 scripts/srt_cli.py reserve --retry \
  --train-id "1,3,5" \
  --timeout-minutes 60 \
  --wait-seconds 10

Options:

  • --train-id: Specific train(s) to reserve (comma-separated, e.g., "1" or "1,3,5"; omit to try all trains)
  • --retry: Enable automatic retry on failure
  • --timeout-minutes: Maximum retry duration in minutes (default: 60)
  • --wait-seconds: Wait time between retry attempts in seconds (default: 10)

Behavior with --retry:

  1. Cycles through all available trains from search results
  2. Waits --wait-seconds between attempts (plus rate-limiting delays)
  3. Continues until success or timeout
  4. Logs progress to ~/.openclaw/tmp/srt/reserve.log

Returns: Reservation details with payment deadline

JSON Format:

{
  "success": true,
  "data": {
    "reservation_id": "RES123456",
    "journey_date": "20260217",
    "journey_time": "120500",
    "departure": "μˆ˜μ„œ",
    "arrival": "λΆ€μ‚°",
    "train_number": "301",
    "seat_number": "3A",
    "payment_required": true,
    "attempts": 12
  }
}

Note:

  • Payment must be completed manually by user via SRT app/website
  • For retry mode, run in background with exec tool and periodically check logs

3. view_bookings

List all current reservations.

Usage:

uv run --with SRTrain python3 scripts/srt_cli.py list --format json

Returns: JSON array of active reservations

JSON Format:

{
  "success": true,
  "data": [
    {
      "reservation_id": "RES123456",
      "journey_date": "20260217",
      "journey_time": "120500",
      "departure": "μˆ˜μ„œ",
      "arrival": "λΆ€μ‚°",
      "train_number": "301",
      "seat_number": "3A",
      "payment_required": true
    }
  ]
}

4. cancel_booking

Cancel a reservation by ID.

Usage:

uv run --with SRTrain python3 scripts/srt_cli.py cancel \
  --reservation-id "RES123456" \
  --confirm

Returns: Cancellation confirmation

JSON Format:

{
  "success": true,
  "data": {
    "success": true,
    "reservation_id": "RES123456",
    "message": "Reservation cancelled successfully"
  }
}

5. check_log

Check the progress of reservation attempts (especially useful for retry mode).

Usage:

uv run --with SRTrain python3 scripts/srt_cli.py log -n 30

Returns: Last N lines of reservation log file (~/.openclaw/tmp/srt/reserve.log)

Options:

  • -n, --lines: Number of lines to show (default: 20)

Log Format Example:

[2026-02-03 11:00:00] INFO: === SRT μ˜ˆμ•½ μ‹œμž‘ (μž¬μ‹œλ„ λͺ¨λ“œ) ===
[2026-02-03 11:00:00] INFO: νƒ€μž„μ•„μ›ƒ: 60λΆ„
[2026-02-03 11:00:00] INFO: μž¬μ‹œλ„ 간격: 10초
[2026-02-03 11:00:00] INFO: λŒ€μƒ μ—΄μ°¨: 1,3,5 (총 3개)
[2026-02-03 11:00:05] INFO: === μ‹œλ„ #1 (μ—΄μ°¨ 1/3) ===
[2026-02-03 11:00:05] INFO: 🎫 μ˜ˆμ•½ μ‹œλ„ 쀑... (μ—΄μ°¨ 301, 120500)
[2026-02-03 11:00:06] WARN: ❌ μ’Œμ„ μ—†μŒ (μ—΄μ°¨ 301)
[2026-02-03 11:00:06] INFO: ⏳ 10초 λŒ€κΈ° ν›„ μž¬μ‹œλ„...
[2026-02-03 11:00:26] INFO: === μ‹œλ„ #2 (μ—΄μ°¨ 2/3) ===
...
[2026-02-03 11:05:00] SUCCESS: βœ… μ˜ˆμ•½ 성곡!

Error Handling

The skill provides clear, actionable error messages:

Common Errors:

  1. AuthenticationFailed

    • Invalid credentials
    • Solution: Check phone number and password in config
  2. NoSeatsAvailable

    • Train is sold out
    • Solution: Try next train or different time
    • Exit code: 1 (retryable)
  3. StationNotFound

    • Invalid station name
    • Solution: Use Korean station names from the list above
  4. NoTrainsFound

    • No trains for specified route/time
    • Solution: Try different date or time
  5. RateLimitExceeded

    • Too many retry attempts (max 10 per session)
    • Solution: Wait a few minutes before trying again
  6. NetworkError

    • Connection timeout or failure
    • Solution: Check internet connection and retry

Exit Codes:

  • 0 - Success
  • 1 - Retryable error (e.g., no seats available)
  • 2 - Fatal error (e.g., authentication failed, invalid input)

⚠️ Rate Limiting and Account Protection

To protect your SRT account from being blocked by the server:

  • Automatic delays between requests:
    • Minimum 3 seconds between reservation attempts
    • Minimum 5 seconds between search requests
  • Maximum 10 retry attempts per session
  • Exponential backoff after failures (3s β†’ 5s β†’ 10s β†’ 15s β†’ 20s β†’ 30s)

What this means for users:

  • The skill will automatically wait between requests
  • You'll see waiting messages like "⏳ SRT μ„œλ²„ 보호λ₯Ό μœ„ν•΄ λŒ€κΈ° 쀑 (3초)"
  • If you hit the retry limit, wait a few minutes before trying again

For AI orchestration:

  • The AI should inform users about delays during retries
  • Example: "μž¬μ‹œλ„ μ€‘μž…λ‹ˆλ‹€. μ„œλ²„ 보호λ₯Ό μœ„ν•΄ 3초 λŒ€κΈ°ν•©λ‹ˆλ‹€..."
  • After 10 failed attempts, suggest alternatives like different times or dates

Natural Language Handling

When users make requests in Korean, the AI should:

  1. Extract parameters from natural language:

    • Stations (must convert to Korean if given in English)
    • Date (relative dates like "내일", "λ‹€μŒμ£Ό κΈˆμš”μΌ" β†’ YYYYMMDD)
    • Time (relative times like "μ˜€ν›„ 2μ‹œ", "12μ‹œ 이후" β†’ HHMMSS)
    • Passenger count (default to 1 if not specified)
  2. Call tools in correct sequence:

    • Search before reserving
    • List before canceling
    • Handle retry logic with rate limiting
  3. Handle errors gracefully:

    • If no seats available, try next train (with delays)
    • If station not found, suggest correct Korean name
    • Inform user about waiting times during rate limiting
  4. Confirm actions in Korean:

    • "μ˜ˆμ•½μ΄ μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€" (Reservation completed)
    • "3초 ν›„ λ‹€μŒ μ—΄μ°¨λ₯Ό μ‹œλ„ν•©λ‹ˆλ‹€" (Trying next train in 3 seconds)
    • "κ²°μ œλŠ” SRT μ•±μ—μ„œ μ™„λ£Œν•΄μ£Όμ„Έμš”" (Complete payment in SRT app)

Real-World Usage Scenarios

Scenario 1: Simple Reservation

User: "2μ›” 17일에 μˆ˜μ„œμ—μ„œ λ™λŒ€κ΅¬ κ°€λŠ”κ±° 12μ‹œμ΄ν›„ 제일 λΉ λ₯Έκ±Έλ‘œ 2μž₯ μ˜ˆμ•½ν•΄μ€˜"

AI Actions:

  1. Parse: departure=μˆ˜μ„œ, arrival=λ™λŒ€κ΅¬, date=20260217, time=120000, passengers=adult:2
  2. Search trains
  3. Select first available train
  4. Reserve train
  5. Confirm with payment reminder

Scenario 2: Retry Until Success

User: "맀진이면 μ„±κ³΅ν• λ•ŒκΉŒμ§€ λ°˜λ³΅ν•΄"

AI Actions:

  1. Search trains
  2. Start background retry:
    exec reserve --retry --timeout-minutes 60 --wait-seconds 10 (in background)
    
  3. Create monitoring cron job (isolated session + agentTurn):
    cron add --job '{
      "schedule": {"kind": "every", "everyMs": 120000},
      "payload": {
        "kind": "agentTurn",
        "message": "Check SRT retry log and report progress",
        "deliver": true,
        "channel": "discord"
      },
      "sessionTarget": "isolated",
      "enabled": true
    }'
    cron wake --mode "now"
    
  4. Inform user: "λ°±κ·ΈλΌμš΄λ“œ μž¬μ‹œλ„ μ‹œμž‘. 2λΆ„λ§ˆλ‹€ μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€."

⚠️ Background Retry Monitoring

MANDATORY: Use isolated session + agentTurn cron jobs for monitoring reserve --retry.

Setup

# 1. Start background retry
exec reserve --retry --timeout-minutes 60 (background)

# 2. Create monitoring cron (isolated + agentTurn)
cron add --job '{
  "schedule": {"kind": "every", "everyMs": 120000},
  "payload": {
    "kind": "agentTurn",
    "message": "Check `srt_cli.py log -n 30`, parse progress, report to user. Delete cron if done.",
    "deliver": true,
    "channel": "discord"
  },
  "sessionTarget": "isolated",
  "enabled": true
}'

# 3. Wake immediately
cron wake --mode "now"

Requirements

  • sessionTarget: "isolated" (NOT "main")
  • payload.kind: "agentTurn" (NOT "systemEvent")
  • payload.deliver: true
  • Schedule: Every 1-3 minutes depending on task duration
  • Wake: Always call cron wake --mode "now" after creating job

Why

  • systemEvent in main session doesn't trigger agent action
  • agentTurn in isolated session actually executes and reports
  • Prevents blocking, message batching, and silent monitoring

Scenario 3: Check and Cancel

User: "λ‚΄ μ˜ˆμ•½ 확인해주고 제일 λΉ λ₯Έκ±° μ·¨μ†Œν•΄μ€˜"

AI Actions:

  1. List reservations
  2. Parse JSON, find earliest by date/time
  3. Cancel reservation
  4. Confirm cancellation

Scenario 4: Modify Booking

User: "λΆ€μ‚° μ˜ˆμ•½ μ·¨μ†Œν•˜κ³  λ™λŒ€κ΅¬λ‘œ λ‹€μ‹œ μ˜ˆμ•½ν•΄μ€˜"

AI Actions:

  1. List reservations
  2. Find Busan reservation
  3. Cancel Busan reservation
  4. Search for trains to λ™λŒ€κ΅¬ (same date/time)
  5. Reserve new train
  6. Confirm both actions

Payment Notes

IMPORTANT: This skill can search and reserve trains, but cannot process payments.

After making a reservation:

  1. You'll receive a reservation number
  2. Payment must be completed via:
  3. Check payment deadline (usually 20 minutes after reservation)
  4. Unpaid reservations will be automatically cancelled

Troubleshooting

"SRT 인증 정보λ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€"

  • Verify SRT_PHONE and SRT_PASSWORD environment variables are set
  • Check your shell profile (~/.zshrc, ~/.bashrc) has export keyword
  • Example: export SRT_PHONE="010-1234-5678"

"검색 κ²°κ³Όλ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€"

  • Run search command before reserve
  • Search results are cached in ~/.openclaw/tmp/srt/last_search.pkl

"μž¬μ‹œλ„ ν•œλ„ 초과"

  • You've made 10 reservation attempts
  • Wait 5-10 minutes before trying again
  • Try different trains or times

Login failures

  • Verify credentials are correct
  • Check if SRT service is available
  • Ensure phone number format includes hyphens (010-1234-5678)

Development

Testing Locally

# Install dependencies
# Install uv if not already installed
# https://docs.astral.sh/uv/getting-started/installation/

# Configure credentials
export SRT_PHONE="010-1234-5678"
export SRT_PASSWORD="your_password"

# Test commands
uv run --with SRTrain python3 scripts/srt_cli.py search --departure "μˆ˜μ„œ" --arrival "λΆ€μ‚°" --date "20260203" --time "140000"
uv run --with SRTrain python3 scripts/srt_cli.py list

Publishing to ClawHub

# Authenticate
clawhub login

# Publish
clawhub publish . \
  --slug srt \
  --name "SRT Korean Train Service" \
  --version 0.1.2 \
  --tags latest

License

MIT

Support

For issues or questions:

Version History

  • 0.1.3 - Retry improvements and monitoring requirements
    • Unified reserve command with --retry flag
    • Added --timeout-minutes for time-based retry limits (default: 60)
    • Added --train-id support for comma-separated multiple trains (e.g., "1,3,5")
    • Changed --wait-seconds default from 20 to 10 seconds
    • Search includes sold-out trains by default (available_only=False)
    • Monitoring: Isolated session + agentTurn cron jobs required for background retry
  • 0.1.2 - Add --all flag for sold-out trains (deprecated)
  • 0.1.1 - Use uv for dependency management
    • Replace venv/pip with uv run --with SRTrain
    • Environment variables only for credentials (remove config file support)
  • 0.1.0 - Initial release
    • Search trains
    • Make reservations
    • View bookings
    • Cancel bookings
    • Rate limiting protection
    • AI-friendly JSON output