Implement message splitting for messages exceeding Telegram's 4096 character limit. Update header branding, increase max_tokens to 4000, adjust END_HOUR to 20, update default AI model, and revise documentation to reflect channel setup instead of groups.
179 lines
6.4 KiB
Python
179 lines
6.4 KiB
Python
from dotenv import load_dotenv
|
|
import os
|
|
import random
|
|
import requests
|
|
import openai
|
|
import schedule
|
|
import time
|
|
from datetime import datetime
|
|
|
|
load_dotenv()
|
|
|
|
TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
|
|
TELEGRAM_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID")
|
|
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
|
OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
|
|
OPENROUTER_MODEL = os.getenv("OPENROUTER_MODEL")
|
|
STEPFUN_BASE_URL = os.getenv("STEPFUN_BASE_URL")
|
|
STEPFUN_API_KEY = os.getenv("STEPFUN_API_KEY")
|
|
STEPFUN_MODEL = os.getenv("STEPFUN_MODEL")
|
|
LLAMACPP_BASE_URL = os.getenv("LLAMACPP_BASE_URL")
|
|
LLAMACPP_API_KEY = os.getenv("LLAMACPP_API_KEY")
|
|
LLAMACPP_MODEL = os.getenv("LLAMACPP_MODEL")
|
|
DEFAULT_AI_MODEL = os.getenv("DEFAULT_AI_MODEL", OPENROUTER_MODEL or STEPFUN_MODEL or LLAMACPP_MODEL or "gpt-4o-mini")
|
|
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 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 STEPFUN_API_KEY:
|
|
client = openai.OpenAI(base_url=STEPFUN_BASE_URL, api_key=STEPFUN_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")
|
|
|
|
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"🧠 Modelo: `{DEFAULT_AI_MODEL}`\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)
|
|
send_telegram_message(insight, topic)
|
|
|
|
|
|
def main():
|
|
print("=== ThorAgentIA iniciado ===")
|
|
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.")
|