Add Telegram as a third messaging provider alongside web and twilio. Core Features: - Interactive login flow with phone/SMS/2FA authentication - Send text and media messages (images, videos, audio, documents) - Monitor incoming messages with auto-reply support - Session management at ~/.clawdis/telegram/session/ - Full CLI integration (login, logout, status, send, relay commands) Implementation Details: - Uses telegram npm package for MTProto API access - Supports both URL and local file media sending - Cross-platform path handling (Windows/Unix) - Optional Twilio env vars (supports Telegram-only usage) - Minimal provider abstraction pattern - Comprehensive test coverage (440 tests passing) Changes: - Add Telegram module (client, login, monitor, inbound, outbound, session) - Add provider factory and base interfaces - Wire Telegram functions into CLI deps - Update env validation to make Twilio fields optional - Add telegram to all CLI commands (login, logout, status, send, relay) - Add null checks in Twilio code for optional env fields - Fix send command to properly load session and connect - Add local file support with cross-platform path handling - Update login message to show correct ~/.clawdis path - Add comprehensive tests and documentation Basic Usage: warelay login --provider telegram warelay send --provider telegram --to "@user" --message "Hi" warelay send --provider telegram --to "@user" --media "/path/to/file.jpg" warelay relay --provider telegram All tests pass (63 files, 440 tests). Zero TypeScript errors.
49 lines
1.3 KiB
TypeScript
49 lines
1.3 KiB
TypeScript
import type { Api, TelegramClient } from "telegram";
|
|
|
|
// Entity type - can be User, Chat, Channel, or their empty variants
|
|
type Entity = Api.User | Api.Chat | Api.Channel;
|
|
|
|
/**
|
|
* Resolve Telegram entity (user/chat) from identifier.
|
|
* Supports @username, phone number, or user ID.
|
|
*/
|
|
export async function resolveEntity(
|
|
client: TelegramClient,
|
|
identifier: string,
|
|
): Promise<Entity> {
|
|
// Clean identifier
|
|
const clean = identifier.trim();
|
|
|
|
// Try as-is first (handles @username, phone, user ID)
|
|
try {
|
|
return (await client.getEntity(clean)) as Entity;
|
|
} catch (_firstErr) {
|
|
// If not @ prefix, try adding it
|
|
if (!clean.startsWith("@")) {
|
|
try {
|
|
return (await client.getEntity(`@${clean}`)) as Entity;
|
|
} catch {
|
|
// Fall through to error
|
|
}
|
|
}
|
|
|
|
throw new Error(
|
|
`Could not resolve Telegram entity: ${identifier}. ` +
|
|
"Use @username, phone number (+1234567890), or user ID.",
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Extract user ID from entity as string to avoid precision loss.
|
|
* Telegram IDs are bigint and can exceed Number.MAX_SAFE_INTEGER.
|
|
*/
|
|
export function extractUserId(entity: Entity): string {
|
|
// Extract ID as unknown to bypass TypeScript's overly narrow type inference
|
|
const id = ("id" in entity ? entity.id : null) as unknown;
|
|
if (typeof id === "bigint") {
|
|
return id.toString();
|
|
}
|
|
return "0";
|
|
}
|