2026-01-28 23:00:58 -05:00

334 lines
9.0 KiB
Markdown

# TextMe Clawdbot Channel Plugin
External channel plugin for integrating TextMe messaging with Clawdbot.
## Features
- **Multi-account support** - Manage multiple TextMe phone numbers
- **Persistent authentication** - Tokens stored securely, auto-refresh before expiry
- **Inbound messages** - Real-time WebSocket connection, auto-reconnect
- **Outbound messages** - HTTP webhook interface for Clawdbot
- **Standard channel plugin interface** - Probe, send, health endpoints
## Installation
```bash
cd textme-closebot-channel
npm install
npm run build
```
## Configuration
### Option 1: Environment Variables (Simple)
For a single account setup:
```bash
export TEXTME_EMAIL="your-email@example.com"
export TEXTME_PASSWORD="your-password"
export TEXTME_PHONE_NUMBERS="+1234567890,+0987654321"
export CLAWDBOT_GATEWAY_URL="http://localhost:3000"
export CLAWDBOT_GATEWAY_TOKEN="your-gateway-token" # optional
export TEXTME_WEBHOOK_PORT="3100"
export TEXTME_DEBUG="true" # optional
```
### Option 2: Configuration File (Multi-account)
Create `textme-channel.json` in your working directory:
```json
{
"accounts": [
{
"id": "primary",
"name": "Primary Account",
"credentials": {
"email": "primary@example.com",
"password": "password123"
},
"phoneNumbers": ["+1234567890"],
"enabled": true,
"isDefault": true
},
{
"id": "secondary",
"name": "Secondary Account",
"credentials": {
"email": "secondary@example.com",
"password": "password456"
},
"phoneNumbers": ["+0987654321"],
"enabled": true
}
],
"clawdbotGatewayUrl": "http://localhost:3000",
"clawdbotGatewayToken": "your-token",
"webhookPort": 3100,
"webhookPath": "/textme",
"debug": false,
"tokenStoragePath": ".textme-tokens.json",
"autoReconnect": true,
"maxReconnectAttempts": 10,
"reconnectDelay": 5000
}
```
## Usage
### Running Standalone
```bash
# Start the plugin
npm start
# Or with tsx for development
npm run dev
```
### Programmatic Usage
```typescript
import { createTextMeChannelPlugin } from 'textme-closebot-channel';
const plugin = createTextMeChannelPlugin({
configPath: './my-config.json',
debug: true,
// Optional: custom message handler (bypasses gateway forwarding)
onMessage: async (message, account) => {
console.log('Received:', message);
},
});
// Start the plugin
await plugin.start();
// Get status
const status = plugin.getStatus();
console.log('Running:', status.running);
console.log('Accounts:', status.accounts);
// Send a message programmatically
const result = await plugin.send({
target: '123456', // conversation ID
message: 'Hello from Clawdbot!',
accountId: 'primary', // optional: specific account
});
// Stop the plugin
await plugin.stop();
```
## Webhook Endpoints
The plugin exposes these HTTP endpoints:
### GET /textme/probe
Channel plugin probe endpoint. Returns plugin capabilities and account status.
```bash
curl http://localhost:3100/textme/probe
```
Response:
```json
{
"channel": "textme",
"version": "1.0.0",
"capabilities": ["send", "receive", "attachments", "multi-account"],
"accounts": [
{
"id": "primary",
"name": "Primary Account",
"phoneNumbers": ["+1234567890"],
"enabled": true
}
],
"status": "ready"
}
```
### POST /textme/send
Send a message via TextMe.
```bash
curl -X POST http://localhost:3100/textme/send \
-H "Content-Type: application/json" \
-d '{
"target": "123456",
"message": "Hello!",
"accountId": "primary"
}'
```
Request body:
```json
{
"target": "123456", // Conversation ID or phone number
"message": "Hello!", // Message content
"accountId": "primary", // Optional: specific account ID
"fromNumber": "+1234567890", // Optional: specific from number
"attachments": ["123"], // Optional: attachment IDs
"replyTo": "789" // Optional: reply to message ID
}
```
Response:
```json
{
"success": true,
"messageId": "456789"
}
```
### GET /textme/health
Health check endpoint.
```bash
curl http://localhost:3100/textme/health
```
Response:
```json
{
"status": "healthy",
"accounts": 2,
"timestamp": "2024-01-01T00:00:00.000Z"
}
```
## Inbound Message Format
Messages forwarded to Clawdbot gateway:
```json
{
"channel": "textme",
"channelId": "textme:primary:123456",
"messageId": "msg-123",
"authorId": "user-456",
"authorName": "John Doe",
"content": "Hello!",
"timestamp": "2024-01-01T00:00:00.000Z",
"attachments": [
{
"url": "https://...",
"type": "image"
}
],
"metadata": {
"conversationId": "123456",
"accountId": "primary",
"accountName": "Primary Account",
"phoneNumbers": ["+1234567890"]
}
}
```
## Token Storage
Tokens are stored in `.textme-tokens.json` (configurable via `tokenStoragePath`). This file is created with restrictive permissions (0600) and contains:
```json
{
"accounts": {
"primary": {
"accessToken": "...",
"refreshToken": "...",
"expiresAt": 1704067200000,
"userId": 12345
}
},
"lastUpdated": "2024-01-01T00:00:00.000Z"
}
```
**Important:** Keep this file secure and don't commit it to version control.
## Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ TextMe Channel Plugin │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Config │ │ Auth │ │ Token │ │
│ │ Manager │◄───│ Manager │◄───│ Storage │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Plugin Core │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Inbound │ │ Outbound │ │
│ │ Handler │ │ Handler │ │
│ │ (WebSocket) │ │ (HTTP) │ │
│ └─────────────┘ └─────────────┘ │
│ │ │ │
└─────────│────────────────────────────────────│───────────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ TextMe │ │ TextMe │
│ Realtime │ │ REST API │
│ WebSocket │ │ │
└─────────────┘ └─────────────┘
```
## Development
```bash
# Install dependencies
npm install
# Build
npm run build
# Watch mode
npm run watch
# Run with tsx (no build needed)
npm run dev
# Type check
npm run typecheck
```
## Troubleshooting
### Authentication Errors
1. Check credentials in config/environment
2. Delete `.textme-tokens.json` to force re-authentication
3. Enable debug mode to see detailed logs
### Connection Issues
1. Check network connectivity
2. Verify TextMe service status
3. Check if tokens are expired (delete token file)
4. Enable debug mode and check WebSocket errors
### Messages Not Forwarding
1. Verify `clawdbotGatewayUrl` is correct
2. Check if gateway token is valid
3. Check Clawdbot gateway logs for errors
4. Test with custom `onMessage` handler
## License
MIT
## Disclaimer
This plugin uses the unofficial `textme-unofficial-api` package. Use at your own risk. See the API package disclaimer for details.