You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Backend de agendamento e publicação automática de posts no Telegram.
Sistema que permite criar, agendar e publicar posts em canais do Telegram de forma automatizada, com fila de processamento, retry com backoff exponencial, monitormaneto via Prometheus/Grafana e autenticação JWT.
src/
├── app/ # Configuração do Fastify
│ ├── app.ts # Build da aplicação (plugins, rotas, error handler)
│ └── server.ts # Entrypoint (listen)
├── config/
│ └── env.ts # Validação de variáveis de ambiente com Zod
├── database/prisma/
│ └── client.ts # Instância singleton do Prisma Client
├── infra/ # Infraestrutura (Docker, monitoramento)
│ ├── grafana/
│ │ ├── dashboards/ # Provisioning de dashboards
│ │ └── datasources/ # Provisioning de datasources
│ └── prometheus/
│ └── prometheus.yml # Configuração de scrape
├── modules/ # Módulos da aplicação (domain-driven)
│ ├── auth/ # Autenticação (register, login)
│ ├── metrics/ # Métricas Prometheus
│ ├── posts/ # CRUD de posts
│ ├── telegram/ # Gerenciamento de canais Telegram
│ └── users/ # Perfil do usuário
├── plugins/ # Plugins do Fastify
│ ├── jwt.ts # JWT sign/verify + middleware authenticate
│ └── redis.ts # Conexão Redis (ioredis)
├── queues/
│ └── index.ts # Definição das filas BullMQ (publish, retry, dead-letter)
├── repositories/ # Data access layer (Prisma)
│ ├── job.repository.ts
│ ├── post.repository.ts
│ ├── telegram-channel.repository.ts
│ └── user.repository.ts
├── services/
│ ├── storage.service.ts # Upload de imagens (placeholder)
│ └── telegram.service.ts # Integração com a API do Telegram (Telegraf)
├── shared/
│ ├── constants/ # Enums do sistema
│ │ ├── job-status.ts
│ │ ├── post-status.ts
│ │ └── queues.ts
│ ├── errors/ # Classes de erro customizadas
│ │ └── app-error.ts
│ └── types/
│ └── index.ts # Interfaces compartilhadas
└── workers/
└── publish-post.worker.ts # Worker BullMQ que publica no Telegram
Modelo de Dados
erDiagram
User ||--o{ TelegramChannel : has
User ||--o{ Post : creates
TelegramChannel ||--o{ Post : target
Post ||--o{ Job : tracks
User {
uuid id PK
string name
string email UK
string password_hash
datetime created_at
}
TelegramChannel {
uuid id PK
uuid user_id FK
text bot_token
text chat_id
datetime created_at
}
Post {
uuid id PK
uuid user_id FK
uuid channel_id FK
string title
text caption
text image_url
string status "DRAFT | SCHEDULED | PROCESSING | PUBLISHED | FAILED | RETRYING | CANCELLED"
datetime scheduled_at
datetime published_at NULL
datetime created_at
}
Job {
uuid id PK
uuid post_id FK
string queue_name
string status "PENDING | ACTIVE | COMPLETED | FAILED | DELAYED | CANCELLED"
int attempts
datetime created_at
}
Loading
Ciclo de Vida de um Post
DRAFT → SCHEDULED → PROCESSING → PUBLISHED
│
▼
FAILED → RETRYING → PROCESSING (nova tentativa)
│
▼
DEAD LETTER (após 5 tentativas)
Fluxo de Publicação
POST /posts
│
├─ Valida dados com Zod
├─ Verifica se o canal pertence ao usuário
├─ Cria o post no banco (status: DRAFT)
├─ Adiciona job na fila "publish-post" com delay = scheduledAt - now
├─ Atualiza status para SCHEDULED
└─ Retorna 201 + bullJobId
Worker (quando o delay expira)
│
├─ Busca o post no banco
├─ Se CANCELLED → descarta o job
├─ Atualiza status para PROCESSING
├─ Envia a foto + legenda para o Telegram
├─ Se sucesso → marca PUBLISHED, incrementa métrica
│
└─ Se falha →
├─ Marca FAILED
├─ Se ainda há tentativas → adiciona na "retry-post" com backoff exponencial (5s, 10s, 20s, 40s...)
└─ Se esgotou tentativas → não faz mais nada (dead letter implícita)
Duração da publicação (buckets: 0.1, 0.5, 1, 2, 5, 10s)
bullmq_waiting_jobs
Gauge
Jobs aguardando na fila
bullmq_active_jobs
Gauge
Jobs ativos na fila
bullmq_failed_jobs
Gauge
Jobs com falha na fila
Como Executar
Desenvolvimento (local)
# 1. Instalar dependências
npm install
# 2. Configurar .env (ou copiar o existente)# DATABASE_URL, REDIS_URL, JWT_SECRET, PORT, HOST# 3. Subir PostgreSQL e Redis
docker compose up -d postgres redis
# 4. Rodar migrations do Prisma
npx prisma migrate dev
# 5. Iniciar API + Worker (em terminais separados)
npx tsx watch src/app/server.ts
npx tsx watch src/workers/publish-post.worker.ts
Produção (Docker Compose)
# Sobe todos os serviços
docker compose up -d
# Serviços:# API: http://localhost:3000# Grafana: http://localhost:3030 (admin / admin)# Prometheus: http://localhost:9090# Ver logs
docker compose logs -f api worker
Acessando o Grafana
Abra http://localhost:3030
Login: admin / admin (troca a senha no primeiro acesso)
O dashboard "PostFlow - Monitoramento" já estará disponível
O datasource Prometheus já vem pré-configurado
Variáveis de Ambiente
Variável
Obrigatória
Padrão
Descrição
DATABASE_URL
Sim
—
URL de conexão do PostgreSQL
REDIS_URL
Sim
—
URL de conexão do Redis
JWT_SECRET
Sim
—
Chave secreta para assinar JWT (mín. 16 caracteres)
PORT
Não
3000
Porta do servidor HTTP
HOST
Não
0.0.0.0
Host do servidor HTTP
NODE_ENV
Não
development
Ambiente (development, production, test)
Scripts Disponíveis
Comando
Descrição
npm run dev
Inicia a API com hot-reload (tsx watch)
npm run build
Compila TypeScript para JavaScript
npm start
Inicia a API compilada
npm run worker
Inicia o worker com hot-reload
npx prisma studio
Abre o Prisma Studio (interface do banco)
npx prisma migrate dev
Cria/executa migrations
npx prisma generate
Gera o Prisma Client
Desenvolvido por Lázaro Vasconcelos 💻
About
Sistema que permite criar, agendar e publicar posts em canais do Telegram de forma automatizada, com fila de processamento, retry com backoff exponencial, monitormaneto via Prometheus/Grafana e autenticação JWT.