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:
- No Affiliation: This project is not affiliated with TextMe Inc.
- Terms of Service: Using this library may violate TextMe's Terms of Service
- No Warranty: This library is provided "as is" without warranty of any kind
- Breakage Risk: TextMe may change their internal APIs at any time, breaking this library
- Account Risk: Your TextMe account could be suspended for using unofficial clients
- 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.