120 lines
4.4 KiB
Python
120 lines
4.4 KiB
Python
import os
|
|
import logging
|
|
import httpx
|
|
import asyncio
|
|
from telegram import Update
|
|
from telegram.ext import ApplicationBuilder, ContextTypes, MessageHandler, filters
|
|
from dotenv import load_dotenv
|
|
|
|
# Carrega as variáveis do arquivo .env
|
|
load_dotenv()
|
|
|
|
# Configurações obtidas do .env
|
|
TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
|
|
ALLOWED_USER_ID = os.getenv("TELEGRAM_CHAT_ID")
|
|
API_BASE_URL = "http://localhost:8001"
|
|
|
|
# O ID permitido deve ser comparado como string ou int, padronizando aqui
|
|
if ALLOWED_USER_ID:
|
|
ALLOWED_USER_ID = int(ALLOWED_USER_ID)
|
|
|
|
# Configuração de Logs
|
|
logging.basicConfig(
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
level=logging.INFO
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Dicionário global para manter o histórico (Em um sistema de produção, usar Redis ou DB)
|
|
chat_histories = {}
|
|
|
|
async def call_antigravity_api(endpoint: str, payload: dict) -> str:
|
|
"""Faz a chamada para a API interna do BotVPS."""
|
|
async with httpx.AsyncClient(timeout=120.0) as client:
|
|
try:
|
|
logger.info(f"Enviando payload para {endpoint}: {payload.get('text', payload.get('task'))}")
|
|
response = await client.post(f"{API_BASE_URL}{endpoint}", json=payload)
|
|
response.raise_for_status()
|
|
data = response.json()
|
|
|
|
# Tenta extrair a resposta de diferentes formatos possíveis
|
|
reply = data.get("reply") or data.get("message") or str(data)
|
|
return reply
|
|
except Exception as e:
|
|
logger.error(f"Erro ao chamar API Antigravity: {str(e)}")
|
|
return f"❌ *Erro na API:* {str(e)}"
|
|
|
|
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
"""Manipulador central de mensagens."""
|
|
if not update.message or not update.message.text:
|
|
return
|
|
|
|
chat_id = update.effective_chat.id
|
|
user_id = update.effective_user.id
|
|
|
|
# Filtro de Segurança
|
|
if ALLOWED_USER_ID and user_id != ALLOWED_USER_ID:
|
|
logger.warning(f"Acesso negado para o ID: {user_id}. Esperado: {ALLOWED_USER_ID}")
|
|
return
|
|
|
|
text = update.message.text
|
|
logger.info(f"Mensagem recebida de {user_id}: {text}")
|
|
|
|
# Inicializa histórico se não existir
|
|
if chat_id not in chat_histories:
|
|
chat_histories[chat_id] = []
|
|
|
|
# Diferenciação entre comandos de sistema e conhecimento geral
|
|
if text.startswith(('/bash', '/vps', '/cmd')):
|
|
# Comandos de sistema geralmente não precisam de histórico de chat natural
|
|
task = text.replace('/bash', '').replace('/vps', '').replace('/cmd', '').strip()
|
|
|
|
if not task:
|
|
await update.message.reply_text("❓ Por favor, envie o comando após o prefixo.")
|
|
return
|
|
|
|
await update.message.reply_text("⚙️ *Processando tarefa no Claw System...*", parse_mode='Markdown')
|
|
reply = await call_antigravity_api("/api/orchestrate", {"task": task})
|
|
else:
|
|
# Chat Natural com contexto
|
|
await context.bot.send_chat_action(chat_id=chat_id, action="typing")
|
|
|
|
# Prepara payload com histórico
|
|
payload = {
|
|
"text": text,
|
|
"history": chat_histories[chat_id][-10:] # Envia os últimos 10 turnos
|
|
}
|
|
|
|
reply = await call_antigravity_api("/api/chat", payload)
|
|
|
|
# Atualiza histórico Local
|
|
chat_histories[chat_id].append({"user": text, "bot": reply})
|
|
# Mantém apenas os últimos 15 para não crescer infinito no middleware
|
|
if len(chat_histories[chat_id]) > 15:
|
|
chat_histories[chat_id].pop(0)
|
|
|
|
# Envia a resposta de volta para o usuário
|
|
if len(reply) > 4000:
|
|
reply = reply[:3900] + "... [Texto truncado]"
|
|
|
|
try:
|
|
await update.message.reply_text(reply, parse_mode='Markdown')
|
|
except Exception as e:
|
|
logger.error(f"Erro ao enviar Markdown: {e}. Tentando texto puro.")
|
|
await update.message.reply_text(reply)
|
|
|
|
if __name__ == '__main__':
|
|
if not TOKEN:
|
|
logger.error("ERRO: TELEGRAM_BOT_TOKEN não encontrado no .env!")
|
|
exit(1)
|
|
|
|
# Inicializa o Bot (python-telegram-bot v20+)
|
|
application = ApplicationBuilder().token(TOKEN).build()
|
|
|
|
# Adiciona o handler para mensagens de texto
|
|
text_handler = MessageHandler(filters.TEXT & (~filters.COMMAND), handle_message)
|
|
application.add_handler(text_handler)
|
|
|
|
logger.info("Bot Ponte Antigravity (Middleware) iniciado e aguardando...")
|
|
application.run_polling()
|