Compare commits

...
11 Commits
Author SHA1 Message Date
marco c6a2e6a452 feat(config): update default AI model to inclusionai/ling-3.0-flash
Switch from minimax/minimax-m3:free to inclusionai/ling-3.0-flash as the
default AI model for insight generation, aligning with the updated AI
provider configuration.
2026-09-03 15:20:42 -03:00
marco 5bc68e3627 feat(db): add SQLite database persistence for insights
Implement local database storage to automatically save all sent insights
with metadata including topic, content, AI provider, model, and timestamp.
Add database module with initialization and query functions, integrate
with main job flow, and update documentation with database schema details.
2026-09-03 15:05:45 -03:00
marco ee398ff8a0 refactor(config): simplify AI provider configuration with provider selector
Remove StepFun provider support and consolidate AI configuration under
DEFAULT_AI_PROVIDER variable supporting openrouter, llamacpp, and openai.
Update .env, README.md, and main.py to use the new provider-based structure.
Add "Qualidade Total na Empresa" to topics list.
2026-09-03 15:01:16 -03:00
marco 369b81a242 feat(config): update AI model configurations
Update DEFAULT_AI_MODEL to step-3.5-flash, OPENROUTER_MODEL to minimax/minimax-m3:free, and STEPFUN_MODEL to step-3.5-flash
2026-09-03 14:33:32 -03:00
marco b48f88fb4b feat(config): update telegram chat ID and polling interval
Change TELEGRAM_CHAT_ID to new channel and increase INTERVAL_MINUTES
from 3 to 120 minutes. Update deployment package app.zip.
2026-08-24 08:51:55 -03:00
marco a682eda9f3 feat(telegram): add message chunking and update channel configuration
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.
2026-08-24 08:35:52 -03:00
marco bfc6f444f8 feat(topics): add financial planning and control topics 2026-08-18 07:43:17 -03:00
marco ba52d43a9f feat(config): expand topics list with finance and sales resources 2026-08-18 07:17:49 -03:00
marco c0b87c40a4 docs(telegram): add setup guide and update chat ID
Adds comprehensive documentation for creating a Telegram bot, configuring
a group, and setting permissions. Updates TELEGRAM_CHAT_ID in .env to
the correct group identifier for automated messaging.
2026-08-17 18:50:41 -03:00
marco 44ce0a0d18 feat(config): expand topics list with business and strategy resources 2026-08-17 14:12:20 -03:00
marco f7cbf6c054 fix(schedule): use isoweekday for correct day mapping 2026-08-17 12:42:41 -03:00
7 changed files with 411 additions and 91 deletions
+13 -19
View File
@@ -2,38 +2,32 @@
# Configuração de horário de funcionamento (hora local) # Configuração de horário de funcionamento (hora local)
START_HOUR=7 START_HOUR=7
END_HOUR=22 END_HOUR=20
DAYS_OF_WEEK=1,2,3,4,5,6,7 DAYS_OF_WEEK=1,2,3,4,5,6,7
# Intervalo em minutos para gerar e enviar insights # Intervalo em minutos para gerar e enviar insights
INTERVAL_MINUTES=3 INTERVAL_MINUTES=120
# Assuntos (20 assuntos separados por vírgula) # Assuntos (20 assuntos separados por vírgula)
TOPICS=Marketing,Negócios,Pensamentos de Empresários Famosos,Lei da Atração,Lei do Triunfo,Administração de Pequenos Negócios,CRM,Vendas,Compras para Empresas,Planejamento Estratégico Empresarial,Recursos Humanos,A Arte de Fazer Amigos,Inteligência Emocional,Produtividade,Liderança,Inovação,Experiência do Cliente,Networking,Marca Pessoal,Storytelling TOPICS=Marketing,Negócios,Pensamentos de Empresários Famosos,Lei da Atração,Lei do Triunfo (Autor: Napoleon Hill),Administração de Pequenos Negócios,CRM,Vendas,Compras para Empresas,Planejamento Estratégico Empresarial,Recursos Humanos,A Arte de Fazer Amigos,Inteligência Emocional,Produtividade,Liderança,Inovação,Experiência do Cliente,Networking,Marca Pessoal,Storytelling,As 36 Estratégias dos Chineses (Autores: Wee Chow Hou & Lan Luh Luh),Como garantir três vendas extras por dia (Autor: Evaldo Costa), 100 Segredos das Pessoas de Sucesso (Autor: David Niven),Como Fazer Amigos e Influenciar Pessoas(Autor: Dale Carnegie),Economia,Investimentos,Renda Passiva,A Arte de Vender(Autor: Paul W. Ivey),Educação Financeira,Planejamento Financeiro Pessoal,Planejamento Financeiro Empresarial,Fluxo de Caixa,Controle Financeiro Empresarial,Qualidade Total na Empresa
# Modelo de IA padrão (opcional, se não usar provedores abaixo) # Provedor de IA padrão (openrouter | llamacpp | openai)
# DEFAULT_AI_MODEL=gpt-4o-mini DEFAULT_AI_PROVIDER=openrouter
# OPENAI_API_KEY=sua_api_key_openai_aqui
# Provedor OpenRouter # Modelo de IA padrão (depende do provedor escolhido)
#DEFAULT_AI_MODEL=minimax/minimax-m3:free
DEFAULT_AI_MODEL=inclusionai/ling-3.0-flash
# Chave de API do provedor escolhido
OPENROUTER_API_KEY=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 OPENROUTER_API_KEY=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
OPENROUTER_MODEL=poolside/laguna-xs-2.1:free
# Provedor StepFun
STEPFUN_BASE_URL=https://api.stepfun.ai/step_plan/v1/
STEPFUN_API_KEY=4RJZ4kHTbMNqWNn7IgahHF1kzcTi8zzUMv7YLQqjChCH5DftV2bSbGif1HllC44nv
STEPFUN_MODEL=step-3.7-flash
# Provedor LlamaCPP local
LLAMACPP_BASE_URL=http://localhost:8080/v1/ LLAMACPP_BASE_URL=http://localhost:8080/v1/
LLAMACPP_API_KEY=not-needed LLAMACPP_API_KEY=not-needed
LLAMACPP_MODEL=qwen2.5-coder-3b-instruct-q4_k_m.gguf # OPENAI_API_KEY=sua_api_key_openai_aqui
# Configuração do Telegram # Configuração do Telegram
TELEGRAM_BOT_TOKEN=8638829617:AAEXTF0a7g66XRPcUb9gvw8t2StUPstX6VI TELEGRAM_BOT_TOKEN=8903949501:AAGXMQOS1q3z4_w1tUhBZZbYCZ8F0fkbi7E
TELEGRAM_CHAT_ID=7889499475 TELEGRAM_CHAT_ID=-1003832867367
# Idioma # Idioma
LANGUAGE=pt-BR LANGUAGE=pt-BR
MIN_LINES=20 MIN_LINES=20
+31 -52
View File
@@ -5,17 +5,18 @@ Sistema automatizado de envio de insights via Telegram, utilizando inteligência
## Funcionalidades ## Funcionalidades
- Gera insights profundos em português brasileiro sobre temas pré-definidos. - Gera insights profundos em português brasileiro sobre temas pré-definidos.
- Envia automaticamente os insights para um chat do Telegram. - Envia automaticamente os insights para um **canal do Telegram**.
- Opera em horários configuráveis (padrão: 07:00 às 22:00). - Opera em horários configuráveis (padrão: 07:00 às 22:00).
- Funciona de segunda a domingo (dias configuráveis). - Funciona de segunda a domingo (dias configuráveis).
- Intervalo entre envios configurável. - Intervalo entre envios configurável.
- Seleção aleatória de tópicos cadastrados. - Seleção aleatória de tópicos cadastrados.
- Suporte a múltiplos provedores de IA: OpenAI, OpenRouter, StepFun ou LlamaCPP local. - Suporte a múltiplos provedores de IA: OpenRouter, LlamaCPP local ou OpenAI.
- Todos os insights são salvos automaticamente em um banco de dados SQLite local (`insights.db`).
## Pré-requisitos ## Pré-requisitos
- Python 3.10 ou superior - Python 3.10 ou superior
- Chave de API de IA: OpenAI, OpenRouter, StepFun ou LlamaCPP local - Chave de API de IA: OpenRouter, LlamaCPP local ou OpenAI
- Bot criado no Telegram via BotFather - Bot criado no Telegram via BotFather
- Sistema Linux (Debian 12 recomendado) - Sistema Linux (Debian 12 recomendado)
@@ -29,26 +30,23 @@ TELEGRAM_CHAT_ID=seu_chat_id
INTERVAL_MINUTES=60 INTERVAL_MINUTES=60
START_HOUR=7 START_HOUR=7
END_HOUR=22 END_HOUR=22
TOPICS=Marketing,Negócios,Lei da Atração,... TOPICS=Marketing,Negócios,...
# Provedor preferencial: OpenRouter # Provedor de IA (openrouter | llamacpp | openai)
DEFAULT_AI_PROVIDER=openrouter
# Modelo de IA (depende do provedor escolhido)
DEFAULT_AI_MODEL=minimax/minimax-m3:free
# Chave de API do provedor escolhido
OPENROUTER_API_KEY=sua_chave_openrouter OPENROUTER_API_KEY=sua_chave_openrouter
OPENROUTER_MODEL=inclusionai/ling-3.0-tiny:free # LLAMACPP_API_KEY=not-needed # se usar LlamaCPP
# OPENAI_API_KEY=sua_chave_openai # se usar OpenAI direto
# Alternativa: StepFun
STEPFUN_BASE_URL=https://api.stepfun.ai/step_plan/v1/
STEPFUN_API_KEY=sua_chave_stepfun
STEPFUN_MODEL=step-3.7-flash
# Alternativa: LlamaCPP local
LLAMACPP_BASE_URL=http://localhost:8080/v1/
LLAMACPP_API_KEY=not-needed
LLAMACPP_MODEL=qwen2.5-coder-3b-instruct-q4_k_m.gguf
``` ```
2. **Crie um bot no Telegram** via @BotFather e obtenha o token. 2. **Crie um bot no Telegram** via @BotFather e obtenha o token.
3. **Obtenha seu chat ID** enviando uma mensagem para o bot e consultando a API do Telegram ou usando um bot como @myidbot. 3. **Obtenha o identificador do canal** após adicionar o bot como administrador no canal. Use o username do canal no formato `@nome_do_canal` ou o ID numérico `-100xxxxxxxxxx`.
## Instalação ## Instalação
@@ -57,11 +55,6 @@ chmod +x iniciar.sh
./iniciar.sh ./iniciar.sh
``` ```
O script irá:
- Criar o ambiente virtual Python
- Instalar todas as dependências
- Preparar o sistema para execução
## Execução ## Execução
```bash ```bash
@@ -69,24 +62,18 @@ source venv/bin/activate
python3 main.py python3 main.py
``` ```
Para rodar como serviço em background no Linux, utilize `systemd` ou `screen`/`tmux`.
## Variáveis de Ambiente ## Variáveis de Ambiente
| Variável | Descrição | Padrão | | Variável | Descrição | Padrão |
|---|---|---| |---|---|---|
| `OPENAI_API_KEY` | Chave da API da OpenAI | opcional | | `DEFAULT_AI_PROVIDER` | Provedor de IA (`openrouter`, `llamacpp`, `openai`) | `openrouter` |
| `DEFAULT_AI_MODEL` | Nome do modelo no provedor escolhido | obrigatório |
| `OPENROUTER_API_KEY` | Chave da API OpenRouter | opcional | | `OPENROUTER_API_KEY` | Chave da API OpenRouter | opcional |
| `OPENROUTER_MODEL` | Modelo no OpenRouter | inclusionai/ling-3.0-tiny:free | | `LLAMACPP_BASE_URL` | URL base da API LlamaCPP local | `http://localhost:8080/v1/` |
| `STEPFUN_BASE_URL` | URL base StepFun | https://api.stepfun.ai/step_plan/v1/ | | `LLAMACPP_API_KEY` | Chave da API LlamaCPP | `not-needed` |
| `STEPFUN_API_KEY` | Chave StepFun | opcional | | `OPENAI_API_KEY` | Chave da API OpenAI | opcional |
| `STEPFUN_MODEL` | Modelo StepFun | step-3.7-flash |
| `LLAMACPP_BASE_URL` | URL base LlamaCPP | http://localhost:8080/v1/ |
| `LLAMACPP_API_KEY` | Chave LlamaCPP | not-needed |
| `LLAMACPP_MODEL` | Modelo LlamaCPP | qwen2.5-coder-3b-instruct-q4_k_m.gguf |
| `DEFAULT_AI_MODEL` | Modelo usado quando houver apenas OpenAI | gpt-4o-mini |
| `TELEGRAM_BOT_TOKEN` | Token do bot Telegram | obrigatório | | `TELEGRAM_BOT_TOKEN` | Token do bot Telegram | obrigatório |
| `TELEGRAM_CHAT_ID` | ID do chat Telegram | obrigatório | | `TELEGRAM_CHAT_ID` | Username do canal ou ID numérico | obrigatório |
| `INTERVAL_MINUTES` | Intervalo entre envios (minutos) | 60 | | `INTERVAL_MINUTES` | Intervalo entre envios (minutos) | 60 |
| `START_HOUR` | Hora inicial de funcionamento | 7 | | `START_HOUR` | Hora inicial de funcionamento | 7 |
| `END_HOUR` | Hora final de funcionamento | 22 | | `END_HOUR` | Hora final de funcionamento | 22 |
@@ -95,23 +82,15 @@ Para rodar como serviço em background no Linux, utilize `systemd` ou `screen`/`
| `LANGUAGE` | Idioma dos insights | pt-BR | | `LANGUAGE` | Idioma dos insights | pt-BR |
| `MIN_LINES` | Mínimo de linhas por insight | 20 | | `MIN_LINES` | Mínimo de linhas por insight | 20 |
> Prioridade de provedor: OpenRouter > StepFun > LlamaCPP > OpenAI ### Banco de dados SQLite
## Estrutura do Projeto Todos os insights enviados são registrados automaticamente no arquivo `insights.db`, na mesma pasta do projeto. A tabela `insights` armazena:
``` | Campo | Descrição |
ThorAgenteIA/ |---|---|
├── .env # Configurações sensíveis (não versionar) | `id` | Identificador único |
├── .gitignore | `topic` | Tópico do insight |
├── iniciar.sh # Script de setup automático | `content` | Conteúdo completo do insight |
├── main.py # Código principal | `provider` | Provedor de IA utilizado |
├── requirements.txt # Dependências Python | `model` | Modelo utilizado |
├── RULES.md # Regras para IA coder | `sent_at` | Data e hora do envio |
└── README.md # Documentação
```
## Solução de Problemas
- **Erro de API Key**: Verifique se pelo menos um provedor está configurado no `.env`.
- **Mensagem não enviada**: Confira o token do bot e o chat ID.
- **Horário incorreto**: Verifique o fuso horário do servidor Linux.
+262
View File
@@ -0,0 +1,262 @@
# Como criar um Bot no Telegram e configurar um Canal
Este guia explica passo a passo como criar um bot no Telegram, configurar um canal, adicionar administradores e configurar tudo para que o canal receba as mensagens do bot.
---
## 1. Criar o Bot no Telegram
### 1.1. Acessar o BotFather
1. Abra o Telegram e pesquise por **@BotFather** ou acesse [https://t.me/BotFather](https://t.me/BotFather).
2. Clique em **Iniciar** ou envie o comando `/start`.
### 1.2. Criar o novo bot
1. Envie o comando `/newbot`.
2. Escolha um nome para o seu bot (ex: `ThorAgentIA Bot`). Este é o nome de exibição.
3. Escolha um username para o bot (ex: `thoragentia_bot`). O username deve terminar com `bot` e ser único no Telegram.
### 1.3. Obter o Token
Após criar o bot, o BotFather irá enviar uma mensagem semelhante a:
```
Usuário: @thoragentia_bot
Token: 1234567890:ABCdefGhIJKlmNoPQRsTUVwxyz1234567890
```
**Guarde este token com segurança.** Ele será usado na variável `TELEGRAM_BOT_TOKEN` do arquivo `.env`.
> ⚠️ Nunca compartilhe o token publicamente. Qualquer pessoa com acesso ao token pode controlar o bot.
---
## 2. Criar um Canal no Telegram
### 2.1. Criar o canal
1. No Telegram, clique no ícone de **menu** (três linhas) e selecione **Novo canal**.
2. Defina um nome para o canal (ex: `Insights ThorAgentIA`).
3. (Opcional) Adicione uma descrição e foto.
4. Clique em **Criar**.
### 2.2. Tornar o canal público ou privado
- **Canal público**: Qualquer pessoa pode encontrar o canal pelo username.
- **Canal privado**: Apenas usuários convidados podem acessar.
Recomenda-se usar canal **público** se desejar que o bot envie mensagens usando apenas o username. Para canais privados, será necessário usar o ID numérico.
### 2.3. Configurar permissões do canal
1. Clique no nome do canal no topo.
2. Clique em **Gerenciar canal** (ou **Editar canal**).
3. Ajuste as permissões conforme necessidade.
Para canais, o foco principal é garantir que o bot possa publicar mensagens.
---
## 3. Adicionar o Bot ao Canal
### 3.1. Adicionar como administrador (recomendado)
1. Abra o canal e clique no nome do canal no topo.
2. Clique em **Administradores**.
3. Clique em **Adicionar administrador**.
4. Pesquise pelo username do bot (ex: `@thoragentia_bot`).
5. Selecione o bot e confirme.
> **Nota**: Para canais públicos, o bot também pode ser adicionado sem ser administrador, mas para enviar mensagens proativamente é necessário ser administrador com permissão de postar mensagens.
### 3.2. Conceder permissões ao bot
Para que o bot possa enviar mensagens no canal, ele precisa ter a permissão **Postar mensagens** ou **Enviar mensagens**.
#### Como localizar essa permissão no Telegram
**Telegram Desktop / Web**
1. Abra o canal.
2. Clique no **nome do canal** no topo para abrir as informações.
3. Clique em **Administradores**.
4. Na lista, clique no nome do seu bot.
5. Role até a seção **Permissões de administrador**.
6. Ative a opção **Postar mensagens** (ou **Enviar mensagens**).
7. Clique em **Salvar** no final da tela.
**Telegram Android / iOS**
1. Abra o canal.
2. Toque no **nome do canal** no topo para abrir as informações.
3. Toque em **Administradores**.
4. Na lista, toque no seu bot.
5. Ative a opção **Postar mensagens** (ou **Enviar mensagens**).
6. Toque no ícone de **confirmar/check** no canto superior direito para salvar.
#### Importante sobre a permissão "Postar mensagens"
Essa permissão controla se o administrador pode publicar mensagens no canal. Se estiver desativada, o bot será adicionado como administrador, mas não conseguirá enviar mensagens por conta própria.
> **Nota**: Se o bot não for administrador, ele só poderá responder a comandos ou mensagens enviadas diretamente para ele. Para enviar mensagens proativamente, ele precisa ser administrador com essa permissão ativada.
---
## 4. Obter o Identificador do Canal
Para configurar o bot para enviar mensagens para o canal, você precisa do **identificador do canal**, que pode ser o username no formato `@nome_do_canal` ou o ID numérico `-100xxxxxxxxxx`.
### 4.1. Método 1: Usar o username do canal
Se o canal for público e tiver um username definido, basta usar o formato `@nome_do_canal` em `TELEGRAM_CHAT_ID`.
### 4.2. Método 2: Usar a API do Telegram
1. Adicione o bot ao canal (veja seção 3).
2. Envie uma mensagem do canal ou adicione o bot como administrador.
3. Acesse a seguinte URL no navegador (substitua `SEU_TOKEN` pelo token do bot):
```
https://api.telegram.org/botSEU_TOKEN/getUpdates
```
4. Procure por `"chat":{"id":-100XXXXXXXXXX` na resposta JSON. O número negativo é o ID do canal.
> **Dica**: Você também pode executar o comando abaixo no terminal para consultar os updates do bot:
```bash
python3 -c "
import requests, os
from dotenv import load_dotenv
load_dotenv()
token = os.getenv('TELEGRAM_BOT_TOKEN')
r = requests.get(f'https://api.telegram.org/bot{token}/getUpdates', timeout=15)
print(r.text)
"
```
### 4.3. Método 3: Usar um bot auxiliar
1. Adicione o bot **@myidbot** ao canal.
2. Envie o comando `/myid`.
3. O bot irá responder com o identificador do canal.
---
## 5. Obter o Identificador do Canal
Para configurar o bot para enviar mensagens para o canal, você precisa do **identificador do canal**, que pode ser o username no formato `@nome_do_canal` ou o ID numérico `-100xxxxxxxxxx`.
### 5.1. Método 1: Usando o BotFather
1. Acesse o BotFather.
2. Clique no bot criado (ex: `@thoragentia_bot`).
3. O BotFather irá exibir as informações do bot, incluindo o identificador do canal se houver.
### 5.2. Método 2: Usando a API do Telegram
1. Adicione o bot ao canal (veja seção 3).
2. Envie uma mensagem qualquer no canal ou adicione o bot como administrador.
3. Acesse a seguinte URL no navegador (substitua `SEU_TOKEN` pelo token do bot):
```
https://api.telegram.org/botSEU_TOKEN/getUpdates
```
4. Procure por `"chat":{"id":-100XXXXXXXXXX` na resposta JSON. O número negativo é o ID do canal.
### 5.3. Método 3: Usando um bot auxiliar
1. Adicione o bot **@myidbot** ao canal.
2. Envie o comando `/myid`.
3. O bot irá responder com o identificador do canal.
---
## 6. Configurar o ThorAgentIA para o Canal
### 6.1. Configurar o arquivo `.env`
Edite o arquivo `.env` do projeto ThorAgentIA com o token e identificador do canal obtidos:
```env
TELEGRAM_BOT_TOKEN=1234567890:ABCdefGhIJKlmNoPQRsTUVwxyz1234567890
TELEGRAM_CHAT_ID=@nome_do_canal
```
> **Importante**: Para canais públicos, use o formato `@nome_do_canal`. Para canais privados, use o ID numérico `-100xxxxxxxxxx`.
### 6.2. Testar a conexão
Execute o script principal para verificar se o bot envia mensagens corretamente para o canal:
```bash
source venv/bin/activate
python3 main.py
```
Se configurado corretamente, o bot começará a enviar insights automaticamente para o canal nos horários definidos.
---
## 7. Gerenciar Membros e Permissões
### 7.1. Adicionar novos membros
- Use o link de convite do canal (se o canal for privado).
- Ou adicione diretamente pelo menu do canal.
### 7.2. Remover membros
1. Abra o canal e clique no nome do canal.
2. Vá em **Membros**.
3. Clique no membro que deseja remover.
4. Selecione **Remover membro**.
### 7.3. Promover membros a administradores
1. Abra o canal e clique no nome do canal.
2. Vá em **Administradores**.
3. Clique em **Adicionar administrador**.
4. Pesquise e selecione o membro.
5. Defina as permissões desejadas.
---
## 8. Solução de Problemas
### O bot não envia mensagens para o canal
1. Verifique se o bot é administrador do canal.
2. Verifique se a permissão **Postar mensagens** está ativada para o bot.
3. Confirme se o `TELEGRAM_BOT_TOKEN` e `TELEGRAM_CHAT_ID` estão corretos no `.env`.
4. Verifique os logs do script para identificar erros.
### Usuários não recebem as mensagens
1. Certifique-se de que os usuários são membros do canal.
2. Para canais privados, verifique se os usuários foram convidados corretamente.
3. Para canais grandes, verifique se o bot não foi silenciado pelos usuários.
### O bot não responde a comandos no canal
1. Verifique se o bot está ativo no canal.
2. Confira se o token do bot está correto.
3. Verifique se há restrições de permissão no canal.
---
## 9. Boas Práticas
- Nunca compartilhe o token do bot publicamente.
- Revise regularmente os administradores do canal para manter a segurança.
- Defina horários adequados para envio de mensagens (evite horários muito cedo ou tarde).
- Para canais grandes, considere usar um plano de distribuição mais espaçado.
- Documente as configurações do canal em um arquivo seguro (não no `.env`).
---
## Referências
- [Documentação oficial do Telegram Bot API](https://core.telegram.org/bots/api)
- [BotFather](https://t.me/BotFather)
- [myidbot](https://t.me/myidbot)
BIN
View File
Binary file not shown.
+46
View File
@@ -0,0 +1,46 @@
import sqlite3
import os
from datetime import datetime
DB_PATH = os.path.join(os.path.dirname(__file__), "insights.db")
def init_db() -> None:
conn = sqlite3.connect(DB_PATH)
conn.execute("""
CREATE TABLE IF NOT EXISTS insights (
id INTEGER PRIMARY KEY AUTOINCREMENT,
topic TEXT NOT NULL,
content TEXT NOT NULL,
provider TEXT NOT NULL,
model TEXT NOT NULL,
sent_at TEXT NOT NULL
)
""")
conn.commit()
conn.close()
def save_insight(topic: str, content: str, provider: str, model: str) -> int:
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
sent_at = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
cursor.execute(
"INSERT INTO insights (topic, content, provider, model, sent_at) VALUES (?, ?, ?, ?, ?)",
(topic, content, provider, model, sent_at),
)
insight_id = cursor.lastrowid
conn.commit()
conn.close()
return insight_id
def get_insights(limit: int = 50):
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
rows = conn.execute(
"SELECT * FROM insights ORDER BY id DESC LIMIT ?", (limit,)
).fetchall()
conn.close()
return [dict(row) for row in rows]
BIN
View File
Binary file not shown.
+59 -20
View File
@@ -6,21 +6,18 @@ import openai
import schedule import schedule
import time import time
from datetime import datetime from datetime import datetime
from database import init_db, save_insight
load_dotenv() load_dotenv()
TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN") TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
TELEGRAM_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID") TELEGRAM_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") 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") OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
OPENROUTER_MODEL = os.getenv("OPENROUTER_MODEL") LLAMACPP_BASE_URL = os.getenv("LLAMACPP_BASE_URL", "http://localhost:8080/v1/")
STEPFUN_BASE_URL = os.getenv("STEPFUN_BASE_URL") LLAMACPP_API_KEY = os.getenv("LLAMACPP_API_KEY", "not-needed")
STEPFUN_API_KEY = os.getenv("STEPFUN_API_KEY") OPENAI_API_KEY = os.getenv("OPENAI_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") LANGUAGE = os.getenv("LANGUAGE", "pt-BR")
MIN_LINES = int(os.getenv("MIN_LINES", "20")) MIN_LINES = int(os.getenv("MIN_LINES", "20"))
INTERVAL_MINUTES = int(os.getenv("INTERVAL_MINUTES", "60")) INTERVAL_MINUTES = int(os.getenv("INTERVAL_MINUTES", "60"))
@@ -34,10 +31,14 @@ if not TELEGRAM_BOT_TOKEN or TELEGRAM_BOT_TOKEN == "seu_bot_token_aqui":
if not TELEGRAM_CHAT_ID or TELEGRAM_CHAT_ID == "seu_chat_id_aqui": if not TELEGRAM_CHAT_ID or TELEGRAM_CHAT_ID == "seu_chat_id_aqui":
raise ValueError("TELEGRAM_CHAT_ID não configurado no .env") raise ValueError("TELEGRAM_CHAT_ID não configurado no .env")
if OPENROUTER_API_KEY and OPENROUTER_API_KEY != "sk-or-v1-...": 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) 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: elif LLAMACPP_API_KEY:
client = openai.OpenAI(base_url=LLAMACPP_BASE_URL, api_key=LLAMACPP_API_KEY) client = openai.OpenAI(base_url=LLAMACPP_BASE_URL, api_key=LLAMACPP_API_KEY)
elif OPENAI_API_KEY: elif OPENAI_API_KEY:
@@ -45,6 +46,10 @@ elif OPENAI_API_KEY:
else: else:
raise ValueError("Nenhuma chave de IA configurada no .env") 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()] TOPICS = [t.strip() for t in TOPICS_RAW.split(",") if t.strip()]
if not TOPICS: if not TOPICS:
raise ValueError("Nenhum tópico informado no .env (variável TOPICS)") raise ValueError("Nenhum tópico informado no .env (variável TOPICS)")
@@ -56,7 +61,7 @@ if not DAYS_OF_WEEK:
def is_within_schedule(): def is_within_schedule():
now = datetime.now() now = datetime.now()
return now.weekday() in DAYS_OF_WEEK and START_HOUR <= now.hour < END_HOUR return now.isoweekday() in DAYS_OF_WEEK and START_HOUR <= now.hour < END_HOUR
def generate_insight(topic): def generate_insight(topic):
@@ -78,9 +83,12 @@ def generate_insight(topic):
{"role": "user", "content": prompt}, {"role": "user", "content": prompt},
], ],
temperature=0.7, temperature=0.7,
max_tokens=1500, max_tokens=4000,
) )
return response.choices[0].message.content.strip() 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: except Exception as e:
return f"[Erro ao gerar insight: {e}]" return f"[Erro ao gerar insight: {e}]"
@@ -88,9 +96,9 @@ def generate_insight(topic):
def send_telegram_message(text, topic): def send_telegram_message(text, topic):
now = datetime.now() now = datetime.now()
header = ( header = (
f"🤖 *ThorAgentIA*\n" f"🤖 *Syspanel Insights - by ThorAgentIA*\n"
f"🤖 *https://syspanel.com.br*\n"
f"🕒 {now.strftime('%d/%m/%Y %H:%M:%S')}\n" f"🕒 {now.strftime('%d/%m/%Y %H:%M:%S')}\n"
f"🧠 Modelo: `{DEFAULT_AI_MODEL}`\n"
f"📌 Assunto: {topic}\n\n" f"📌 Assunto: {topic}\n\n"
) )
message = header + text message = header + text
@@ -101,10 +109,35 @@ def send_telegram_message(text, topic):
"text": message, "text": message,
"parse_mode": "Markdown", "parse_mode": "Markdown",
} }
try: try:
response = requests.post(url, json=payload, timeout=30) if len(message) <= 4096:
response.raise_for_status() response = requests.post(url, json=payload, timeout=30)
print(f"[{now.strftime('%Y-%m-%d %H:%M:%S')}] Mensagem enviada com sucesso.") 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: except Exception as e:
print(f"[{now.strftime('%Y-%m-%d %H:%M:%S')}] Erro ao enviar mensagem: {e}") print(f"[{now.strftime('%Y-%m-%d %H:%M:%S')}] Erro ao enviar mensagem: {e}")
@@ -120,11 +153,17 @@ def job():
print(f"[{now.strftime('%Y-%m-%d %H:%M:%S')}] Tópico escolhido: {topic}") 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...") print(f"[{now.strftime('%Y-%m-%d %H:%M:%S')}] Gerando insight...")
insight = generate_insight(topic) 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) send_telegram_message(insight, topic)
def main(): def main():
print("=== ThorAgentIA iniciado ===") 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"Horário permitido: {START_HOUR}h às {END_HOUR}h")
print(f"Dias permitidos: {DAYS_OF_WEEK}") print(f"Dias permitidos: {DAYS_OF_WEEK}")
print(f"Intervalo: {INTERVAL_MINUTES} minutos") print(f"Intervalo: {INTERVAL_MINUTES} minutos")