diff --git a/.env.example b/.env.example index 7bfee69..9b818f6 100644 --- a/.env.example +++ b/.env.example @@ -69,6 +69,10 @@ TELEGRAM_BOT_TOKEN=your-telegram-bot-token # Telegram webhook URL(您的公開 HTTPS URL) # TELEGRAM_WEBHOOK_URL=https://your-domain.com +# 強制使用 IPv4 連接 Telegram API(預設:false) +# 在某些網路環境下,IPv6 連接可能不穩定,設置為 true 可強制使用 IPv4 +# TELEGRAM_FORCE_IPV4=false + # ===== 系统配置 ===== # 会话映射文件路径 SESSION_MAP_PATH=/path/to/your/project/src/data/session-map.json diff --git a/README.md b/README.md index a503d78..ce20979 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,22 @@ TELEGRAM_WEBHOOK_URL=https://your-ngrok-url.app SESSION_MAP_PATH=/your/path/to/Claude-Code-Remote/src/data/session-map.json ``` +**Optional Telegram settings:** +```env +# Force IPv4 connections to Telegram API (default: false) +# Enable this if you experience connectivity issues with IPv6 +TELEGRAM_FORCE_IPV4=true +``` + +**Network Configuration Notes:** +- **IPv4 vs IPv6**: Some network environments may have unstable IPv6 connectivity to Telegram's API servers +- **When to use `TELEGRAM_FORCE_IPV4=true`**: + - Connection timeouts or failures when sending messages + - Inconsistent webhook delivery + - Network environments that don't properly support IPv6 +- **Default behavior**: Uses system default (usually IPv6 when available, fallback to IPv4) +- **Performance impact**: Minimal - only affects initial connection establishment + #### Option C: Configure LINE **Required LINE settings:** diff --git a/config/channels.json b/config/channels.json index e744f53..f5bde88 100644 --- a/config/channels.json +++ b/config/channels.json @@ -24,7 +24,8 @@ "botToken": "", "chatId": "", "groupId": "", - "whitelist": [] + "whitelist": [], + "forceIPv4": false } }, "whatsapp": { diff --git a/src/channels/telegram/telegram.js b/src/channels/telegram/telegram.js index 14ad758..fc1cc4e 100644 --- a/src/channels/telegram/telegram.js +++ b/src/channels/telegram/telegram.js @@ -41,6 +41,18 @@ class TelegramChannel extends NotificationChannel { return true; } + /** + * Generate network options for axios requests + * @returns {Object} Network options object + */ + _getNetworkOptions() { + const options = {}; + if (this.config.forceIPv4) { + options.family = 4; + } + return options; + } + _generateToken() { // Generate short Token (uppercase letters + numbers, 8 digits) const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; @@ -73,7 +85,8 @@ class TelegramChannel extends NotificationChannel { try { const response = await axios.get( - `${this.apiBaseUrl}/bot${this.config.botToken}/getMe` + `${this.apiBaseUrl}/bot${this.config.botToken}/getMe`, + this._getNetworkOptions() ); if (response.data.ok && response.data.result.username) { @@ -145,7 +158,8 @@ class TelegramChannel extends NotificationChannel { try { const response = await axios.post( `${this.apiBaseUrl}/bot${this.config.botToken}/sendMessage`, - requestData + requestData, + this._getNetworkOptions() ); this.logger.info(`Telegram message sent successfully, Session: ${sessionId}`); @@ -229,4 +243,4 @@ class TelegramChannel extends NotificationChannel { } } -module.exports = TelegramChannel; \ No newline at end of file +module.exports = TelegramChannel; diff --git a/src/channels/telegram/webhook.js b/src/channels/telegram/webhook.js index ddf855c..aca77c0 100644 --- a/src/channels/telegram/webhook.js +++ b/src/channels/telegram/webhook.js @@ -33,13 +33,25 @@ class TelegramWebhookHandler { _setupRoutes() { // Telegram webhook endpoint this.app.post('/webhook/telegram', this._handleWebhook.bind(this)); - + // Health check endpoint this.app.get('/health', (req, res) => { res.json({ status: 'ok', service: 'telegram-webhook' }); }); } + /** + * Generate network options for axios requests + * @returns {Object} Network options object + */ + _getNetworkOptions() { + const options = {}; + if (this.config.forceIPv4) { + options.family = 4; + } + return options; + } + async _handleWebhook(req, res) { try { const update = req.body; @@ -226,7 +238,8 @@ class TelegramWebhookHandler { try { const response = await axios.get( - `${this.apiBaseUrl}/bot${this.config.botToken}/getMe` + `${this.apiBaseUrl}/bot${this.config.botToken}/getMe`, + this._getNetworkOptions() ); if (response.data.ok && response.data.result.username) { @@ -277,7 +290,8 @@ class TelegramWebhookHandler { chat_id: chatId, text: text, ...options - } + }, + this._getNetworkOptions() ); } catch (error) { this.logger.error('Failed to send message:', error.response?.data || error.message); @@ -291,7 +305,8 @@ class TelegramWebhookHandler { { callback_query_id: callbackQueryId, text: text - } + }, + this._getNetworkOptions() ); } catch (error) { this.logger.error('Failed to answer callback query:', error.response?.data || error.message); @@ -305,9 +320,10 @@ class TelegramWebhookHandler { { url: webhookUrl, allowed_updates: ['message', 'callback_query'] - } + }, + this._getNetworkOptions() ); - + this.logger.info('Webhook set successfully:', response.data); return response.data; } catch (error) { @@ -323,4 +339,4 @@ class TelegramWebhookHandler { } } -module.exports = TelegramWebhookHandler; \ No newline at end of file +module.exports = TelegramWebhookHandler; diff --git a/src/core/config.js b/src/core/config.js index 815dd90..a28fa12 100644 --- a/src/core/config.js +++ b/src/core/config.js @@ -96,10 +96,12 @@ class ConfigManager { }, telegram: { type: 'chat', - enabled: false, + enabled: process.env.TELEGRAM_ENABLED === 'true', config: { - token: '', - chatId: '' + botToken: process.env.TELEGRAM_BOT_TOKEN || '', + chatId: process.env.TELEGRAM_CHAT_ID || '', + groupId: process.env.TELEGRAM_GROUP_ID || '', + forceIPv4: process.env.TELEGRAM_FORCE_IPV4 === 'true' } } };