Pular para conteúdo

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:

  1. Notificações privadas: Enviar alertas pessoais sem expor em canais públicos
  2. Onboarding: Mensagens de boas-vindas para novos membros
  3. Alertas individuais: Notificar usuários sobre ações que os afetam
  4. Comunicação 1:1: Automatizar mensagens personalizadas

Como funciona internamente?

Quando a SLACK_SEND_DM é executada, o sistema:

  1. Abre ou localiza a conversa direta (DM) com o usuário
  2. Usa conversations.open para obter o canal DM
  3. Envia a mensagem usando chat.postMessage
  4. Se erro: Retorna erro detalhado (usuário não encontrado, bot sem permissão)
  5. 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

  1. Onboarding: "Olá João! Bem-vindo à empresa. Aqui está seu guia inicial..."
  2. Alertas pessoais: "Sua tarefa 'Deploy Prod' está atrasada"
  3. Notificações de aprovação: "Seu pedido de férias foi aprovado!"
  4. Lembretes: "Você tem uma reunião em 15 minutos"
  5. Informações sensíveis: Enviar senhas temporárias, links privados
  6. 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 diretas
  • users:read - Ler informações de usuários

Como obter:

  1. Acesse https://api.slack.com/apps
  2. Selecione seu App
  3. Em OAuth & Permissions, adicione scopes: im:write, users:read
  4. Reinstale o App se necessário
  5. 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:

  1. Clique no perfil do usuário
  2. Clique nos 3 pontos (...)
  3. 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