from dotenv import load_dotenv import os import random import requests import openai import schedule import time from datetime import datetime from database import init_db, save_insight load_dotenv() TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN") TELEGRAM_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID") DEFAULT_AI_PROVIDER = os.getenv("DEFAULT_AI_PROVIDER", "openrouter").lower() DEFAULT_AI_MODEL = os.getenv("DEFAULT_AI_MODEL", "") OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY") LLAMACPP_BASE_URL = os.getenv("LLAMACPP_BASE_URL", "http://localhost:8080/v1/") LLAMACPP_API_KEY = os.getenv("LLAMACPP_API_KEY", "not-needed") OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") LANGUAGE = os.getenv("LANGUAGE", "pt-BR") MIN_LINES = int(os.getenv("MIN_LINES", "20")) INTERVAL_MINUTES = int(os.getenv("INTERVAL_MINUTES", "60")) START_HOUR = int(os.getenv("START_HOUR", "7")) END_HOUR = int(os.getenv("END_HOUR", "22")) TOPICS_RAW = os.getenv("TOPICS", "") DAYS_OF_WEEK_RAW = os.getenv("DAYS_OF_WEEK", "1,2,3,4,5,6,7") if not TELEGRAM_BOT_TOKEN or TELEGRAM_BOT_TOKEN == "seu_bot_token_aqui": raise ValueError("TELEGRAM_BOT_TOKEN não configurado no .env") if not TELEGRAM_CHAT_ID or TELEGRAM_CHAT_ID == "seu_chat_id_aqui": raise ValueError("TELEGRAM_CHAT_ID não configurado no .env") if DEFAULT_AI_PROVIDER == "openrouter" and OPENROUTER_API_KEY and OPENROUTER_API_KEY != "sk-or-v1-...": client = openai.OpenAI(base_url="https://openrouter.ai/api/v1", api_key=OPENROUTER_API_KEY) elif DEFAULT_AI_PROVIDER == "llamacpp" and LLAMACPP_API_KEY: client = openai.OpenAI(base_url=LLAMACPP_BASE_URL, api_key=LLAMACPP_API_KEY) elif DEFAULT_AI_PROVIDER == "openai" and OPENAI_API_KEY: client = openai.OpenAI(api_key=OPENAI_API_KEY) elif OPENROUTER_API_KEY and OPENROUTER_API_KEY != "sk-or-v1-...": client = openai.OpenAI(base_url="https://openrouter.ai/api/v1", api_key=OPENROUTER_API_KEY) elif LLAMACPP_API_KEY: client = openai.OpenAI(base_url=LLAMACPP_BASE_URL, api_key=LLAMACPP_API_KEY) elif OPENAI_API_KEY: client = openai.OpenAI(api_key=OPENAI_API_KEY) else: raise ValueError("Nenhuma chave de IA configurada no .env") init_db() CURRENT_PROVIDER = DEFAULT_AI_PROVIDER TOPICS = [t.strip() for t in TOPICS_RAW.split(",") if t.strip()] if not TOPICS: raise ValueError("Nenhum tópico informado no .env (variável TOPICS)") DAYS_OF_WEEK = [int(d.strip()) for d in DAYS_OF_WEEK_RAW.split(",") if d.strip()] if not DAYS_OF_WEEK: DAYS_OF_WEEK = [1, 2, 3, 4, 5, 6, 7] def is_within_schedule(): now = datetime.now() return now.isoweekday() in DAYS_OF_WEEK and START_HOUR <= now.hour < END_HOUR def generate_insight(topic): prompt = ( f"Você é um assistente especializado em {topic}. " f"Escreva um insight profundo, prático e motivador sobre {topic} " f"em português brasileiro ({LANGUAGE}). " f"O texto deve ter pelo menos {MIN_LINES} linhas, ser original, direto ao ponto e útil para o leitor. " f"Não utilize marcações markdown como títulos ou negrito excessivo. " f"Escreva de forma fluida, como se fosse uma orientação prática. " f"Separe os parágrafos com linhas em branco (duas quebras de linha)." ) try: response = client.chat.completions.create( model=DEFAULT_AI_MODEL, messages=[ {"role": "system", "content": "Responda sempre em português brasileiro."}, {"role": "user", "content": prompt}, ], temperature=0.7, max_tokens=4000, ) content = response.choices[0].message.content if not content: return "[Erro ao gerar insight: resposta vazia da API]" return content.strip() except Exception as e: return f"[Erro ao gerar insight: {e}]" def send_telegram_message(text, topic): now = datetime.now() header = ( f"🤖 *Syspanel Insights - by ThorAgentIA*\n" f"🤖 *https://syspanel.com.br*\n" f"🕒 {now.strftime('%d/%m/%Y %H:%M:%S')}\n" f"📌 Assunto: {topic}\n\n" ) message = header + text url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage" payload = { "chat_id": TELEGRAM_CHAT_ID, "text": message, "parse_mode": "Markdown", } try: if len(message) <= 4096: response = requests.post(url, json=payload, timeout=30) response.raise_for_status() print(f"[{now.strftime('%Y-%m-%d %H:%M:%S')}] Mensagem enviada com sucesso.") else: chunks = [] current = header parts = text.split("\n\n") for part in parts: candidate = current + part if len(candidate) <= 4096: current = candidate + "\n\n" else: chunks.append(current.strip()) current = header + part + "\n\n" if current.strip(): chunks.append(current.strip()) for idx, chunk in enumerate(chunks, start=1): chunk_payload = { "chat_id": TELEGRAM_CHAT_ID, "text": chunk, "parse_mode": "Markdown", } response = requests.post(url, json=chunk_payload, timeout=30) response.raise_for_status() print(f"[{now.strftime('%Y-%m-%d %H:%M:%S')}] Mensagem enviada em {len(chunks)} parte(s).") except Exception as e: print(f"[{now.strftime('%Y-%m-%d %H:%M:%S')}] Erro ao enviar mensagem: {e}") def job(): now = datetime.now() print(f"\n[{now.strftime('%Y-%m-%d %H:%M:%S')}] Verificando horário...") if not is_within_schedule(): print(f"[{now.strftime('%Y-%m-%d %H:%M:%S')}] Fora do horário permitido. Pulando envio.") return topic = random.choice(TOPICS) print(f"[{now.strftime('%Y-%m-%d %H:%M:%S')}] Tópico escolhido: {topic}") print(f"[{now.strftime('%Y-%m-%d %H:%M:%S')}] Gerando insight...") insight = generate_insight(topic) try: save_insight(topic=topic, content=insight, provider=CURRENT_PROVIDER, model=DEFAULT_AI_MODEL) print(f"[{now.strftime('%Y-%m-%d %H:%M:%S')}] Insight salvo no banco de dados.") except Exception as e: print(f"[{now.strftime('%Y-%m-%d %H:%M:%S')}] Erro ao salvar no banco: {e}") send_telegram_message(insight, topic) def main(): print("=== ThorAgentIA iniciado ===") print(f"Provedor: {DEFAULT_AI_PROVIDER} | Modelo: {DEFAULT_AI_MODEL}") print(f"Horário permitido: {START_HOUR}h às {END_HOUR}h") print(f"Dias permitidos: {DAYS_OF_WEEK}") print(f"Intervalo: {INTERVAL_MINUTES} minutos") print(f"Tópicos disponíveis: {len(TOPICS)}") for i, t in enumerate(TOPICS, 1): print(f" {i}. {t}") print() schedule.every(INTERVAL_MINUTES).minutes.do(job) job() while True: schedule.run_pending() time.sleep(1) if __name__ == "__main__": try: main() except KeyboardInterrupt: print("\nThorAgentIA encerrado.")