A taxa média de evasão de cursos online no Brasil é de 50%. Em alguns nichos (idiomas, programação iniciante) chega a 70%. O motivo número um, segundo pesquisas com alunos, não é falta de tempo — é falta de engajamento ativo da plataforma. O aluno simplesmente esquece que comprou o curso.
Plataformas EAD que adotaram WhatsApp como canal de engajamento reduziram evasão em 30-40%. Este artigo detalha como fazer isso na prática, com código real e respeitando LGPD.
Por que WhatsApp e não email
- Email tem 18-22% de taxa de abertura. WhatsApp 95-98%.
- Aluno checa WhatsApp 80x por dia em média. Email 2x.
- Mensagem WhatsApp respondida em média em 90 segundos. Email 1h30min.
- Custo por mensagem WhatsApp: ~R$0,001. Custo email idem, mas o ROI por mensagem é 4x maior por causa da abertura.
Quatro casos de uso comprovados
Caso 1: Lembrete de aula ao vivo
30 minutos antes de live de tira-dúvidas, dispare lembrete com link da aula e tópico. Aumenta presença em 2-3x.
Caso 2: Prazo de entrega de atividade
24h antes de fechar prazo, lembre alunos que ainda não entregaram. Em cursos com nota mínima, reduz quem desiste por perder prazo.
Caso 3: Módulo novo disponível
Quando aluno completa módulo X e existe módulo X+1 disponível, avise. Acelera ritmo e cria sensação de progresso.
Caso 4: Certificado pronto
Quando aluno conclui curso, envie certificado em PDF direto pelo WhatsApp. Maior chance de compartilhamento social do que se ele só recebesse no painel.
Pré-requisitos
- Plataforma EAD com banco de alunos e progresso (Moodle, Hotmart, Eduzz, próprio sistema)
- Telefones dos alunos com opt-in registrado (ver seção LGPD abaixo)
- Conta na ZAP API com instância conectada
- Servidor Node.js (cron job ou serverless)
Código: cron job de reengajamento
Verifica diariamente alunos sem acesso há 3 dias e envia mensagem personalizada.
// reengajamento.js
import axios from "axios";
import { Pool } from "pg";
const ZAP = axios.create({
baseURL: "https://api.zap-api.tech/v1",
headers: { Authorization: `Bearer ${process.env.ZAP_TOKEN}` },
});
const db = new Pool({ connectionString: process.env.DATABASE_URL });
async function reengajarAlunos() {
const { rows: alunos } = await db.query(`
SELECT a.id, a.nome, a.telefone, c.titulo as curso, m.ultimo_acesso
FROM alunos a
JOIN matriculas m ON m.aluno_id = a.id
JOIN cursos c ON c.id = m.curso_id
WHERE m.ultimo_acesso < NOW() - INTERVAL '3 days'
AND m.ultimo_acesso > NOW() - INTERVAL '14 days'
AND m.status = 'ativa'
AND a.optin_whatsapp = true
AND m.reengajado_em IS NULL
`);
for (const aluno of alunos) {
const mensagem = `Oi, ${aluno.nome.split(" ")[0]}! 👋
Notei que você não acessa o curso "${aluno.curso}" há alguns dias. Tudo bem?
Continue de onde parou: https://plataforma.com.br/login
Se precisar de ajuda, é só responder esta mensagem.`;
try {
await ZAP.post(`/instances/${process.env.ZAP_INSTANCE}/messages`, {
type: "text",
to: "55" + aluno.telefone,
text: mensagem,
});
// Marca como reengajado para não duplicar
await db.query(
"UPDATE matriculas SET reengajado_em = NOW() WHERE aluno_id = $1",
[aluno.id]
);
} catch (err) {
console.error("Falha em", aluno.id, err.message);
}
}
}
reengajarAlunos();
Código: lembrete de aula ao vivo
async function lembrarAulaAoVivo(aulaId) {
const { rows: inscritos } = await db.query(`
SELECT a.nome, a.telefone, aula.titulo, aula.link, aula.inicio_em
FROM aulas aula
JOIN inscricoes_aula i ON i.aula_id = aula.id
JOIN alunos a ON a.id = i.aluno_id
WHERE aula.id = $1 AND a.optin_whatsapp = true
`, [aulaId]);
for (const i of inscritos) {
const horario = new Intl.DateTimeFormat("pt-BR", {
hour: "2-digit",
minute: "2-digit",
}).format(new Date(i.inicio_em));
const mensagem = `${i.nome.split(" ")[0]}, sua aula começa em 30 minutos!
📚 ${i.titulo}
🕐 Hoje às ${horario}
🔗 ${i.link}`;
await ZAP.post(`/instances/${process.env.ZAP_INSTANCE}/messages`, {
type: "text",
to: "55" + i.telefone,
text: mensagem,
});
}
}
Código: enviar certificado em PDF
Após gerar PDF do certificado, envie como documento direto pelo WhatsApp.
async function enviarCertificado(alunoId, cursoId) {
const { rows: [aluno] } = await db.query(
"SELECT nome, telefone FROM alunos WHERE id = $1",
[alunoId]
);
const urlCertificado = `https://cdn.plataforma.com.br/cert/${alunoId}/${cursoId}.pdf`;
// Mensagem texto antes
await ZAP.post(`/instances/${process.env.ZAP_INSTANCE}/messages`, {
type: "text",
to: "55" + aluno.telefone,
text: `Parabéns, ${aluno.nome.split(" ")[0]}! 🎓\n\nVocê concluiu o curso. Seu certificado está logo abaixo.`,
});
// Documento (PDF)
await ZAP.post(`/instances/${process.env.ZAP_INSTANCE}/messages`, {
type: "document",
to: "55" + aluno.telefone,
url: urlCertificado,
filename: "certificado.pdf",
caption: "Compartilhe nas suas redes! 🎉",
});
}
Código: áudio motivacional para turma
Toda segunda-feira de manhã, áudio do professor incentivando a turma. Aumenta sensação de proximidade.
async function audioMotivacional(turmaId, urlAudio) {
const { rows: turma } = await db.query(`
SELECT a.telefone, a.nome
FROM alunos a
JOIN matriculas m ON m.aluno_id = a.id
WHERE m.turma_id = $1 AND m.status = 'ativa'
AND a.optin_whatsapp = true
`, [turmaId]);
for (const aluno of turma) {
await ZAP.post(`/instances/${process.env.ZAP_INSTANCE}/messages`, {
type: "audio",
to: "55" + aluno.telefone,
url: urlAudio,
});
await new Promise(r => setTimeout(r, 1500)); // throttle 1.5s entre envios
}
}
Curl de teste
curl -X POST https://api.zap-api.tech/v1/instances/inst_xxx/messages \
-H "Authorization: Bearer tk_seu_token" \
-H "Content-Type: application/json" \
-d '{
"type": "document",
"to": "5511999998888",
"url": "https://exemplo.com/certificado.pdf",
"filename": "certificado.pdf",
"caption": "Parabéns!"
}'
FAQ
LGPD em EAD: qual base legal usar?
"Execução de contrato" (art. 7º, V da LGPD). O aluno comprou o curso, comunicação sobre o curso é parte da execução do contrato. Para mensagens de marketing (cross-sell de outros cursos), aí precisa de consentimento explícito separado.
Como funciona o opt-out do aluno?
No primeiro contato, deixe explícito como sair: "Para parar de receber, responda SAIR". Quando vier mensagem com "sair", "stop", "cancelar", marque opt_out_whatsapp=true e nunca mais envie. Implementação ~30 linhas de código.
Qual volume aguenta uma instância para EAD com 5.000 alunos ativos?
Uma instância suporta confortavelmente 1.000-2.000 mensagens/dia respeitando warmup. Para 5.000 alunos ativos, mantenha 2-3 instâncias com balanceamento por turma. Detalhes no post sobre escalar WhatsApp para 100mil/dia.
Tenho múltiplos cursos. Uso uma instância por curso?
Não. Use uma instância para a plataforma toda (ou 2-3 se volume justificar) e segmente lógica via tags/labels. Múltiplas instâncias dispersas confundem aluno (recebe mensagem de números diferentes).
Integração com Moodle/Hotmart é fácil?
Moodle expõe webhook nativo de eventos (matrícula, conclusão, atividade). Hotmart tem postback configurável. Em ambos, aponte o webhook para um servidor Node como o exemplo acima e mapeie evento → tipo de mensagem.
Próximo passo
Crie sua conta agora — trial 7 dias permite testar com lista de alunos real. Criar conta grátis.