openclaw/docs/channels/telegram-gramjs.md
spiceoogway 84c1ab4d55 feat(telegram-gramjs): Phase 1 - User account adapter with tests and docs
Implements Telegram user account support via GramJS/MTProto (#937).

## What's New
- Complete GramJS channel adapter for user accounts (not bots)
- Interactive auth flow (phone → SMS → 2FA)
- Session persistence via StringSession
- DM and group message support
- Security policies (allowFrom, dmPolicy, groupPolicy)
- Multi-account configuration

## Files Added

### Core Implementation (src/telegram-gramjs/)
- auth.ts - Interactive authentication flow
- auth.test.ts - Auth flow tests (mocked)
- client.ts - GramJS TelegramClient wrapper
- config.ts - Config adapter for multi-account
- gateway.ts - Gateway adapter (poll/send)
- handlers.ts - Message conversion (GramJS → openclaw)
- handlers.test.ts - Message conversion tests
- setup.ts - CLI setup wizard
- types.ts - TypeScript type definitions
- index.ts - Module exports

### Configuration
- src/config/types.telegram-gramjs.ts - Config schema

### Plugin Extension
- extensions/telegram-gramjs/index.ts - Plugin registration
- extensions/telegram-gramjs/src/channel.ts - Channel plugin implementation
- extensions/telegram-gramjs/openclaw.plugin.json - Plugin manifest
- extensions/telegram-gramjs/package.json - Dependencies

### Documentation
- docs/channels/telegram-gramjs.md - Complete setup guide (14KB)
- GRAMJS-PHASE1-SUMMARY.md - Implementation summary

### Registry
- src/channels/registry.ts - Added telegram-gramjs to CHAT_CHANNEL_ORDER

## Test Coverage
-  Auth flow with phone/SMS/2FA (mocked)
-  Phone number validation
-  Session verification
-  Message conversion (DM, group, reply)
-  Session key routing
-  Command extraction
-  Edge cases (empty messages, special chars)

## Features Implemented (Phase 1)
-  User account authentication via MTProto
-  DM message send/receive
-  Group message send/receive
-  Reply context preservation
-  Security policies (pairing, allowlist)
-  Multi-account support
-  Session persistence
-  Command detection

## Next Steps (Phase 2)
- Media support (photos, videos, files)
- Voice messages and stickers
- Message editing and deletion
- Reactions
- Channel messages

## Documentation Highlights
- Getting API credentials from my.telegram.org
- Interactive setup wizard walkthrough
- DM and group policies configuration
- Multi-account examples
- Rate limits and troubleshooting
- Security best practices
- Migration guide from Bot API

Closes #937 (Phase 1)
2026-01-30 03:03:15 -05:00

14 KiB

summary read_when
Telegram user account support via GramJS/MTProto - access cloud chats as your personal account
Working on Telegram user account features
Need access to personal DMs and groups
Want to use Telegram without creating a bot

Telegram (GramJS / User Account)

Status: Beta (Phase 1 complete - DMs and groups)

Connect openclaw to your personal Telegram account using GramJS (MTProto protocol). This allows the agent to access your DMs, groups, and channels as you — no bot required.

Quick Setup

  1. Get API credentials from https://my.telegram.org/apps

    • api_id (integer)
    • api_hash (string)
  2. Run the setup wizard:

    openclaw setup telegram-gramjs
    
  3. Follow the prompts:

    • Enter your phone number (format: +12025551234)
    • Enter SMS verification code
    • Enter 2FA password (if enabled on your account)
  4. Done! The session is saved to your config file.

What It Is

  • A user account channel (not a bot)
  • Uses GramJS (JavaScript implementation of Telegram's MTProto protocol)
  • Access to all your chats: DMs, groups, channels (as yourself)
  • Session persistence via encrypted StringSession
  • Routing rules: DMs → main session, Groups → isolated sessions

When to Use GramJS vs Bot API

Feature GramJS (User Account) Bot API (grammY)
Access Your personal account Separate bot account
DMs All your DMs Only DMs to the bot
Groups All your groups Only groups with bot added
Channels Subscribed channels Not supported
Read History Full message history Only new messages
Setup API credentials + phone auth Bot token from @BotFather
Privacy You are the account Separate bot identity
Rate Limits Strict (user account limits) More lenient (bot limits)

Use GramJS when:

  • You want the agent to access your personal Telegram
  • You need full chat history access
  • You want to avoid creating a separate bot

Use Bot API when:

  • You want a separate bot identity
  • You need webhook support (not yet in GramJS)
  • You prefer simpler setup (just a token)

Configuration

Basic Setup (Single Account)

{
  channels: {
    telegramGramjs: {
      enabled: true,
      apiId: 123456,
      apiHash: "your_api_hash_here",
      phoneNumber: "+12025551234",
      sessionString: "encrypted_session_data",
      dmPolicy: "pairing",
      groupPolicy: "open"
    }
  }
}

Multi-Account Setup

{
  channels: {
    telegramGramjs: {
      enabled: true,
      accounts: {
        personal: {
          name: "Personal Account",
          apiId: 123456,
          apiHash: "hash1",
          phoneNumber: "+12025551234",
          sessionString: "session1",
          dmPolicy: "pairing"
        },
        work: {
          name: "Work Account",
          apiId: 789012,
          apiHash: "hash2",
          phoneNumber: "+15551234567",
          sessionString: "session2",
          dmPolicy: "allowlist",
          allowFrom: ["+15559876543"]
        }
      }
    }
  }
}

Environment Variables

You can set credentials via environment variables:

export TELEGRAM_API_ID=123456
export TELEGRAM_API_HASH=your_api_hash
export TELEGRAM_SESSION_STRING=your_encrypted_session

Note: Config file values take precedence over environment variables.

Getting API Credentials

  1. Go to https://my.telegram.org/apps
  2. Log in with your phone number
  3. Click "API Development Tools"
  4. Fill out the form:
    • App title: openclaw
    • Short name: openclaw-gateway
    • Platform: Other
    • Description: Personal agent gateway
  5. Click "Create application"
  6. Save your api_id and api_hash

Important notes:

  • api_id and api_hash are NOT secrets — they identify your app, not your account
  • The session string is the secret — keep it encrypted and secure
  • You can use the same API credentials for multiple phone numbers

Authentication Flow

The interactive setup wizard (openclaw setup telegram-gramjs) handles:

1. Phone Number

Enter your phone number (format: +12025551234): +12025551234

Format rules:

  • Must start with +
  • Country code required
  • 10-15 digits total
  • Example: +12025551234 (US), +442071234567 (UK)

2. SMS Code

📱 A verification code has been sent to your phone via SMS.
Enter the verification code: 12345

Telegram will send a 5-digit code to your phone.

3. Two-Factor Authentication (if enabled)

🔒 Your account has Two-Factor Authentication enabled.
Enter your 2FA password: ********

Only required if you have 2FA enabled on your Telegram account.

4. Session Saved

✅ Authentication successful!
Session string generated. This will be saved to your config.

The encrypted session string is saved to your config file.

Session Management

Session Persistence

After successful authentication, a StringSession is generated and saved:

{
  sessionString: "encrypted_base64_session_data"
}

This session remains valid until:

  • You explicitly log out via Telegram settings
  • Telegram detects suspicious activity
  • You hit the max concurrent sessions limit (~10)

Session Security

⚠️ IMPORTANT: Session strings are sensitive credentials!

  • Session strings grant full access to your account
  • Store them encrypted (openclaw does this automatically)
  • Never commit session strings to git
  • Never share session strings with anyone

If a session is compromised:

  1. Go to Telegram Settings → Privacy → Active Sessions
  2. Terminate the suspicious session
  3. Re-run openclaw setup telegram-gramjs to create a new session

Session File Storage (Alternative)

Instead of storing in config, you can use a session file:

{
  sessionFile: "~/.config/openclaw/sessions/telegram-personal.session"
}

The file will be encrypted automatically.

DM Policies

Control who can send DMs to your account:

{
  dmPolicy: "pairing",  // "pairing", "open", "allowlist", "closed"
  allowFrom: ["+12025551234", "@username", "123456789"]
}
Policy Behavior
pairing First contact requires approval (default)
open Accept DMs from anyone
allowlist Only accept from allowFrom list
closed Reject all DMs

Group Policies

Control how the agent responds in groups:

{
  groupPolicy: "open",  // "open", "allowlist", "closed"
  groupAllowFrom: ["@groupusername", "-100123456789"],
  groups: {
    "-100123456789": {  // Specific group ID
      requireMention: true,
      allowFrom: ["@alice", "@bob"]
    }
  }
}

Group Settings

  • requireMention: Only respond when mentioned (default: true)
  • allowFrom: Allowlist of users who can trigger the agent
  • autoReply: Enable auto-reply in this group

Group IDs

GramJS uses Telegram's internal group IDs:

  • Format: -100{channel_id} (e.g., -1001234567890)
  • Find group ID: Send a message in the group, check logs for chatId

Message Routing

DM Messages

telegram-gramjs:{accountId}:{senderId}

Routes to the main agent session (shared history with this user).

Group Messages

telegram-gramjs:{accountId}:group:{groupId}

Routes to an isolated session per group (separate context).

Channel Messages

Not yet supported. Channel messages are skipped in Phase 1.

Features

Supported (Phase 1)

  • DM messages (send and receive)
  • Group messages (send and receive)
  • Reply context (reply to specific messages)
  • Text messages
  • Command detection (/start, /help, etc.)
  • Session persistence
  • Multi-account support
  • Security policies (allowFrom, dmPolicy, groupPolicy)

Coming Soon (Phase 2)

  • Media support (photos, videos, files)
  • Voice messages
  • Stickers and GIFs
  • Reactions
  • Message editing and deletion
  • Forward detection

Future (Phase 3)

  • Channel messages
  • Secret chats
  • Poll creation
  • Inline queries
  • Custom entity parsing (mentions, hashtags, URLs)

Rate Limits

Telegram has strict rate limits for user accounts:

  • ~20 messages per minute per chat
  • ~40-50 messages per minute globally
  • Flood wait errors trigger cooldown (can be minutes or hours)

Best practices:

  • Don't spam messages rapidly
  • Respect FLOOD_WAIT errors (the client will auto-retry)
  • Use batching for multiple messages
  • Consider using Bot API for high-volume scenarios

Troubleshooting

"API_ID_INVALID" or "API_HASH_INVALID"

"PHONE_NUMBER_INVALID"

  • Phone number must start with +
  • Include country code
  • Remove spaces and dashes
  • Example: +12025551234

"SESSION_PASSWORD_NEEDED"

  • Your account has 2FA enabled
  • Enter your 2FA password when prompted
  • Check Telegram Settings → Privacy → Two-Step Verification

"AUTH_KEY_UNREGISTERED"

  • Your session expired or was terminated
  • Re-run openclaw setup telegram-gramjs to re-authenticate

"FLOOD_WAIT_X"

  • You hit Telegram's rate limit
  • Wait X seconds before retrying
  • GramJS handles this automatically with exponential backoff

Connection Issues

  • Check internet connection
  • Verify Telegram isn't blocked on your network
  • Try restarting the gateway
  • Check logs: openclaw logs --channel=telegram-gramjs

Session Lost After Restart

  • Ensure sessionString is saved in config
  • Check file permissions on config file
  • Verify encryption key is consistent

Security Best Practices

Do

  • Store session strings encrypted
  • Use dmPolicy: "pairing" for new contacts
  • Use allowFrom to restrict access
  • Regularly review active sessions in Telegram
  • Use separate accounts for different purposes
  • Enable 2FA on your Telegram account

Don't

  • Share session strings publicly
  • Commit session strings to git
  • Use groupPolicy: "open" in public groups
  • Run on untrusted servers
  • Reuse API credentials across multiple machines

Migration from Bot API

If you're currently using the Telegram Bot API (telegram channel), you can run both simultaneously:

{
  channels: {
    // Bot API (existing)
    telegram: {
      enabled: true,
      botToken: "123:abc"
    },
    
    // GramJS (new)
    telegramGramjs: {
      enabled: true,
      apiId: 123456,
      apiHash: "hash"
    }
  }
}

Routing:

  • Bot token messages → telegram channel
  • User account messages → telegram-gramjs channel
  • No conflicts (separate accounts, separate sessions)

Examples

Personal Assistant Setup

{
  channels: {
    telegramGramjs: {
      enabled: true,
      apiId: 123456,
      apiHash: "your_hash",
      phoneNumber: "+12025551234",
      dmPolicy: "pairing",
      groupPolicy: "closed",  // No groups
      sessionString: "..."
    }
  }
}

Team Bot in Groups

{
  channels: {
    telegramGramjs: {
      enabled: true,
      apiId: 123456,
      apiHash: "your_hash",
      phoneNumber: "+12025551234",
      dmPolicy: "closed",  // No DMs
      groupPolicy: "allowlist",
      groupAllowFrom: [
        "-1001234567890",  // Team group
        "-1009876543210"   // Project group
      ],
      groups: {
        "-1001234567890": {
          requireMention: true,
          allowFrom: ["@alice", "@bob"]
        }
      }
    }
  }
}

Multi-Account with Family + Work

{
  channels: {
    telegramGramjs: {
      enabled: true,
      accounts: {
        family: {
          name: "Family Account",
          apiId: 123456,
          apiHash: "hash1",
          phoneNumber: "+12025551234",
          dmPolicy: "allowlist",
          allowFrom: ["+15555551111", "+15555552222"],  // Family members
          groupPolicy: "closed"
        },
        work: {
          name: "Work Account",
          apiId: 789012,
          apiHash: "hash2",
          phoneNumber: "+15551234567",
          dmPolicy: "allowlist",
          allowFrom: ["@boss", "@coworker1"],
          groupPolicy: "allowlist",
          groupAllowFrom: ["-1001111111111"]  // Work group
        }
      }
    }
  }
}

Advanced Configuration

Connection Settings

{
  connectionRetries: 5,
  connectionTimeout: 30000,  // 30 seconds
  floodSleepThreshold: 60,   // Auto-sleep on flood wait < 60s
  useIPv6: false,
  deviceModel: "openclaw",
  systemVersion: "1.0.0",
  appVersion: "1.0.0"
}

Message Settings

{
  historyLimit: 100,          // Max messages to fetch on poll
  mediaMaxMb: 10,             // Max media file size (Phase 2)
  textChunkLimit: 4096        // Max text length per message
}

Capabilities

{
  capabilities: [
    "sendMessage",
    "receiveMessage",
    "replyToMessage",
    "deleteMessage",      // Phase 2
    "editMessage",        // Phase 2
    "sendMedia",          // Phase 2
    "downloadMedia"       // Phase 2
  ]
}

Logs and Debugging

Enable Debug Logs

export DEBUG=telegram-gramjs:*
openclaw gateway start

Check Session Status

openclaw status telegram-gramjs

View Recent Messages

openclaw logs --channel=telegram-gramjs --limit=50

References

Support

For issues specific to the GramJS channel:


Last Updated: 2026-01-30
Version: Phase 1 (Beta)
Tested Platforms: macOS, Linux
Dependencies: GramJS 2.24.15+, Node.js 18+