|
| 1 | +# Auto Re-login (OTP Webhook) |
| 2 | + |
| 3 | +When a Telkomsel session expires during automation (e.g., auto-buy), Telbot can automatically re-login by receiving the OTP via a webhook from the [SMS Forwarder](../sms-forwarder-openwrt/README.md) running on an OpenWrt device. |
| 4 | + |
| 5 | +## Architecture |
| 6 | + |
| 7 | +``` |
| 8 | +┌──────────────────────────────────┐ |
| 9 | +│ OpenWrt (Home) │ |
| 10 | +│ │ |
| 11 | +│ Android ──ADB──► sms-forwarder │ |
| 12 | +│ │ │ |
| 13 | +│ ┌──────────┴────────┐ │ |
| 14 | +│ │ 1. Telegram (info)│ │ |
| 15 | +│ │ 2. POST webhook │ │ |
| 16 | +│ │ to VPS │ │ |
| 17 | +│ └──────────┬────────┘ │ |
| 18 | +└───────────────────────┼──────────┘ |
| 19 | + │ HTTP POST (internet) |
| 20 | + ▼ |
| 21 | +┌──────────────────────────────────┐ |
| 22 | +│ VPS (Telbot) │ |
| 23 | +│ │ |
| 24 | +│ HTTP Server (:8081/api/otp) │ |
| 25 | +│ │ │ |
| 26 | +│ ▼ │ |
| 27 | +│ OTP Listener ──► parse OTP │ |
| 28 | +│ │ (regex) │ |
| 29 | +│ ▼ │ |
| 30 | +│ Auto Re-login │ |
| 31 | +│ ├─ bot mode (auto-buy resumes) │ |
| 32 | +│ └─ cli mode (auto login) │ |
| 33 | +└──────────────────────────────────┘ |
| 34 | +``` |
| 35 | + |
| 36 | +## How It Works |
| 37 | + |
| 38 | +1. **Session expires** — Telbot detects `401 Unauthorized` during API calls (e.g., quota check in auto-buy) |
| 39 | +2. **Request OTP** — Telbot automatically calls `RequestOTP()` for the phone number |
| 40 | +3. **SMS arrives** — Telkomsel sends OTP via SMS to the phone connected to OpenWrt |
| 41 | +4. **SMS Forwarder** — Detects new SMS via ADB, POSTs it to Telbot's webhook |
| 42 | +5. **Parse & Submit** — Telbot extracts the OTP code (regex), submits it, and gets new tokens |
| 43 | +6. **Resume** — Auto-buy continues with the renewed session |
| 44 | + |
| 45 | +## Setup |
| 46 | + |
| 47 | +### Step 1: Configure Telbot (VPS) |
| 48 | + |
| 49 | +Add these environment variables to your `.env`: |
| 50 | + |
| 51 | +```bash |
| 52 | +OTP_WEBHOOK_PORT=8081 |
| 53 | +OTP_WEBHOOK_SECRET=your-random-secret-here |
| 54 | +``` |
| 55 | + |
| 56 | +Open the firewall port: |
| 57 | +```bash |
| 58 | +sudo ufw allow 8081/tcp |
| 59 | +``` |
| 60 | + |
| 61 | +### Step 2: Configure SMS Forwarder (OpenWrt) |
| 62 | + |
| 63 | +See the [SMS Forwarder README](../sms-forwarder-openwrt/README.md) for full installation. Add the webhook config: |
| 64 | + |
| 65 | +```bash |
| 66 | +# In /etc/sms-forwarder/sms-forwarder.conf: |
| 67 | +WEBHOOK_URL="http://YOUR_VPS_IP:8081/api/otp" |
| 68 | +WEBHOOK_SECRET="your-random-secret-here" |
| 69 | +``` |
| 70 | + |
| 71 | +> **Important:** `WEBHOOK_SECRET` must match `OTP_WEBHOOK_SECRET` in Telbot. |
| 72 | +
|
| 73 | +### Step 3: Test |
| 74 | + |
| 75 | +Health check: |
| 76 | +```bash |
| 77 | +curl http://YOUR_VPS_IP:8081/health |
| 78 | +# Expected: ok |
| 79 | +``` |
| 80 | + |
| 81 | +Simulate an OTP webhook: |
| 82 | +```bash |
| 83 | +curl -X POST http://YOUR_VPS_IP:8081/api/otp \ |
| 84 | + -H "Content-Type: application/json" \ |
| 85 | + -H "X-Webhook-Secret: your-random-secret-here" \ |
| 86 | + -d '{"from":"+6281219414870","body":"Kode OTP MyTelkomsel Anda: 654321. Jangan berikan ke siapapun."}' |
| 87 | +``` |
| 88 | + |
| 89 | +## Webhook API |
| 90 | + |
| 91 | +### `POST /api/otp` |
| 92 | + |
| 93 | +Receives SMS content from the SMS Forwarder. |
| 94 | + |
| 95 | +**Headers:** |
| 96 | +| Header | Required | Description | |
| 97 | +|--------|----------|-------------| |
| 98 | +| `Content-Type` | Yes | `application/json` | |
| 99 | +| `X-Webhook-Secret` | If configured | Must match `OTP_WEBHOOK_SECRET` | |
| 100 | + |
| 101 | +**Request body:** |
| 102 | +```json |
| 103 | +{ |
| 104 | + "from": "+6281xxxxx", |
| 105 | + "body": "Kode OTP MyTelkomsel Anda: 123456. Jangan berikan kepada siapapun." |
| 106 | +} |
| 107 | +``` |
| 108 | + |
| 109 | +**Responses:** |
| 110 | +```json |
| 111 | +{"status":"dispatched","otp":"123456"} // OTP sent to waiting caller |
| 112 | +{"status":"no_waiter","otp":"123456"} // No one waiting for OTP |
| 113 | +{"status":"no_otp_found"} // Could not parse OTP from body |
| 114 | +``` |
| 115 | + |
| 116 | +### `GET /health` |
| 117 | + |
| 118 | +Returns `ok` — useful for uptime monitoring. |
| 119 | + |
| 120 | +## OTP Parsing |
| 121 | + |
| 122 | +The listener uses regex to extract OTP codes from SMS body: |
| 123 | + |
| 124 | +| Priority | Pattern | Example Match | |
| 125 | +|----------|---------|---------------| |
| 126 | +| 1 | `Kode OTP ... 123456` | Specific Telkomsel pattern | |
| 127 | +| 2 | Generic 6-digit | Any standalone 6-digit number | |
| 128 | +| 3 | Generic 4-digit | Any standalone 4-digit number | |
| 129 | + |
| 130 | +## Behavior |
| 131 | + |
| 132 | +- **Backward compatible** — Without `OTP_WEBHOOK_PORT`, behavior is unchanged (manual login only) |
| 133 | +- **Cooldown** — Minimum 2 minutes between re-login attempts per phone number to avoid rate limiting |
| 134 | +- **Timeout** — If no OTP is received within 3 minutes, re-login fails and auto-buy stops |
| 135 | +- **Fallback** — If auto re-login fails, user is notified and manual login is required |
| 136 | +- **Both modes** — Works in both `--bot` and `--cli` modes |
0 commit comments