Tutorial: Automação Completa de Onboarding de Funcionários
Automatize todo o processo de integração de novos colaboradores: provisionamento de contas, envio de materiais, treinamentos e acompanhamento.
O Que Você Vai Construir
Sistema que: 1. Detecta novo funcionário no RH 2. Cria contas em todas as ferramentas (Google, Slack, GitHub, etc) 3. Envia kit de boas-vindas personalizado 4. Agenda treinamentos automáticos 5. Acompanha progresso e engajamento 6. Notifica gestores sobre marcos
Tempo estimado: 55 minutos Nível: Avançado Impacto: 85% menos tempo de RH, experiência consistente
Pré-requisitos
- ✅ Google Workspace API
- ✅ Slack API
- ✅ GitHub/GitLab API
- ✅ Sistema de RH (BambooHR, Gupy, ou similar)
Estrutura
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
employee_id VARCHAR(100) UNIQUE,
first_name VARCHAR(100),
last_name VARCHAR(100),
email VARCHAR(255) UNIQUE,
department VARCHAR(100),
position VARCHAR(255),
manager_email VARCHAR(255),
start_date DATE,
status VARCHAR(50) DEFAULT 'pending',
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE onboarding_tasks (
id SERIAL PRIMARY KEY,
employee_id INT REFERENCES employees(id),
task_type VARCHAR(100),
task_name VARCHAR(255),
description TEXT,
status VARCHAR(50) DEFAULT 'pending',
scheduled_for TIMESTAMP,
completed_at TIMESTAMP,
metadata JSONB
);
CREATE TABLE provisioned_accounts (
id SERIAL PRIMARY KEY,
employee_id INT REFERENCES employees(id),
service VARCHAR(100),
account_id VARCHAR(255),
username VARCHAR(255),
created_at TIMESTAMP DEFAULT NOW()
);
Parte 1: Detectar Novo Funcionário
// Webhook: Sistema de RH
// Transform: "Normalizar Dados"
{{
{
"employeeId": $trigger.body.employee_id,
"firstName": $trigger.body.first_name,
"lastName": $trigger.body.last_name,
"personalEmail": $trigger.body.personal_email,
"department": $trigger.body.department,
"position": $trigger.body.position,
"managerEmail": $trigger.body.manager_email,
"startDate": $trigger.body.start_date,
"companyEmail": `${$trigger.body.first_name.toLowerCase()}.${$trigger.body.last_name.toLowerCase()}@empresa.com`
}
}}
// Database Insert: "Registrar Funcionário"
{
"table": "employees",
"data": {
"employee_id": "{{ $nodes['normalizar'].output.employeeId }}",
"first_name": "{{ $nodes['normalizar'].output.firstName }}",
"last_name": "{{ $nodes['normalizar'].output.lastName }}",
"email": "{{ $nodes['normalizar'].output.companyEmail }}",
"department": "{{ $nodes['normalizar'].output.department }}",
"position": "{{ $nodes['normalizar'].output.position }}",
"manager_email": "{{ $nodes['normalizar'].output.managerEmail }}",
"start_date": "{{ $nodes['normalizar'].output.startDate }}",
"status": "onboarding"
},
"returning": ["id"]
}
Parte 2: Provisionamento de Contas
Google Workspace
// HTTP Request: "Criar Conta Google"
{
"method": "POST",
"url": "https://admin.googleapis.com/admin/directory/v1/users",
"headers": {
"Authorization": "Bearer {{ $credentials.google.accessToken }}",
"Content-Type": "application/json"
},
"body": {
"primaryEmail": "{{ $nodes['normalizar'].output.companyEmail }}",
"name": {
"givenName": "{{ $nodes['normalizar'].output.firstName }}",
"familyName": "{{ $nodes['normalizar'].output.lastName }}"
},
"password": "{{ Math.random().toString(36).slice(-12) }}TempPass!",
"changePasswordAtNextLogin": true,
"orgUnitPath": "/{{ $nodes['normalizar'].output.department }}",
"includeInGlobalAddressList": true
}
}
Slack
// HTTP Request: "Convidar para Slack"
{
"method": "POST",
"url": "https://slack.com/api/admin.users.invite",
"headers": {
"Authorization": "Bearer {{ $credentials.slack.adminToken }}",
"Content-Type": "application/json"
},
"body": {
"team_id": "{{ $credentials.slack.teamId }}",
"email": "{{ $nodes['normalizar'].output.companyEmail }}",
"real_name": "{{ $nodes['normalizar'].output.firstName }} {{ $nodes['normalizar'].output.lastName }}",
"channel_ids": ["{{ $vars.slackChannels.geral }}", "{{ $vars.slackChannels[$nodes['normalizar'].output.department.toLowerCase()] }}"]
}
}
GitHub
// HTTP Request: "Adicionar ao GitHub"
{
"method": "PUT",
"url": "https://api.github.com/orgs/{{ $vars.githubOrg }}/memberships/{{ $nodes['normalizar'].output.companyEmail.split('@')[0] }}",
"headers": {
"Authorization": "token {{ $credentials.github.token }}",
"Accept": "application/vnd.github.v3+json"
},
"body": {
"role": "member"
}
}
Registrar Contas
// Database Insert (Multiple): "Registrar Provisionamento"
{
"table": "provisioned_accounts",
"data": [
{
"employee_id": "{{ $nodes['registrar'].output.id }}",
"service": "google",
"account_id": "{{ $nodes['criar-google'].output.id }}",
"username": "{{ $nodes['normalizar'].output.companyEmail }}"
},
{
"employee_id": "{{ $nodes['registrar'].output.id }}",
"service": "slack",
"account_id": "{{ $nodes['slack'].output.user.id }}",
"username": "{{ $nodes['normalizar'].output.companyEmail }}"
},
{
"employee_id": "{{ $nodes['registrar'].output.id }}",
"service": "github",
"username": "{{ $nodes['normalizar'].output.companyEmail.split('@')[0] }}"
}
]
}
Parte 3: Kit de Boas-Vindas
Email Personalizado
// Send Email: "Boas-Vindas"
{
"to": "{{ $nodes['normalizar'].output.personalEmail }}",
"cc": "{{ $nodes['normalizar'].output.managerEmail }}",
"from": "rh@empresa.com",
"subject": "🎉 Bem-vindo(a) à Empresa!",
"html": `
<h1>Olá, {{ $nodes['normalizar'].output.firstName }}!</h1>
<p>Estamos muito felizes em ter você no time! 🚀</p>
<h2>📅 Seu Primeiro Dia</h2>
<p><strong>Data:</strong> {{ new Date($nodes['normalizar'].output.startDate).toLocaleDateString('pt-BR') }}</p>
<p><strong>Horário:</strong> 9h00</p>
<p><strong>Local:</strong> Escritório - Recepção</p>
<h2>📧 Suas Credenciais</h2>
<ul>
<li><strong>Email corporativo:</strong> {{ $nodes['normalizar'].output.companyEmail }}</li>
<li><strong>Senha temporária:</strong> Enviada separadamente</li>
</ul>
<h2>✅ Próximos Passos</h2>
<ol>
<li>Acesse seu email corporativo</li>
<li>Entre no Slack (convite enviado)</li>
<li>Complete o formulário de onboarding: <a href="{{ $vars.onboardingFormUrl }}">Clique aqui</a></li>
<li>Assista aos vídeos de boas-vindas</li>
</ol>
<h2>👥 Seu Time</h2>
<p><strong>Gestor:</strong> {{ $nodes['normalizar'].output.managerEmail }}</p>
<p><strong>Departamento:</strong> {{ $nodes['normalizar'].output.department }}</p>
<p>Qualquer dúvida, estamos aqui!</p>
<p>Equipe de RH</p>
`
}
Mensagem no Slack
// Delay: Aguardar 1 dia (para dar tempo de aceitar convite)
// Slack Message: "Boas-Vindas no Slack"
{
"channel": "{{ $vars.slackChannels.geral }}",
"text": "Novo membro no time!",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": `🎉 Pessoal, vamos dar as boas-vindas ao *{{ $nodes['normalizar'].output.firstName }} {{ $nodes['normalizar'].output.lastName }}*!\n\nEle(a) está entrando como *{{ $nodes['normalizar'].output.position }}* no time de *{{ $nodes['normalizar'].output.department }}*.\n\nVamos fazer com que se sinta em casa! 👋`
}
}
]
}
Parte 4: Treinamentos Automáticos
Criar Tarefas de Onboarding
// Function: "Gerar Tarefas"
{{
(() => {
const tasks = [
{
name: 'Assistir vídeo: Cultura da Empresa',
type: 'video',
scheduledFor: new Date($nodes['normalizar'].output.startDate),
url: 'https://empresa.com/videos/cultura'
},
{
name: 'Completar curso: Segurança da Informação',
type: 'course',
scheduledFor: new Date(new Date($nodes['normalizar'].output.startDate).getTime() + 24*60*60*1000),
url: 'https://lms.empresa.com/security'
},
{
name: 'Reunião 1:1 com Gestor',
type: 'meeting',
scheduledFor: new Date(new Date($nodes['normalizar'].output.startDate).getTime() + 2*24*60*60*1000)
},
{
name: 'Tour pelas ferramentas',
type: 'tutorial',
scheduledFor: new Date(new Date($nodes['normalizar'].output.startDate).getTime() + 3*24*60*60*1000)
},
{
name: 'Feedback 30 dias',
type: 'survey',
scheduledFor: new Date(new Date($nodes['normalizar'].output.startDate).getTime() + 30*24*60*60*1000)
}
];
return tasks;
})()
}}
// Database Insert (Batch): "Criar Tarefas"
{
"table": "onboarding_tasks",
"data": "{{ $nodes['gerar-tarefas'].output.map(task => ({ employee_id: $nodes['registrar'].output.id, task_type: task.type, task_name: task.name, scheduled_for: task.scheduledFor, metadata: JSON.stringify({ url: task.url }) })) }}"
}
Enviar Lembretes
Flow separado com Schedule Trigger (diário):
// Database Query: "Tarefas do Dia"
SELECT
t.*,
e.first_name,
e.email
FROM onboarding_tasks t
JOIN employees e ON e.id = t.employee_id
WHERE t.status = 'pending'
AND DATE(t.scheduled_for) = CURRENT_DATE
ORDER BY t.scheduled_for;
// Para cada tarefa:
// Send Email: "Lembrete de Tarefa"
{
"to": "{{ $item.email }}",
"subject": "📋 Lembrete: {{ $item.task_name }}",
"html": `
<h2>Olá, {{ $item.first_name }}!</h2>
<p>Você tem uma tarefa de onboarding pendente:</p>
<h3>{{ $item.task_name }}</h3>
<p>{{ $item.description || 'Complete quando puder!' }}</p>
{{ JSON.parse($item.metadata).url ? `<a href="${JSON.parse($item.metadata).url}" style="background: #5c6ac4; color: white; padding: 15px 30px; text-decoration: none; border-radius: 5px; display: inline-block;">Começar Agora</a>` : '' }}
`
}
Parte 5: Acompanhamento
Tracking de Progresso
// Webhook: Tarefa Completada
// Database Update: "Marcar Como Completa"
{
"table": "onboarding_tasks",
"data": {
"status": "completed",
"completed_at": "{{ new Date().toISOString() }}"
},
"where": {
"id": "{{ $trigger.body.task_id }}"
}
}
// Database Query: "Calcular Progresso"
SELECT
COUNT(*) as total_tasks,
COUNT(*) FILTER (WHERE status = 'completed') as completed_tasks,
ROUND(
COUNT(*) FILTER (WHERE status = 'completed')::DECIMAL /
NULLIF(COUNT(*), 0) * 100,
2
) as progress_percentage
FROM onboarding_tasks
WHERE employee_id = {{ $trigger.body.employee_id }};
Notificar Gestor
// If/Else: "Completou 100%?"
{{ $nodes['calcular-progresso'].output.rows[0].progress_percentage === 100 }}
// Branch TRUE:
// Send Email: "Onboarding Concluído"
{
"to": "{{ $item.manager_email }}",
"cc": "rh@empresa.com",
"subject": "✅ {{ $item.first_name }} completou o onboarding!",
"html": `
<h2>Parabéns!</h2>
<p><strong>{{ $item.first_name }} {{ $item.last_name }}</strong> completou todas as tarefas de onboarding! 🎉</p>
<p>Ele(a) está pronto(a) para começar a contribuir com o time.</p>
<p>Recomendamos agendar uma conversa para definir metas e expectativas.</p>
`
}
Parte 6: Dashboard de Métricas
-- Status de onboarding
SELECT
e.first_name || ' ' || e.last_name as employee,
e.department,
e.start_date,
COUNT(t.id) as total_tasks,
COUNT(t.id) FILTER (WHERE t.status = 'completed') as completed_tasks,
ROUND(
COUNT(t.id) FILTER (WHERE t.status = 'completed')::DECIMAL /
NULLIF(COUNT(t.id), 0) * 100,
2
) as progress,
EXTRACT(DAY FROM NOW() - e.start_date) as days_since_start
FROM employees e
LEFT JOIN onboarding_tasks t ON t.employee_id = e.id
WHERE e.status = 'onboarding'
GROUP BY e.id, e.first_name, e.last_name, e.department, e.start_date
ORDER BY e.start_date DESC;
-- Tempo médio de onboarding
SELECT
department,
AVG(EXTRACT(EPOCH FROM (MAX(t.completed_at) - e.start_date))/86400) as avg_days_to_complete
FROM employees e
JOIN onboarding_tasks t ON t.employee_id = e.id
WHERE e.status = 'active'
GROUP BY department;
Teste Completo
curl -X POST https://api.lumina.app.br/v1/webhooks/wh_new_employee \
-H "Content-Type: application/json" \
-d '{
"employee_id": "EMP001",
"first_name": "João",
"last_name": "Silva",
"personal_email": "joao.silva@gmail.com",
"department": "Engenharia",
"position": "Desenvolvedor Full Stack",
"manager_email": "gerente@empresa.com",
"start_date": "2025-02-01"
}'
Próximos Passos
- Slack Bot - Bot para responder dúvidas
- Invoice OCR - Processar documentos
- Analytics - Métricas de RH
Última atualização: Janeiro 2025