SLACK_SEND_DM - Enviar Mensagem Direta
O que é esta Tool?
A SLACK_SEND_DM é a tool responsável por enviar mensagens diretas (DMs) para usuários específicos do Slack usando a API oficial do Slack.
Por que esta Tool existe?
Mensagens diretas no Slack têm comportamento diferente de mensagens em canais. A SLACK_SEND_DM existe para:
- Notificações privadas: Enviar alertas pessoais sem expor em canais públicos
- Onboarding: Mensagens de boas-vindas para novos membros
- Alertas individuais: Notificar usuários sobre ações que os afetam
- Comunicação 1:1: Automatizar mensagens personalizadas
Como funciona internamente?
Quando a SLACK_SEND_DM é executada, o sistema:
- Abre ou localiza a conversa direta (DM) com o usuário
- Usa conversations.open para obter o canal DM
- Envia a mensagem usando chat.postMessage
- Se erro: Retorna erro detalhado (usuário não encontrado, bot sem permissão)
- Se sucesso: Retorna timestamp da mensagem e ID do canal DM
Código interno (productivity-executors.service.ts - implementação futura):
async executeSlackSendDM(data: any, variables: Record<string, any>): Promise<any> {
const { userId, text, botToken, blocks } = data;
// Passo 1: Abrir/obter canal DM
const openDMUrl = 'https://slack.com/api/conversations.open';
const openResponse = await axios.post(openDMUrl,
{ users: userId },
{
headers: {
'Authorization': `Bearer ${botToken}`,
'Content-Type': 'application/json',
}
}
);
if (!openResponse.data.ok) {
throw new Error(`Failed to open DM: ${openResponse.data.error}`);
}
const dmChannel = openResponse.data.channel.id;
// Passo 2: Enviar mensagem no canal DM
const sendUrl = 'https://slack.com/api/chat.postMessage';
const sendResponse = await axios.post(sendUrl,
{
channel: dmChannel,
text: text,
blocks: blocks || undefined,
},
{
headers: {
'Authorization': `Bearer ${botToken}`,
'Content-Type': 'application/json',
}
}
);
if (!sendResponse.data.ok) {
throw new Error(`Failed to send DM: ${sendResponse.data.error}`);
}
return {
success: true,
ts: sendResponse.data.ts,
channel: dmChannel,
message: 'DM sent successfully',
};
}
Quando você DEVE usar esta Tool?
Use SLACK_SEND_DM sempre que precisar de mensagens diretas e privadas:
Casos de uso
- Onboarding: "Olá João! Bem-vindo à empresa. Aqui está seu guia inicial..."
- Alertas pessoais: "Sua tarefa 'Deploy Prod' está atrasada"
- Notificações de aprovação: "Seu pedido de férias foi aprovado!"
- Lembretes: "Você tem uma reunião em 15 minutos"
- Informações sensíveis: Enviar senhas temporárias, links privados
- Follow-up automatizado: "Como foi sua primeira semana na empresa?"
Quando NÃO usar SLACK_SEND_DM
- Mensagens em canais: Use SLACK_SEND_MESSAGE para canais
- Comunicação de equipe: Use canais para transparência
- Anúncios gerais: Use canais ao invés de DM em massa
Parâmetros Detalhados
botToken (string, obrigatório)
O que é: Token de autenticação do Slack Bot (começa com xoxb-).
Permissões necessárias:
im:write- Enviar mensagens diretasusers:read- Ler informações de usuários
Como obter:
- Acesse https://api.slack.com/apps
- Selecione seu App
- Em OAuth & Permissions, adicione scopes:
im:write,users:read - Reinstale o App se necessário
- Copie o Bot User OAuth Token
Flow completo para testar:
{
"name": "Teste Slack DM - Simples",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "slack_1",
"type": "slack_send_dm",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Enviar DM",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"userId": "U01234567",
"text": "Olá! Esta é uma mensagem direta automática."
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ DM enviada com sucesso!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "slack_1" },
{ "source": "slack_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
userId (string, obrigatório)
O que é: ID único do usuário do Slack (começa com U).
Como obter o User ID:
Método 1 - Via Interface do Slack:
- Clique no perfil do usuário
- Clique nos 3 pontos (...)
- Selecione Copy member ID
Método 2 - Via API:
curl -X GET "https://slack.com/api/users.list" \
-H "Authorization: Bearer xoxb-seu-token"
Método 3 - Por email:
curl -X GET "https://slack.com/api/users.lookupByEmail?email=joao@empresa.com" \
-H "Authorization: Bearer xoxb-seu-token"
Flow completo para testar:
{
"name": "Teste Slack DM - User ID",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Definir User ID",
"parameters": {
"variableName": "slackUserId",
"value": "U01234567"
}
}
},
{
"id": "slack_1",
"type": "slack_send_dm",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Enviar DM",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"userId": "{{slackUserId}}",
"text": "Mensagem enviada para User ID: {{slackUserId}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "variable_1" },
{ "source": "variable_1", "target": "slack_1" },
{ "source": "slack_1", "target": "end_1" }
]
}
text (string, obrigatório)
O que é: Conteúdo da mensagem direta.
Formatação Markdown Slack:
*negrito*
_itálico_
~riscado~
`código`
<https://exemplo.com|Texto do link>
:emoji:
Menções:
Olá <@U01234567>! - Menciona o usuário
<!channel> - Menciona o canal (não funciona em DM)
<!here> - Menciona quem está online (não funciona em DM)
Flow completo para testar:
{
"name": "Teste Slack DM - Mensagem Formatada",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "slack_1",
"type": "slack_send_dm",
"position": { "x": 300, "y": 100 },
"data": {
"label": "DM Rica",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"userId": "U01234567",
"text": "🎉 *Bem-vindo à Empresa!*\n\nOlá, <@U01234567>!\n\nAqui estão seus _primeiros passos_:\n\n1. Acesse o <https://intranet.empresa.com|Portal Interno>\n2. Configure seu `perfil`\n3. Junte-se aos canais\n\n~Dúvidas?~ Entre em contato comigo! :smile:"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 500, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "slack_1" },
{ "source": "slack_1", "target": "end_1" }
]
}
blocks (array, opcional)
O que é: Array de blocos Slack Blocks API para mensagens interativas em DM.
Padrão: undefined
Exemplo de Blocks para DM:
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Ação necessária*\nPor favor, aprove o pedido:"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": { "type": "plain_text", "text": "Aprovar" },
"style": "primary",
"value": "approve",
"action_id": "approve_button"
},
{
"type": "button",
"text": { "type": "plain_text", "text": "Rejeitar" },
"style": "danger",
"value": "reject",
"action_id": "reject_button"
}
]
}
]
}
Teste no Block Kit Builder: https://api.slack.com/block-kit/building
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| botToken | string | Sim | Token do Bot (xoxb-...) com scope im:write |
| userId | string | Sim | ID do usuário Slack (U01234567) |
| text | string | Sim | Texto da mensagem (suporta Markdown) |
| blocks | array | Não | Blocks API para mensagens interativas |
Exemplo 1: Onboarding Automático
Objetivo: Enviar mensagem de boas-vindas para novos membros
JSON para Importar
{
"name": "Onboarding Slack DM",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Novo Membro",
"parameters": {
"variableName": "newUser",
"value": {
"id": "U01234567",
"name": "João Silva",
"email": "joao@empresa.com"
}
}
}
},
{
"id": "slack_1",
"type": "slack_send_dm",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Enviar Boas-Vindas",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"userId": "{{newUser.id}}",
"text": "🎉 *Bem-vindo à Empresa, {{newUser.name}}!*\n\nFicamos felizes em tê-lo(a) conosco!\n\n📚 *Próximos passos:*\n1. Complete seu perfil no <https://intranet.empresa.com|Portal>\n2. Junte-se aos canais: #geral, #random, #anuncios\n3. Agende um 1:1 com seu gestor\n\n💬 *Precisa de ajuda?*\nEstou aqui para isso! :smile:\n\n_Esta é uma mensagem automatizada do sistema de onboarding_"
}
}
},
{
"id": "delay_1",
"type": "delay",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Aguardar 1 hora",
"parameters": {
"duration": 3600
}
}
},
{
"id": "slack_2",
"type": "slack_send_dm",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Follow-up",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"userId": "{{newUser.id}}",
"text": "Olá {{newUser.name}}! 👋\n\nComo está sendo sua primeira hora aqui?\n\nJá conseguiu acessar tudo? Se tiver alguma dúvida, é só me chamar!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1100, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "variable_1" },
{ "source": "variable_1", "target": "slack_1" },
{ "source": "slack_1", "target": "delay_1" },
{ "source": "delay_1", "target": "slack_2" },
{ "source": "slack_2", "target": "end_1" }
]
}
Saída esperada:
Imediatamente:
🎉 Bem-vindo à Empresa, João Silva!
...
Após 1 hora:
Olá João Silva! 👋
Como está sendo sua primeira hora aqui?
...
Exemplo 2: Alerta Individual
Objetivo: Notificar usuário sobre tarefa atrasada
JSON para Importar
{
"name": "Alerta Tarefa Atrasada",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "slack_1",
"type": "slack_send_dm",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Notificar Usuário",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"userId": "U01234567",
"text": "⚠️ *Tarefa Atrasada*\n\n📋 Tarefa: _Deploy Produção_\n📅 Prazo: 14/01/2025\n⏰ Atrasada há: 1 dia\n🔗 <https://tasks.empresa.com/task/456|Ver tarefa>\n\nPor favor, atualize o status da tarefa o quanto antes."
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 500, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "slack_1" },
{ "source": "slack_1", "target": "end_1" }
]
}
Exemplo 3: Aprovação por DM
Objetivo: Solicitar aprovação com botões interativos
JSON para Importar
{
"name": "Pedido Aprovação DM",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Dados Pedido",
"parameters": {
"variableName": "pedido",
"value": {
"tipo": "Férias",
"solicitante": "Maria Santos",
"periodo": "01-15/02/2025",
"dias": 15
}
}
}
},
{
"id": "slack_1",
"type": "slack_send_dm",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Solicitar Aprovação",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"userId": "U01234567",
"text": "📋 *Novo Pedido de {{pedido.tipo}}*\n\n👤 Solicitante: {{pedido.solicitante}}\n📅 Período: {{pedido.periodo}}\n⏰ Dias: {{pedido.dias}}\n\nPor favor, aprove ou rejeite este pedido.",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "📋 *Novo Pedido de Férias*\n\n👤 Solicitante: Maria Santos\n📅 Período: 01-15/02/2025\n⏰ Dias: 15"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": { "type": "plain_text", "text": "✅ Aprovar" },
"style": "primary",
"value": "approve",
"action_id": "approve_ferias"
},
{
"type": "button",
"text": { "type": "plain_text", "text": "❌ Rejeitar" },
"style": "danger",
"value": "reject",
"action_id": "reject_ferias"
}
]
}
]
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "variable_1" },
{ "source": "variable_1", "target": "slack_1" },
{ "source": "slack_1", "target": "end_1" }
]
}
Resposta da Tool
{
"success": true,
"ts": "1234567890.123456",
"channel": "D01234567",
"message": "DM sent successfully"
}
Nota: O channel retornado é o ID do canal DM (começa com D), não um canal normal.
Boas Práticas
✅ SIM:
- Personalizar mensagens com nome do usuário
- Incluir contexto claro (por que está recebendo a DM)
- Usar formatação Markdown para legibilidade
- Incluir links úteis e próximos passos
- Respeitar horário comercial (evitar DMs às 3h da manhã)
- Identificar que é mensagem automatizada
- Usar Blocks API para ações interativas
❌ NÃO:
- Não envie spam ou mensagens não solicitadas
- Não envie informações sensíveis sem criptografia
- Não abuse de DMs em massa (use canais quando apropriado)
- Não envie DMs genéricas (personalize sempre)
Dicas
💡 User ID: Sempre use User ID (U01234567), não username (pode mudar)
💡 Personalização: Inclua nome do usuário e contexto específico
💡 Timing: Use node DELAY para espaçar mensagens de onboarding
💡 Interatividade: Blocks API funciona em DMs - use botões para ações
💡 Fallback: Sempre tenha um text mesmo ao usar blocks (para notificações)
💡 Privacidade: DMs são privadas - ideais para informações pessoais
Erros Comuns
user_not_found
Causa: User ID inválido Solução: Verifique o User ID usando API users.list
cannot_dm_bot
Causa: Tentando enviar DM para outro bot Solução: DMs só funcionam entre bots e usuários humanos
user_disabled
Causa: Usuário foi desativado no workspace Solução: Verifique status do usuário antes de enviar
missing_scope
Causa: Bot não tem scope im:write
Solução: Adicione scope e reinstale o app
Diferenças entre DM e Canal
| Aspecto | DM (slack_send_dm) | Canal (slack_send_message) |
|---|---|---|
| Scope | im:write |
chat:write |
| Privacidade | Privado (1:1) | Público/Privado (grupo) |
| ID começa com | D |
C (público) ou G (privado) |
| Menções @channel | Não funciona | Funciona |
| Uso | Notificações pessoais | Comunicação de equipe |
Próxima Tool
→ SLACK_SEND_MESSAGE - Enviar para canal → SLACK_UPLOAD_FILE - Upload de arquivos → SLACK_REACT_MESSAGE - Adicionar reação