diff --git a/README.md b/README.md new file mode 100644 index 0000000..81a2e7c --- /dev/null +++ b/README.md @@ -0,0 +1,298 @@ +# Textpipe - SMS API Gateway + +An Android app that turns your phone into an SMS API gateway with a web interface. + +## Features + +- **REST API** - Send and receive SMS via HTTP endpoints +- **Dual SIM Support** - Each SIM gets its own API key +- **Web UI** - Google Messages-like interface accessible from any browser +- **Local Database** - All messages stored locally with delivery tracking +- **Background Service** - Runs as a foreground service with persistent notification +- **Auto-start** - Optionally start on device boot +- **Root Port Redirect** - Use ports 80/443 with root access via iptables + +## Requirements + +- Android 7.0+ (API 24+) +- SMS permissions +- Phone state permissions (for dual SIM) +- (Optional) Root access for privileged ports + +## Building + +### Prerequisites + +- Android Studio or command line with Android SDK +- JDK 11+ +- Node.js 18+ (for web UI) + +### Build Steps + +1. **Clone the repository** + ```bash + git clone + cd textpipe + ``` + +2. **Build the Web UI** + ```bash + cd webui + npm install + npm run build + cd .. + ``` + This builds the Vue frontend to `app/src/main/assets/webui/` + +3. **Build the Android App** + ```bash + ./gradlew assembleDebug + ``` + The APK will be at `app/build/outputs/apk/debug/app-debug.apk` + +4. **Install on device** + ```bash + adb install app/build/outputs/apk/debug/app-debug.apk + ``` + +### Release Build + +```bash +./gradlew assembleRelease +``` + +Note: You'll need to configure signing in `app/build.gradle.kts` for release builds. + +## Usage + +### Initial Setup + +1. Install and open the app +2. Grant all requested permissions (SMS, Phone, Notifications) +3. Note the API key(s) shown for each SIM card +4. Configure the port (default: 8080) +5. Tap "Start Server" +6. (Optional) Disable battery optimization for reliable background operation + +### API Endpoints + +Base URL: `http://:` + +#### Status (No auth required) +``` +GET /api/status +``` +Returns server status and SIM information. + +#### Send SMS +``` +POST /api/sms/send +Header: X-API-Key: +Content-Type: application/json + +{ + "to": "+1234567890", + "text": "Hello from Textpipe!" +} +``` + +Response: +```json +{ + "id": 1, + "status": "pending", + "simSlot": 0 +} +``` + +#### List Messages +``` +GET /api/sms/messages +Header: X-API-Key: +``` + +Optional query parameter: `?type=sent` or `?type=received` + +Response: +```json +{ + "messages": [ + { + "id": 1, + "type": "sent", + "address": "+1234567890", + "text": "Hello!", + "simSlot": 0, + "status": "delivered", + "timestamp": 1707148800000, + "deliveryTimestamp": 1707148805000 + } + ], + "total": 1 +} +``` + +#### Get Message Status +``` +GET /api/sms/status/{id} +Header: X-API-Key: +``` + +### Authentication + +Pass your API key in one of these ways: +- Header: `Authorization: Bearer ` +- Header: `X-API-Key: ` +- Query param: `?api_key=` + +Each SIM card has its own unique API key. The API key determines which SIM sends the message. + +### Web Interface + +Open `http://:/` in any browser to access the web UI. + +1. Enter your API key to login +2. View conversations grouped by contact +3. Send new messages using the + button +4. Click on a conversation to view message thread + +### cURL Examples + +**Send SMS:** +```bash +curl -X POST http://10.0.1.12:8080/api/sms/send \ + -H "Content-Type: application/json" \ + -H "X-API-Key: your-api-key-here" \ + -d '{"to": "+1234567890", "text": "Hello!"}' +``` + +**Check status:** +```bash +curl http://10.0.1.12:8080/api/status +``` + +**List messages:** +```bash +curl -H "X-API-Key: your-api-key-here" \ + http://10.0.1.12:8080/api/sms/messages +``` + +**Get specific message:** +```bash +curl -H "X-API-Key: your-api-key-here" \ + http://10.0.1.12:8080/api/sms/status/1 +``` + +## Configuration + +### Port Configuration + +- Default port: 8080 +- Can be changed in the app UI +- For ports below 1024 (like 80 or 443), root access is required +- With root, the app uses iptables to redirect traffic from the privileged port to the actual server port + +### Auto-start + +Enable "Auto-start on boot" in Settings to automatically start the server when the device boots. + +### Battery Optimization + +For reliable background operation, disable battery optimization for Textpipe: +1. Go to Settings in the app +2. Tap "Disable" next to Battery Optimization +3. Confirm in the system dialog + +## Project Structure + +``` +textpipe/ +├── app/ # Android app +│ └── src/main/ +│ ├── java/sh/sar/textpipe/ +│ │ ├── MainActivity.kt +│ │ ├── TextpipeApplication.kt +│ │ ├── data/ +│ │ │ ├── db/ # Room database +│ │ │ ├── model/ # API models +│ │ │ └── repository/ # Data repository +│ │ ├── server/ # Ktor HTTP server +│ │ │ ├── TextpipeServer.kt +│ │ │ ├── auth/ # API key auth +│ │ │ └── routes/ # API endpoints +│ │ ├── service/ # Android services +│ │ │ ├── TextpipeService.kt +│ │ │ ├── SmsSender.kt +│ │ │ ├── SmsReceiver.kt +│ │ │ └── BootReceiver.kt +│ │ ├── sim/ # SIM management +│ │ ├── root/ # Root utilities +│ │ └── ui/ # Compose UI +│ ├── assets/webui/ # Built web UI +│ └── AndroidManifest.xml +├── webui/ # Vue.js web interface +│ ├── src/ +│ │ ├── App.vue +│ │ ├── api.js +│ │ ├── style.css +│ │ └── components/ +│ ├── package.json +│ └── vite.config.js +├── gradle/ +│ └── libs.versions.toml # Dependency versions +└── build.gradle.kts +``` + +## Tech Stack + +### Android App +- Kotlin +- Jetpack Compose (UI) +- Ktor CIO (HTTP server) +- Room (Database) +- Kotlin Coroutines +- kotlinx.serialization (JSON) + +### Web UI +- Vue 3 +- Vite +- Vanilla CSS + +## Message Status Flow + +``` +pending → sent → delivered + ↘ failed +``` + +- **pending** - Message queued, sending in progress +- **sent** - Message sent successfully +- **delivered** - Delivery confirmation received +- **failed** - Send failed + +## Troubleshooting + +### "Address already in use" error +The port is still bound from a previous instance. Either: +- Wait a few seconds and try again +- Change to a different port +- Force stop the app and restart + +### Server doesn't start +- Check that no other app is using the port +- Verify all permissions are granted +- Check logcat for errors: `adb logcat -s TextpipeServer TextpipeService` + +### Messages not sending +- Verify SMS permission is granted +- Check you have cellular signal +- Ensure the API key matches an active SIM + +### Web UI not loading +- Verify the server is running (check app status) +- Check you're using the correct IP and port +- Try accessing `/api/status` directly + +## License + +MIT