Webhook TypeScript hospedado na Vercel que, ao ser chamado pelo botão da home do curso no Notion, cria todas as entradas de progresso do aluno de uma vez — status "Não iniciado" para todas as aulas, exceto a primeira que já entra como "Em andamento".
notion-progress/
├── api/
│ └── init-progress.ts # Endpoint chamado pelo Notion
├── lib/
│ └── notion.ts # Lógica de integração com a API do Notion
├── .env.example # Template das variáveis de ambiente
├── package.json
├── tsconfig.json
└── vercel.json
- Acesse https://www.notion.so/my-integrations
- Clique em "New integration"
- Dê um nome (ex: "Course Progress") e selecione seu workspace
- Em "Capabilities", marque: Read content, Update content, Insert content
- Salve e copie o Internal Integration Token (começa com
secret_) - Abra as databases Aulas e Progresso dos Alunos no Notion
- Em cada uma: clique em
...→ "Add connections" → selecione sua integração
Copie .env.example para .env.local e preencha:
NOTION_TOKEN=secret_... # Token copiado no passo anterior
NOTION_DB_AULAS=cfc78666e07f8237b2a381fcef970b25
NOTION_DB_PROGRESSO=ff678666e07f838e983b0174338fec58
WEBHOOK_SECRET=... # Qualquer string longa (use: openssl rand -hex 32)npm install
npm i -g vercel # Se ainda não tiver a CLI
vercel login
vercel --prodAdicione as variáveis de ambiente quando solicitado, ou depois em: vercel.com → seu projeto → Settings → Environment Variables
Após o deploy, seu endpoint estará em:
https://seu-projeto.vercel.app/api/init-progress
- Abra a página home do curso
- Edite o botão → "Add automation" (ou edite a existente)
- Configure:
- Trigger: Button clicked
- Action: Send HTTP request
- URL:
https://seu-projeto.vercel.app/api/init-progress - Method:
POST - Headers:
Key Value Content-Typeapplication/jsonx-webhook-secret(seu WEBHOOK_SECRET) - Body:
{ "userId": "{{current user.id}}" }
- URL:
- Recebe o
userIddo Notion (quem clicou no botão) - Busca todas as aulas da database, ordenadas por
Número - Verifica quais aulas já possuem entrada em Progresso para esse usuário
- Cria as entradas faltando em lotes de 5 (respeita o rate limit da API)
- A primeira aula recebe status "Em andamento", todas as demais "Não iniciado"
- É idempotente: se chamado novamente, só cria entradas para aulas ainda não cadastradas
Com todas as entradas criadas, os cálculos ficam viáveis via recursos nativos:
% de conclusão por módulo (na database Módulos):
- Em Módulos, crie um rollup da relação
Aulas - Aponte para a relação
Progressonas aulas e conte entradas com statusConcluída - Divida pelo total de aulas do módulo para obter a porcentagem
% geral do aluno (na database Progresso, agrupado por Aluno):
- Use uma view agrupada por
Alunocom um rollup ou fórmula que contaConcluída / total