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

7.5 KiB

textme-unofficial-api

⚠️ UNOFFICIAL API - This library is not affiliated with, endorsed by, or connected to TextMe Inc. in any way. Use at your own risk. This library may break at any time if TextMe changes their internal APIs.

An unofficial TypeScript/JavaScript client for the TextMe messaging service. Provides authentication, REST API access, and realtime WebSocket support.

Installation

npm install textme-unofficial-api

Requirements

  • Node.js >= 18.0.0
  • A TextMe account

Quick Start

import { TextMeClient } from 'textme-unofficial-api';

const client = new TextMeClient({
  credentials: {
    email: 'your-email@example.com',
    password: 'your-password'
  }
});

// Connect and authenticate
await client.connect();

// Listen for incoming messages
client.on('message.received', (event) => {
  console.log('New message from:', event.message.senderPhoneNumber);
  console.log('Content:', event.message.content.text);
});

// Send a message
await client.sendMessage({
  recipientPhoneNumber: '+1234567890',
  senderPhoneNumber: '+0987654321', // Your TextMe number
  text: 'Hello from TextMe!'
});

// Get conversations
const conversations = await client.getConversations({ limit: 20 });
console.log(`You have ${conversations.data.length} conversations`);

// Disconnect when done
await client.disconnect();

API Reference

TextMeClient

The unified client that combines all functionality.

Constructor Options

interface TextMeClientOptions {
  // Authentication (provide one)
  credentials?: { email: string; password: string };
  tokens?: AuthTokens;
  
  // Configuration
  baseUrl?: string;      // Custom API base URL
  wsUrl?: string;        // Custom WebSocket URL
  timeout?: number;      // Request timeout (ms)
  debug?: boolean;       // Enable debug logging
  
  // Reconnection
  autoReconnect?: boolean;       // Auto-reconnect on disconnect
  maxReconnectAttempts?: number; // Max reconnection attempts
  reconnectDelay?: number;       // Delay between attempts (ms)
}

Connection Methods

// Connect and authenticate
await client.connect(): Promise<AuthSession>

// Disconnect from services
await client.disconnect(): Promise<void>

// Check connection status
client.isConnected(): boolean

Authentication Methods

// Login with credentials
await client.login(credentials): Promise<AuthSession>

// Refresh tokens
await client.refreshTokens(): Promise<AuthTokens>

// Get current user info
await client.getCurrentUser(): Promise<User>

Messaging Methods

// Send a message
await client.sendMessage({
  recipientPhoneNumber: string,
  senderPhoneNumber: string,
  text?: string,
  mediaUrls?: string[]
}): Promise<SendMessageResponse>

// Get conversations
await client.getConversations({
  limit?: number,
  offset?: number,
  before?: string,
  after?: string
}): Promise<PaginatedResponse<Conversation>>

// Get messages in a conversation
await client.getMessages({
  conversationId: string,
  limit?: number,
  before?: string,
  after?: string
}): Promise<PaginatedResponse<Message>>

// Mark messages as read
await client.markAsRead(conversationId: string, messageIds?: string[]): Promise<void>

// Delete a message
await client.deleteMessage(messageId: string): Promise<void>

Realtime Events

// Subscribe to events
client.on('message.received', (event) => {
  console.log(event.message);
});

client.on('message.status', (event) => {
  console.log(`Message ${event.messageId} is now ${event.status}`);
});

client.on('typing.start', (event) => {
  console.log(`Someone is typing in ${event.conversationId}`);
});

client.on('connection.close', (event) => {
  console.log('Disconnected');
});

// Unsubscribe
client.off('message.received', handler);

// Send typing indicator
client.sendTyping(conversationId, true);  // Started typing
client.sendTyping(conversationId, false); // Stopped typing

Individual Modules

For advanced use cases, you can use the modules directly:

import { TextMeAuth, TextMeAPI, TextMeRealtime } from 'textme-unofficial-api';

// Authentication only
const auth = new TextMeAuth({ debug: true });
const session = await auth.login({ email, password });

// API only
const api = new TextMeAPI();
api.setTokens(session.tokens);
const conversations = await api.getConversations();

// Realtime only
const realtime = new TextMeRealtime({ autoReconnect: true });
await realtime.connect(session.tokens);
realtime.on('message.received', console.log);

Types

User

interface User {
  id: string;
  email: string;
  displayName: string;
  avatarUrl?: string;
  phoneNumbers: PhoneNumber[];
  createdAt: string;
  updatedAt: string;
}

PhoneNumber

interface PhoneNumber {
  id: string;
  number: string;
  countryCode: string;
  type: 'mobile' | 'landline' | 'voip' | 'unknown';
  isPrimary: boolean;
  isVerified: boolean;
  capabilities: {
    sms: boolean;
    mms: boolean;
    voice: boolean;
  };
}

Conversation

interface Conversation {
  id: string;
  type: 'direct' | 'group';
  participants: Participant[];
  lastMessage?: Message;
  unreadCount: number;
  isPinned: boolean;
  isMuted: boolean;
  createdAt: string;
  updatedAt: string;
}

Message

interface Message {
  id: string;
  conversationId: string;
  senderId: string;
  senderPhoneNumber: string;
  recipientPhoneNumber: string;
  content: {
    type: 'text' | 'media' | 'mixed';
    text?: string;
    media?: MediaAttachment[];
  };
  status: 'pending' | 'sent' | 'delivered' | 'read' | 'failed';
  direction: 'inbound' | 'outbound';
  timestamp: string;
  readAt?: string;
  deliveredAt?: string;
}

Error Handling

import { TextMeError, AuthenticationError, RateLimitError } from 'textme-unofficial-api';

try {
  await client.connect();
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid credentials');
  } else if (error instanceof RateLimitError) {
    console.error(`Rate limited. Retry after ${error.retryAfter}ms`);
  } else if (error instanceof TextMeError) {
    console.error(`API error: ${error.code} - ${error.message}`);
  }
}

Token Persistence

To avoid logging in every time, save and restore tokens:

import { TextMeClient } from 'textme-unofficial-api';
import fs from 'fs/promises';

// First time: login and save tokens
const client = new TextMeClient({
  credentials: { email, password }
});
const session = await client.connect();

await fs.writeFile('tokens.json', JSON.stringify(session.tokens));

// Later: restore from saved tokens
const savedTokens = JSON.parse(await fs.readFile('tokens.json', 'utf-8'));

const client2 = new TextMeClient({
  tokens: savedTokens
});
await client2.connect();

⚠️ Disclaimer

This is an unofficial, reverse-engineered API client. By using this library, you acknowledge:

  1. No Affiliation: This project is not affiliated with TextMe Inc.
  2. Terms of Service: Using this library may violate TextMe's Terms of Service
  3. No Warranty: This library is provided "as is" without warranty of any kind
  4. Breakage Risk: TextMe may change their internal APIs at any time, breaking this library
  5. Account Risk: Your TextMe account could be suspended for using unofficial clients
  6. Legal Risk: You are responsible for how you use this library

Use responsibly and at your own risk.

License

MIT


This library was created for educational purposes. Please respect TextMe's services and their users.