claude-code-remote-remake/claude-hook-notify.js

168 lines
6.3 KiB
JavaScript
Raw Permalink Normal View History

Telegram&Line support (#17) * feat: Add LINE and Telegram messaging support This major enhancement extends Claude Code Remote with multi-platform messaging support: ## 🚀 New Features ### LINE Messaging Support - LINE Bot API integration with token-based commands - Secure webhook handler with signature verification - Session management with 24-hour expiration - Support for both individual and group chats - User/Group ID whitelist security ### Telegram Bot Support - Telegram Bot API with interactive buttons - Slash command support (/cmd TOKEN command) - Callback query handling for better UX - Group and private chat support - Chat ID-based authorization ### Multi-Platform Architecture - Unified notification system supporting all platforms - Platform-agnostic session management - Configurable channel enabling/disabling - Parallel webhook server support ## 🛠️ Technical Implementation ### Core Components - `src/channels/line/` - LINE messaging implementation - `src/channels/telegram/` - Telegram bot implementation - `src/utils/controller-injector.js` - Command injection utility - Multi-platform webhook servers with Express.js ### Configuration & Documentation - Updated `.env.example` with all platform options - Comprehensive setup guides for each platform - Testing guide with ngrok instructions - Updated README with multi-platform support ### Developer Experience - npm scripts for easy platform startup - Unified webhook launcher (`start-all-webhooks.js`) - Individual platform launchers - Enhanced error handling and logging ## 🔧 Usage Examples **Telegram:** `/cmd ABC12345 analyze this code` **LINE:** `Token ABC12345 analyze this code` **Email:** Reply to notification emails ## 📋 Backward Compatibility - All existing email functionality preserved - Configuration migration path provided - No breaking changes to existing hooks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: Complete Telegram Remote Control System with Direct Chat Mode ### 🚀 Major Features Added - **Direct Chat Mode**: Users can chat with Claude naturally without /cmd tokens - **Smart Monitoring**: Intelligent response detection with historical processing - **One-Click Startup**: Complete system management via startup script - **Auto-Notification**: Real-time Claude response detection and Telegram delivery ### 📱 Telegram Integration - `telegram-direct-mode.js`: Direct conversation interface - `telegram-polling.js`: Command polling with token validation - Enhanced notification system with markdown formatting ### 🧠 Smart Monitoring System - `smart-monitor.js`: Advanced response detection with history awareness - `simple-monitor.js`: Lightweight monitoring alternative - `auto-notification-daemon.js`: Background notification service ### 🛠️ System Management - `start-telegram-claude.sh`: Complete service management script - Environment validation and dependency checking - Color-coded status reporting and log management - Process lifecycle management (start/stop/restart/status) ### 📖 Documentation & Testing - `TELEGRAM_CLAUDE_GUIDE.md`: Comprehensive user guide - Complete test suite for all components - Usage examples and troubleshooting guide ### 🔧 Core Improvements - Enhanced `controller-injector.js` with proper Enter key handling - Updated `tmux-monitor.js` with real-time output monitoring - Improved error handling and logging throughout - Session management with automatic cleanup ### 🎯 Key Capabilities - **Seamless Communication**: Direct Telegram ⟷ Claude integration - **Full Automation**: No manual intervention required - **Robust Monitoring**: Never miss Claude responses - **Easy Deployment**: Single script startup and management - **Multi-Modal Support**: Ready for LINE integration expansion ### 📊 System Architecture ``` User → Telegram Bot → Direct Injection → Claude Session → Smart Monitor → Auto Notification → User ``` This completes the transformation from email-based to messaging-app-based remote Claude control, providing a modern, efficient, and user-friendly interface for remote AI interaction. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: Enhance documentation and smart monitoring system - Add comprehensive CLAUDE.md for Claude Code development guidance - Update README.md with multi-platform focus and improved instructions - Enhance smart-monitor.js with auto-approval for tool permissions - Improve start-telegram-claude.sh with better tmux session management - Add auto-approver.js for automated tool permission handling Key improvements: - Multi-platform documentation (Telegram, LINE, Email, Local) - Enhanced troubleshooting and command reference sections - Smart monitoring with historical response detection - Automated tool permission approval workflow - Better tmux integration and session management 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Add CLAUDE.md to .gitignore and remove from tracking - Add CLAUDE.md to .gitignore under "Claude Code development files" section - Remove CLAUDE.md from git tracking while preserving local file - CLAUDE.md should remain as local development documentation only 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: Complete Telegram integration with multi-channel notifications - ✅ Enhanced Telegram bot with smart buttons for personal/group chats - ✅ Multi-channel notification system (Desktop, Telegram, Email, LINE) - ✅ Smart sound alerts with customizable audio feedback - ✅ Real-time command injection with tmux session management - ✅ Intelligent session detection and conversation content extraction - ✅ Unified README documentation with complete setup guides - 🧹 Clean up legacy files and consolidate documentation - 📱 Add setup scripts for easy Telegram configuration - 🔧 Enhance webhook system with improved error handling 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Update processed messages --------- Co-authored-by: laihenyi <henyi@henyi.org> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: laihenyi <laihenyi@users.noreply.github.com>
2025-08-02 04:21:26 +08:00
#!/usr/bin/env node
/**
* Claude Hook Notification Script
* Called by Claude Code hooks to send Telegram notifications
*/
const path = require('path');
const fs = require('fs');
const dotenv = require('dotenv');
// Load environment variables from the project directory
const projectDir = path.dirname(__filename);
const envPath = path.join(projectDir, '.env');
console.log('🔍 Hook script started from:', process.cwd());
console.log('📁 Script location:', __filename);
console.log('🔧 Looking for .env at:', envPath);
if (fs.existsSync(envPath)) {
console.log('✅ .env file found, loading...');
dotenv.config({ path: envPath });
} else {
console.error('❌ .env file not found at:', envPath);
console.log('📂 Available files in script directory:');
try {
const files = fs.readdirSync(projectDir);
console.log(files.join(', '));
} catch (error) {
console.error('Cannot read directory:', error.message);
}
process.exit(1);
}
const TelegramChannel = require('./src/channels/telegram/telegram');
const DesktopChannel = require('./src/channels/local/desktop');
const EmailChannel = require('./src/channels/email/smtp');
async function sendHookNotification() {
try {
console.log('🔔 Claude Hook: Sending notifications...');
// Get notification type from command line argument
const notificationType = process.argv[2] || 'completed';
const channels = [];
const results = [];
// Configure Desktop channel (always enabled for sound)
const desktopChannel = new DesktopChannel({
completedSound: 'Glass',
waitingSound: 'Tink'
});
channels.push({ name: 'Desktop', channel: desktopChannel });
// Configure Telegram channel if enabled
if (process.env.TELEGRAM_ENABLED === 'true' && process.env.TELEGRAM_BOT_TOKEN) {
const telegramConfig = {
botToken: process.env.TELEGRAM_BOT_TOKEN,
chatId: process.env.TELEGRAM_CHAT_ID,
groupId: process.env.TELEGRAM_GROUP_ID
};
if (telegramConfig.botToken && (telegramConfig.chatId || telegramConfig.groupId)) {
const telegramChannel = new TelegramChannel(telegramConfig);
channels.push({ name: 'Telegram', channel: telegramChannel });
}
}
// Configure Email channel if enabled
if (process.env.EMAIL_ENABLED === 'true' && process.env.SMTP_USER) {
const emailConfig = {
smtp: {
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT),
secure: process.env.SMTP_SECURE === 'true',
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS
}
},
from: process.env.EMAIL_FROM,
fromName: process.env.EMAIL_FROM_NAME,
to: process.env.EMAIL_TO
};
if (emailConfig.smtp.host && emailConfig.smtp.auth.user && emailConfig.to) {
const emailChannel = new EmailChannel(emailConfig);
channels.push({ name: 'Email', channel: emailChannel });
}
}
// Get current working directory and tmux session
const currentDir = process.cwd();
const projectName = path.basename(currentDir);
// Try to get current tmux session
let tmuxSession = process.env.TMUX_SESSION || 'claude-real';
try {
const { execSync } = require('child_process');
const sessionOutput = execSync('tmux display-message -p "#S"', {
encoding: 'utf8',
stdio: ['ignore', 'pipe', 'ignore']
}).trim();
if (sessionOutput) {
tmuxSession = sessionOutput;
}
} catch (error) {
// Not in tmux or tmux not available, use default
}
// Create notification
const notification = {
type: notificationType,
title: `Claude ${notificationType === 'completed' ? 'Task Completed' : 'Waiting for Input'}`,
message: `Claude has ${notificationType === 'completed' ? 'completed a task' : 'is waiting for input'}`,
project: projectName
// Don't set metadata here - let TelegramChannel extract real conversation content
};
console.log(`📱 Sending ${notificationType} notification for project: ${projectName}`);
console.log(`🖥️ Tmux session: ${tmuxSession}`);
// Send notifications to all configured channels
for (const { name, channel } of channels) {
try {
console.log(`📤 Sending to ${name}...`);
const result = await channel.send(notification);
results.push({ name, success: result });
if (result) {
console.log(`${name} notification sent successfully!`);
} else {
console.log(`❌ Failed to send ${name} notification`);
}
} catch (error) {
console.error(`${name} notification error:`, error.message);
results.push({ name, success: false, error: error.message });
}
}
// Report overall results
const successful = results.filter(r => r.success).length;
const total = results.length;
if (successful > 0) {
console.log(`\n✅ Successfully sent notifications via ${successful}/${total} channels`);
if (results.some(r => r.name === 'Telegram' && r.success)) {
console.log('📋 You can now send new commands via Telegram');
}
} else {
console.log('\n❌ All notification channels failed');
process.exit(1);
}
} catch (error) {
console.error('❌ Hook notification error:', error.message);
process.exit(1);
}
}
// Show usage if no arguments
if (process.argv.length < 2) {
console.log('Usage: node claude-hook-notify.js [completed|waiting]');
process.exit(1);
}
sendHookNotification();