SLACK_REACT_MESSAGE - Adicionar Reação a Mensagem
O que é esta Tool?
A SLACK_REACT_MESSAGE é a tool responsável por adicionar reações emoji a mensagens do Slack programaticamente.
Por que esta Tool existe?
Reações são formas rápidas de feedback no Slack. A SLACK_REACT_MESSAGE existe para:
- Confirmação visual: Marcar mensagens como lidas/processadas
- Status tracking: Indicar status de tarefas (✅ feito, 🔄 em andamento, ❌ erro)
- Feedback automatizado: Reagir automaticamente a tipos específicos de mensagens
- Acknowledgment: Confirmar recebimento de mensagens importantes
Como funciona internamente?
Quando a SLACK_REACT_MESSAGE é executada, o sistema:
- Valida channel ID, timestamp da mensagem e emoji
- Verifica formato do emoji (deve ser nome válido, não emoji visual)
- Adiciona reação usando endpoint
reactions.add - Reação aparece na mensagem especificada
- Se erro: Retorna erro (mensagem não encontrada, emoji inválido, já reagiu)
- Se sucesso: Confirma adição da reação
Código interno (productivity-executors.service.ts - implementação futura):
async executeSlackReactMessage(data: any, variables: Record<string, any>): Promise<any> {
const { botToken, channel, timestamp, emoji } = data;
// Normalizar emoji (remover : se fornecido)
const emojiName = emoji.replace(/:/g, '');
const reactUrl = 'https://slack.com/api/reactions.add';
const response = await axios.post(reactUrl,
{
channel: channel,
timestamp: timestamp,
name: emojiName,
},
{
headers: {
'Authorization': `Bearer ${botToken}`,
'Content-Type': 'application/json',
}
}
);
if (!response.data.ok) {
// Ignorar se já reagiu
if (response.data.error === 'already_reacted') {
return {
success: true,
message: 'Already reacted to this message',
alreadyReacted: true,
};
}
throw new Error(`Failed to add reaction: ${response.data.error}`);
}
return {
success: true,
channel: channel,
timestamp: timestamp,
emoji: emojiName,
message: 'Reaction added successfully',
};
}
Quando você DEVE usar esta Tool?
Use SLACK_REACT_MESSAGE sempre que precisar de feedback visual em mensagens:
Casos de uso
- Confirmação de processamento: ✅ após processar webhook
- Status de tarefas: 🔄 processando, ✅ completo, ❌ erro
- Triagem: 👀 visto, 🚨 urgente, 💡 ideia
- Automação de workflows: Reagir quando ação é completada
- Tracking: 📝 documentado, 🔧 em correção, ✨ deployed
- Feedback de bots: Indicar que bot recebeu/processou mensagem
Quando NÃO usar SLACK_REACT_MESSAGE
- Comunicação: Use mensagens para comunicação real
- Spam: Não adicione múltiplas reações desnecessárias
- Informações complexas: Use mensagens, não reações
Parâmetros Detalhados
botToken (string, obrigatório)
O que é: Token de autenticação do Slack Bot.
Permissões necessárias:
- reactions:write - Adicionar reações
Flow completo para testar:
{
"name": "Teste Adicionar Reação",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "slack_1",
"type": "slack_send_message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Enviar Mensagem",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "C01234567",
"text": "Esta mensagem receberá uma reação automaticamente"
}
}
},
{
"id": "slack_2",
"type": "slack_react_message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Adicionar Reação",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "C01234567",
"timestamp": "{{ts}}",
"emoji": "white_check_mark"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "slack_1" },
{ "source": "slack_1", "target": "slack_2" },
{ "source": "slack_2", "target": "end_1" }
]
}
channel (string, obrigatório)
O que é: ID do canal onde está a mensagem.
Formatos aceitos:
- Channel ID público: C01234567
- Channel ID privado: G01234567
- DM ID: D01234567
Flow completo para testar:
{
"name": "Reagir em Canal Específico",
"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 Mensagem",
"parameters": {
"variableName": "msg",
"value": {
"canal": "C01234567",
"ts": "1234567890.123456"
}
}
}
},
{
"id": "slack_1",
"type": "slack_react_message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Adicionar ✅",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "{{msg.canal}}",
"timestamp": "{{msg.ts}}",
"emoji": "white_check_mark"
}
}
},
{
"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" }
]
}
timestamp (string, obrigatório)
O que é: Timestamp único da mensagem (formato: 1234567890.123456).
Como obter:
1. Quando enviar mensagem via SLACK_SEND_MESSAGE, o ts é retornado
2. Via webhook do Slack (eventos de mensagem incluem ts)
3. Via API history do canal
Formato: [segundos_unix].[microsegundos]
Exemplo: 1234567890.123456
Flow completo para testar:
{
"name": "Capturar TS e Reagir",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "slack_1",
"type": "slack_send_message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Enviar Mensagem",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "C01234567",
"text": "Tarefa criada: Implementar feature X"
}
}
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Salvar TS",
"parameters": {
"variableName": "messageTs",
"value": "{{ts}}"
}
}
},
{
"id": "slack_2",
"type": "slack_react_message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Marcar Em Andamento",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "C01234567",
"timestamp": "{{messageTs}}",
"emoji": "arrows_counterclockwise"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "slack_1" },
{ "source": "slack_1", "target": "variable_1" },
{ "source": "variable_1", "target": "slack_2" },
{ "source": "slack_2", "target": "end_1" }
]
}
emoji (string, obrigatório)
O que é: Nome do emoji a ser adicionado (SEM os dois pontos).
Formato aceito:
- ✅ Correto: white_check_mark
- ❌ Errado: :white_check_mark:
- ❌ Errado: ✅ (emoji visual)
Emojis comuns para automação:
Status:
white_check_mark (✅)
x (❌)
arrows_counterclockwise (🔄)
warning (⚠️)
Tracking:
eyes (👀)
raised_hands (🙌)
rocket (🚀)
tada (🎉)
Prioridade:
red_circle (🔴)
yellow_circle (🟡)
green_circle (🟢)
fire (🔥)
Lista completa: https://www.webfx.com/tools/emoji-cheat-sheet/
Flow completo para testar:
{
"name": "Múltiplas Reações",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "slack_1",
"type": "slack_send_message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Criar Tarefa",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "C01234567",
"text": "🔥 Tarefa urgente: Corrigir bug crítico em produção"
}
}
},
{
"id": "slack_2",
"type": "slack_react_message",
"position": { "x": 500, "y": 50 },
"data": {
"label": "👀 Visto",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "C01234567",
"timestamp": "{{ts}}",
"emoji": "eyes"
}
}
},
{
"id": "slack_3",
"type": "slack_react_message",
"position": { "x": 500, "y": 150 },
"data": {
"label": "🔴 Urgente",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "C01234567",
"timestamp": "{{ts}}",
"emoji": "red_circle"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "slack_1" },
{ "source": "slack_1", "target": "slack_2" },
{ "source": "slack_1", "target": "slack_3" },
{ "source": "slack_2", "target": "end_1" },
{ "source": "slack_3", "target": "end_1" }
]
}
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| botToken | string | Sim | Token do Bot (reactions:write) |
| channel | string | Sim | ID do canal (C01234567, G01234567, D01234567) |
| timestamp | string | Sim | Timestamp da mensagem (1234567890.123456) |
| emoji | string | Sim | Nome do emoji sem : (white_check_mark) |
Exemplo 1: Tracking de Status de Tarefa
Objetivo: Atualizar reação conforme status da tarefa muda
JSON para Importar
{
"name": "Status Tracking com Reações",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "slack_1",
"type": "slack_send_message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Criar Tarefa",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "C_TASKS",
"text": "📋 Tarefa: Deploy versão 2.0 para produção"
}
}
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Salvar TS",
"parameters": {
"variableName": "taskTs",
"value": "{{ts}}"
}
}
},
{
"id": "slack_2",
"type": "slack_react_message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Status: Em Andamento",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "C_TASKS",
"timestamp": "{{taskTs}}",
"emoji": "arrows_counterclockwise"
}
}
},
{
"id": "delay_1",
"type": "delay",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Simular Deploy",
"parameters": {
"duration": 300
}
}
},
{
"id": "slack_3",
"type": "slack_react_message",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Status: Completo",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "C_TASKS",
"timestamp": "{{taskTs}}",
"emoji": "white_check_mark"
}
}
},
{
"id": "slack_4",
"type": "slack_send_message",
"position": { "x": 1300, "y": 100 },
"data": {
"label": "Notificar Conclusão",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "C_TASKS",
"text": "✅ Deploy concluído com sucesso!",
"threadTs": "{{taskTs}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1500, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "slack_1" },
{ "source": "slack_1", "target": "variable_1" },
{ "source": "variable_1", "target": "slack_2" },
{ "source": "slack_2", "target": "delay_1" },
{ "source": "delay_1", "target": "slack_3" },
{ "source": "slack_3", "target": "slack_4" },
{ "source": "slack_4", "target": "end_1" }
]
}
Resultado:
Mensagem: 📋 Tarefa: Deploy versão 2.0 para produção
Reações: 🔄 (imediatamente) → ✅ (após 5min)
Thread: ✅ Deploy concluído com sucesso!
Exemplo 2: Confirmação de Webhook Processado
Objetivo: Reagir a mensagens de webhook para confirmar processamento
JSON para Importar
{
"name": "Confirmar Webhook Processado",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Webhook Recebido" }
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Dados Webhook",
"parameters": {
"variableName": "webhook",
"value": {
"canal": "C_WEBHOOKS",
"ts": "1234567890.123456",
"tipo": "new_order",
"pedido": "12345"
}
}
}
},
{
"id": "slack_1",
"type": "slack_react_message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "👀 Recebido",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "{{webhook.canal}}",
"timestamp": "{{webhook.ts}}",
"emoji": "eyes"
}
}
},
{
"id": "condition_1",
"type": "condition",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Processar?",
"parameters": {
"condition": "{{webhook.tipo}} == 'new_order'"
}
}
},
{
"id": "slack_2",
"type": "slack_react_message",
"position": { "x": 900, "y": 50 },
"data": {
"label": "✅ Processado",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "{{webhook.canal}}",
"timestamp": "{{webhook.ts}}",
"emoji": "white_check_mark"
}
}
},
{
"id": "slack_3",
"type": "slack_react_message",
"position": { "x": 900, "y": 150 },
"data": {
"label": "❌ Erro",
"parameters": {
"botToken": "xoxb-seu-token-aqui",
"channel": "{{webhook.canal}}",
"timestamp": "{{webhook.ts}}",
"emoji": "x"
}
}
},
{
"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": "condition_1" },
{ "source": "condition_1", "target": "slack_2", "label": "Sim" },
{ "source": "condition_1", "target": "slack_3", "label": "Não" },
{ "source": "slack_2", "target": "end_1" },
{ "source": "slack_3", "target": "end_1" }
]
}
Resposta da Tool
{
"success": true,
"channel": "C01234567",
"timestamp": "1234567890.123456",
"emoji": "white_check_mark",
"message": "Reaction added successfully"
}
Remover Reação
Para remover reação (API diferente):
POST /reactions.remove
{
"channel": "C01234567",
"timestamp": "1234567890.123456",
"name": "white_check_mark"
}
Scope necessário: reactions:write
Boas Práticas
✅ SIM:
- Usar reações para status visual rápido
- Combinar com threads para detalhes
- Usar sistema consistente (✅=completo, 🔄=em andamento, ❌=erro)
- Remover reações antigas ao adicionar novas (ex: trocar 🔄 por ✅)
- Usar reações como acknowledgment de bots
❌ NÃO:
- Não adicione múltiplas reações desnecessárias
- Não use reações para comunicação complexa
- Não abuse (reação em toda mensagem)
Dicas
💡 Status pipeline: 🔄 → ✅ (sucesso) ou ❌ (falha)
💡 Priorização: 🔴 urgente, 🟡 média, 🟢 baixa
💡 Workflow visual: Use reações consistentes para tracking
💡 Idempotência: Se já reagiu, API retorna already_reacted - trate como sucesso
💡 Emoji customizados: Workspaces podem ter emojis customizados - use o nome exato
Erros Comuns
message_not_found
Causa: Timestamp inválido ou mensagem deletada Solução: Verifique se timestamp está correto
invalid_name
Causa: Nome do emoji inválido Solução: Verifique lista de emojis válidos
already_reacted
Causa: Bot já adicionou esta reação Solução: Ignore (objetivo alcançado) ou remova primeiro
not_in_channel
Causa: Bot não é membro do canal Solução: Adicione bot ao canal
missing_scope
Causa: Bot não tem scope reactions:write
Solução: Adicione scope e reinstale app
Emojis Úteis para Automação
Status:
- ✅ white_check_mark - Completo
- 🔄 arrows_counterclockwise - Em andamento
- ❌ x - Erro
- ⚠️ warning - Atenção
- 🚨 rotating_light - Urgente
Tracking:
- 👀 eyes - Visto/Lido
- 🙌 raised_hands - Aprovado
- 🚀 rocket - Deployed
- 📝 memo - Documentado
- 🔧 wrench - Em correção
Prioridade:
- 🔴 red_circle - Alta
- 🟡 yellow_circle - Média
- 🟢 green_circle - Baixa
- 🔥 fire - Crítico
Próxima Tool
→ SLACK_SEND_MESSAGE - Enviar mensagem → SLACK_SEND_DM - Enviar DM → SLACK_UPLOAD_FILE - Upload arquivo