#!/usr/bin/env python3 """ Simple Telegram bot that forwards trade commands to n8n webhook Install: pip3 install python-telegram-bot requests Run: python3 telegram_trade_bot.py """ import os import requests from telegram import Update from telegram.ext import Application, MessageHandler, CommandHandler, filters, ContextTypes # Configuration - SET THESE! TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN', 'YOUR_BOT_TOKEN_HERE') N8N_WEBHOOK_URL = os.getenv('N8N_WEBHOOK_URL', 'https://your-n8n.com/webhook/manual-trade') TRADING_BOT_URL = os.getenv('TRADING_BOT_URL', 'http://trading-bot-v4:3000') API_SECRET_KEY = os.getenv('API_SECRET_KEY', '') ALLOWED_CHAT_ID = int(os.getenv('TELEGRAM_CHAT_ID', '579304651')) async def handle_status_command(update: Update, context: ContextTypes.DEFAULT_TYPE): """Handle /status command - show current open positions""" # Only your chat if update.message.chat_id != ALLOWED_CHAT_ID: return print(f"šŸ“Š /status command received") try: # Fetch positions from trading bot API response = requests.get( f"{TRADING_BOT_URL}/api/trading/positions", headers={'Authorization': f'Bearer {API_SECRET_KEY}'}, timeout=10 ) if not response.ok: await update.message.reply_text(f"āŒ Error fetching positions: {response.status_code}") return data = response.json() if not data.get('success'): await update.message.reply_text("āŒ Failed to fetch positions") return # Check if there are active positions positions = data.get('positions', []) if not positions: await update.message.reply_text("šŸ“Š *No open positions*\n\nAll clear! Ready for new signals.", parse_mode='Markdown') return # Format position information for pos in positions: symbol = pos['symbol'] direction = pos['direction'].upper() entry = pos['entryPrice'] current = pos['currentPrice'] size = pos['currentSize'] leverage = pos['leverage'] # P&L pnl_pct = pos['profitPercent'] account_pnl = pos['accountPnL'] unrealized_pnl = pos['unrealizedPnL'] # Targets sl = pos['stopLoss'] tp1 = pos['takeProfit1'] tp2 = pos['takeProfit2'] tp1_hit = pos['tp1Hit'] # Age age_min = pos['ageMinutes'] # Build status message emoji = "🟢" if account_pnl > 0 else "šŸ”“" if account_pnl < 0 else "⚪" direction_emoji = "šŸ“ˆ" if direction == "LONG" else "šŸ“‰" message = f"{emoji} *{symbol}* {direction_emoji} {direction}\n\n" message += f"šŸ’° *P&L:* ${unrealized_pnl:.2f} ({account_pnl:+.2f}% account)\n" message += f"šŸ“Š *Price Change:* {pnl_pct:+.2f}%\n\n" message += f"*Entry:* ${entry:.4f}\n" message += f"*Current:* ${current:.4f}\n\n" message += f"*Targets:*\n" message += f" TP1: ${tp1:.4f} {'āœ…' if tp1_hit else 'ā³'}\n" message += f" TP2: ${tp2:.4f}\n" message += f" SL: ${sl:.4f}\n\n" message += f"*Position:* ${size:.2f} @ {leverage}x\n" message += f"*Age:* {age_min} min" await update.message.reply_text(message, parse_mode='Markdown') print(f"āœ… Status sent: {len(positions)} position(s)") except Exception as e: print(f"āŒ Error: {e}") await update.message.reply_text(f"āŒ Error: {str(e)}") async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE): """Forward trade commands to n8n""" # Only your chat if update.message.chat_id != ALLOWED_CHAT_ID: return text = update.message.text.lower().strip() # Only process trade commands: buy/sell followed by symbol if not any(text.startswith(cmd) for cmd in ['buy', 'sell', 'long', 'short']): return print(f"šŸ“Ø {text}") # Forward to n8n try: response = requests.post( N8N_WEBHOOK_URL, json={'text': text}, timeout=10 ) if response.ok: print(f"āœ… Sent to n8n") else: print(f"āŒ Error {response.status_code}") await update.message.reply_text(f"āŒ Error: {response.status_code}") except Exception as e: print(f"āŒ {e}") await update.message.reply_text(f"āŒ Error: {str(e)}") def main(): """Start bot""" if TELEGRAM_BOT_TOKEN == 'YOUR_BOT_TOKEN_HERE': print("āŒ Set TELEGRAM_BOT_TOKEN environment variable") print("Example: export TELEGRAM_BOT_TOKEN='your_token'") return if N8N_WEBHOOK_URL == 'https://your-n8n.com/webhook/manual-trade': print("āŒ Set N8N_WEBHOOK_URL environment variable") print("Example: export N8N_WEBHOOK_URL='https://n8n.yourdomain.com/webhook/manual-trade'") return print(f"šŸš€ Telegram Trade Bot Starting...") print(f"šŸ“± Chat ID: {ALLOWED_CHAT_ID}") print(f"šŸ”— Webhook: {N8N_WEBHOOK_URL}") print(f"šŸ¤– Trading Bot: {TRADING_BOT_URL}") print(f"\nāœ… Commands:") print(f" /status - Show open positions") print(f"\nāœ… Trade messages:") print(f" buy sol") print(f" sell btc") print(f" buy eth") print(f" sell sol") app = Application.builder().token(TELEGRAM_BOT_TOKEN).build() app.add_handler(CommandHandler("status", handle_status_command)) app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message)) print(f"\nšŸ¤– Bot ready! Listening for commands...\n") app.run_polling(allowed_updates=Update.ALL_TYPES) if __name__ == '__main__': main()