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

9.0 KiB

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

cd textme-closebot-channel
npm install
npm run build

Configuration

Option 1: Environment Variables (Simple)

For a single account setup:

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:

{
  "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

# Start the plugin
npm start

# Or with tsx for development
npm run dev

Programmatic Usage

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.

curl http://localhost:3100/textme/probe

Response:

{
  "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.

curl -X POST http://localhost:3100/textme/send \
  -H "Content-Type: application/json" \
  -d '{
    "target": "123456",
    "message": "Hello!",
    "accountId": "primary"
  }'

Request body:

{
  "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:

{
  "success": true,
  "messageId": "456789"
}

GET /textme/health

Health check endpoint.

curl http://localhost:3100/textme/health

Response:

{
  "status": "healthy",
  "accounts": 2,
  "timestamp": "2024-01-01T00:00:00.000Z"
}

Inbound Message Format

Messages forwarded to Clawdbot gateway:

{
  "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:

{
  "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

# 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.