Update Telegram Bot to v22.x API (fix import error)

Changes:
- Updated from python-telegram-bot 13.15 to 22.5
- Changed from sync API to async/await pattern
- Updated all command handlers to async
- Updated Application builder (new API)
- Fixed ModuleNotFoundError: No module named 'telegram'

Technical changes:
- Updater -> Application.builder()
- CommandHandler now uses async functions
- Context.DEFAULT_TYPE instead of CallbackContext
- await for all telegram API calls

Compatibility: python-telegram-bot 22.5 works with Python 3.12
This commit is contained in:
cbazza committed 2025-12-26 20:09:41 +01:00
1 parent ac9a8ac969
commit 9475730769
2 files changed
+605 -94

No files matched your search

+66 -94
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
🤖 TELEGRAM BOT COMMANDS - Interactive Bot Control
Erlaubt Remote-Control des Trading Bots via Telegram Commands
🤖 TELEGRAM BOT COMMANDS V2 - Interactive Bot Control
Updated for python-telegram-bot 22.x (latest version)
COMMANDS:
/status - Bot Status, offene Positionen, Balance
@@ -11,28 +11,22 @@ COMMANDS:
/stats - Performance Statistiken (heute, Woche, gesamt)
/balance - Aktueller Kontostand + Equity
/help - Liste aller Commands
USAGE:
1. In separate Cell im Notebook starten:
bot_commander = TelegramBotCommander()
bot_commander.start()
2. Oder als Background-Service:
python telegram_bot_commands.py
"""
import asyncio
import threading
import time
import json
import MetaTrader5 as mt5
from datetime import datetime, timedelta
from typing import Optional, Dict
from telegram import Update, Bot
from telegram.ext import Updater, CommandHandler, CallbackContext
import sqlite3
# New API imports for python-telegram-bot 22.x
from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes
# Import existing modules
from telegram_notifier import TelegramNotifier, load_telegram_config
from telegram_notifier import load_telegram_config
class TradingBotController:
@@ -77,12 +71,7 @@ class TradingBotController:
def close_all_positions(self) -> Dict:
"""
Schließt ALLE offenen Positionen (Emergency Exit)
Returns:
Dict mit Ergebnis
"""
"""Schließt ALLE offenen Positionen (Emergency Exit)"""
if not mt5.initialize():
return {
'success': False,
@@ -142,12 +131,7 @@ class TradingBotController:
def get_status(self) -> Dict:
"""
Holt aktuellen Bot Status
Returns:
Dict mit Status-Informationen
"""
"""Holt aktuellen Bot Status"""
if not mt5.initialize():
return {
'success': False,
@@ -238,17 +222,11 @@ class TradingBotController:
class TelegramBotCommander:
"""
Telegram Bot Command Handler
Läuft im Hintergrund und reagiert auf Commands
Telegram Bot Command Handler (python-telegram-bot 22.x)
"""
def __init__(self, config_file: str = "telegram_config.json"):
"""
Initialize Telegram Bot Commander
Args:
config_file: Path to telegram config file
"""
"""Initialize Telegram Bot Commander"""
# Load config
self.config = load_telegram_config()
@@ -258,87 +236,82 @@ class TelegramBotCommander:
self.bot_token = self.config['bot_token']
self.chat_id = self.config['chat_id']
# Initialize Bot
self.bot = Bot(token=self.bot_token)
self.updater = Updater(token=self.bot_token, use_context=True)
# Controller
self.controller = TradingBotController()
# Notifier (for sending messages)
self.notifier = TelegramNotifier(self.bot_token, self.chat_id)
# Database path
self.db_path = "trading_bot.db"
# Setup command handlers
self._setup_handlers()
# Application (new API)
self.application = None
print("✅ Telegram Bot Commander initialized")
print(f"📱 Bot Token: {self.bot_token[:20]}...")
print(f"👤 Chat ID: {self.chat_id}")
def _setup_handlers(self):
"""Setup command handlers"""
dispatcher = self.updater.dispatcher
async def start_async(self):
"""Start bot asynchronously (new API)"""
# Create application
self.application = Application.builder().token(self.bot_token).build()
# Register commands
dispatcher.add_handler(CommandHandler("start", self.cmd_start))
dispatcher.add_handler(CommandHandler("help", self.cmd_help))
dispatcher.add_handler(CommandHandler("status", self.cmd_status))
dispatcher.add_handler(CommandHandler("pause", self.cmd_pause))
dispatcher.add_handler(CommandHandler("resume", self.cmd_resume))
dispatcher.add_handler(CommandHandler("close", self.cmd_close))
dispatcher.add_handler(CommandHandler("balance", self.cmd_balance))
dispatcher.add_handler(CommandHandler("stats", self.cmd_stats))
# Add command handlers
self.application.add_handler(CommandHandler("start", self.cmd_start))
self.application.add_handler(CommandHandler("help", self.cmd_help))
self.application.add_handler(CommandHandler("status", self.cmd_status))
self.application.add_handler(CommandHandler("pause", self.cmd_pause))
self.application.add_handler(CommandHandler("resume", self.cmd_resume))
self.application.add_handler(CommandHandler("close", self.cmd_close))
self.application.add_handler(CommandHandler("balance", self.cmd_balance))
self.application.add_handler(CommandHandler("stats", self.cmd_stats))
print("✅ Command handlers registered")
def start(self):
"""Start the bot (blocking)"""
print("🚀 Starting Telegram Bot...")
print("📱 Send /help to see available commands")
# Send startup message
self.notifier.send_message(
"🤖 *Telegram Bot Commander STARTED*\n\n"
"✅ Bot is now listening for commands\n"
"Send /help for available commands"
await self.application.bot.send_message(
chat_id=self.chat_id,
text="🤖 *Telegram Bot Commander STARTED*\n\n"
"✅ Bot is now listening for commands\n"
"Send /help for available commands",
parse_mode='Markdown'
)
# Start polling
self.updater.start_polling()
print("✅ Bot is running. Press Ctrl+C to stop.")
# Initialize and start polling
await self.application.initialize()
await self.application.start()
await self.application.updater.start_polling()
# Run until interrupted
self.updater.idle()
print("✅ Bot is running")
def start_background(self):
"""Start bot in background thread"""
thread = threading.Thread(target=self.start, daemon=True)
def run_async_loop():
asyncio.run(self.start_async())
thread = threading.Thread(target=run_async_loop, daemon=True)
thread.start()
print("✅ Telegram Bot running in background")
return thread
# ==========================================
# COMMAND HANDLERS
# COMMAND HANDLERS (async in new API)
# ==========================================
def cmd_start(self, update: Update, context: CallbackContext):
async def cmd_start(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /start command"""
message = (
"🤖 *Trading Bot Commander*\n\n"
"Welcome! I can help you control your trading bot remotely.\n\n"
"Send /help to see available commands."
)
update.message.reply_text(message, parse_mode='Markdown')
await update.message.reply_text(message, parse_mode='Markdown')
def cmd_help(self, update: Update, context: CallbackContext):
async def cmd_help(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /help command"""
message = """
📚 *Available Commands*
@@ -359,28 +332,28 @@ class TelegramBotCommander:
✅ /pause is instant
🔒 Only authorized user can use commands
"""
update.message.reply_text(message, parse_mode='Markdown')
await update.message.reply_text(message, parse_mode='Markdown')
def cmd_status(self, update: Update, context: CallbackContext):
async def cmd_status(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /status command"""
result = self.controller.get_status()
update.message.reply_text(result['message'], parse_mode='Markdown')
await update.message.reply_text(result['message'], parse_mode='Markdown')
def cmd_pause(self, update: Update, context: CallbackContext):
async def cmd_pause(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /pause command"""
result = self.controller.pause_trading("Manual pause via Telegram")
update.message.reply_text(result['message'], parse_mode='Markdown')
await update.message.reply_text(result['message'], parse_mode='Markdown')
def cmd_resume(self, update: Update, context: CallbackContext):
async def cmd_resume(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /resume command"""
result = self.controller.resume_trading()
update.message.reply_text(result['message'], parse_mode='Markdown')
await update.message.reply_text(result['message'], parse_mode='Markdown')
def cmd_close(self, update: Update, context: CallbackContext):
async def cmd_close(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /close command"""
# Safety check - require confirmation
args = context.args
@@ -392,25 +365,25 @@ class TelegramBotCommander:
"To confirm, send:\n"
"`/close confirm`"
)
update.message.reply_text(message, parse_mode='Markdown')
await update.message.reply_text(message, parse_mode='Markdown')
return
# Execute close
update.message.reply_text("🚨 Closing all positions...", parse_mode='Markdown')
await update.message.reply_text("🚨 Closing all positions...", parse_mode='Markdown')
result = self.controller.close_all_positions()
update.message.reply_text(result['message'], parse_mode='Markdown')
await update.message.reply_text(result['message'], parse_mode='Markdown')
def cmd_balance(self, update: Update, context: CallbackContext):
async def cmd_balance(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /balance command"""
result = self.controller.get_balance()
update.message.reply_text(result['message'], parse_mode='Markdown')
await update.message.reply_text(result['message'], parse_mode='Markdown')
def cmd_stats(self, update: Update, context: CallbackContext):
async def cmd_stats(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /stats command"""
stats = self._get_performance_stats()
update.message.reply_text(stats, parse_mode='Markdown')
await update.message.reply_text(stats, parse_mode='Markdown')
# ==========================================
@@ -504,7 +477,6 @@ class TelegramBotCommander:
# GLOBAL CONTROLLER INSTANCE
# ==========================================
# Global instance that can be accessed from notebook
_global_controller = None
def get_bot_controller() -> TradingBotController:
@@ -516,20 +488,20 @@ def get_bot_controller() -> TradingBotController:
# ==========================================
# USAGE
# MAIN
# ==========================================
if __name__ == "__main__":
print("="*70)
print("🤖 TELEGRAM BOT COMMANDER - Starting")
print("🤖 TELEGRAM BOT COMMANDER V2 - Starting")
print("="*70)
try:
# Create bot commander
commander = TelegramBotCommander()
asyncio.run(commander.start_async())
# Start bot (blocking)
commander.start()
# Keep running
asyncio.get_event_loop().run_forever()
except KeyboardInterrupt:
print("\n⏸️ Bot stopped by user")