334 lines
9.0 KiB
Markdown
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.
|