Article-22388-Telegram-Voic.../telegram_trading_bot.py

194 lines
6.5 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
import os, sys, warnings
# ========== FORCE FFMPEG PATH (NO WARNING) ==========
FFMPEG_DIR = r"C:\Users\inter\AppData\Local\Microsoft\WinGet\Packages\Gyan.FFmpeg_Microsoft.Winget.Source_8wekyb3d8bbwe\ffmpeg-8.1.1-full_build\bin"
os.environ["PATH"] = FFMPEG_DIR + os.pathsep + os.environ.get("PATH", "")
os.environ["PYDUB_FFMPEG"] = os.path.join(FFMPEG_DIR, "ffmpeg.exe")
warnings.filterwarnings("ignore", category=RuntimeWarning, module="pydub.utils")
# Monkey-patch pydub's which()
from pydub.utils import which
_original_which = which
def _forced_which(prog):
if prog in ('ffmpeg', 'avconv'):
return os.environ["PYDUB_FFMPEG"]
return _original_which(prog)
import pydub.utils
pydub.utils.which = _forced_which
import pydub
pydub.AudioSegment.converter = os.environ["PYDUB_FFMPEG"]
# Other imports
import json, time, asyncio, threading
from http.server import HTTPServer, BaseHTTPRequestHandler
from telegram import Update
from telegram.ext import Application, MessageHandler, filters, ContextTypes
import speech_recognition as sr
# ==================== CONFIG ====================
TELEGRAM_TOKEN = "REPLACE WITH YOUR BOT TOKEN"
ALLOWED_CHAT_ID = 000000000 #REPLACE WITH YOUR CHAT ID
HTTP_PORT = 8082
command_queue = []
queue_lock = threading.Lock()
result = None
result_event = threading.Event()
# ==================== HTTP SERVER ====================
class CommandHandler(BaseHTTPRequestHandler):
def log_message(self, format, *args):
pass
def do_GET(self):
if self.path == '/get_command':
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
with queue_lock:
if command_queue:
cmd = command_queue.pop(0)
self.wfile.write(json.dumps(cmd).encode())
print(f"Served: {cmd}")
else:
self.wfile.write(json.dumps({"action": None}).encode())
else:
self.send_response(404)
def do_POST(self):
if self.path == '/post_response':
length = int(self.headers.get('Content-Length', 0))
raw = self.rfile.read(length)
try:
data_str = raw.decode('utf-8').strip().rstrip('\x00')
global result
result = json.loads(data_str)
result_event.set()
print(f"Result: {result}")
except Exception as e:
print(f"POST error: {e}")
self.send_response(200)
self.end_headers()
else:
self.send_response(404)
def start_http_server():
server = HTTPServer(('127.0.0.1', HTTP_PORT), CommandHandler)
print(f"✅ HTTP server on {HTTP_PORT}")
server.serve_forever()
# ==================== AUDIO ====================
def transcribe_audio(wav_path):
recognizer = sr.Recognizer()
with sr.AudioFile(wav_path) as src:
recognizer.adjust_for_ambient_noise(src, 0.5)
audio = recognizer.record(src)
try:
return recognizer.recognize_google(audio).lower()
except:
return ""
def parse_command(text):
text = text.lower().strip()
if "close all" in text:
return {"action": "CLOSE_ALL"}
if "balance" in text:
return {"action": "BALANCE"}
action = None
if text.startswith("buy"):
action = "BUY"
text = text[3:].strip()
elif text.startswith("sell"):
action = "SELL"
text = text[4:].strip()
else:
return None
# ✅ DEFAULT LOT SIZE = 0.001 (micro lot, ~$117 for EURUSD)
volume = 0.001
words = text.split()
for i, w in enumerate(words):
if w == "half":
volume = 0.5
words.pop(i)
break
elif w in ["one", "a"]:
volume = 1.0
words.pop(i)
break
else:
try:
volume = float(w)
words.pop(i)
break
except:
pass
sym_text = " ".join(words)
m = {"gold": "XAUUSD", "euro": "EURUSD", "pound": "GBPUSD", "silver": "XAGUSD", "oil": "USOIL"}
symbol = "EURUSD"
for k, v in m.items():
if k in sym_text:
symbol = v
break
return {"action": action, "symbol": symbol, "volume": volume}
def cleanup(*files):
for f in files:
if os.path.exists(f):
try:
os.remove(f)
except:
pass
async def handle_voice(update, context):
if update.effective_chat.id != ALLOWED_CHAT_ID:
await update.message.reply_text("Unauthorized")
return
await update.message.reply_text("🎤 Processing...")
voice = await update.message.voice.get_file()
ogg, wav = "temp.ogg", "temp.wav"
try:
await voice.download_to_drive(ogg)
audio = pydub.AudioSegment.from_ogg(ogg)
audio = audio.set_frame_rate(16000).set_channels(1)
audio.export(wav, format="wav")
text = transcribe_audio(wav)
if not text:
await update.message.reply_text("❌ Could not understand")
return
await update.message.reply_text(f"📝 Heard: {text}")
cmd = parse_command(text)
if not cmd:
await update.message.reply_text("❌ Invalid command. Example: 'buy 0.001 euro'")
return
with queue_lock:
command_queue.append(cmd)
await update.message.reply_text("⏳ Sending to MT5...")
global result
result = None
result_event.clear()
if result_event.wait(timeout=10):
if result and result.get("status") == "success":
msg = f"✅ Success!\nTicket: {result['ticket']}\nPrice: {result['price']}"
else:
msg = f"❌ Error: {result.get('message') if result else 'Unknown'}"
else:
msg = "⏰ No response from MT5. Is EA running?"
await update.message.reply_text(msg)
except Exception as e:
await update.message.reply_text(f"{str(e)[:100]}")
finally:
cleanup(ogg, wav)
async def error_handler(update, context):
print(f"Telegram error: {context.error}")
def main():
threading.Thread(target=start_http_server, daemon=True).start()
app = Application.builder().token(TELEGRAM_TOKEN).build()
app.add_handler(MessageHandler(filters.VOICE, handle_voice))
app.add_error_handler(error_handler)
print("✅ Telegram bot polling...")
app.run_polling()
if __name__ == "__main__":
main()