Integration com APIs de notificação: Slack, Telegram, email

1. Introdução à automação de notificações com Shell Script

Automatizar notificações é uma necessidade frequente em operações de TI: monitoramento de servidores, resultado de deploys, alertas de backup e falhas em processos críticos. O Shell Script oferece uma maneira leve e portátil de integrar-se a APIs de notificação sem depender de bibliotecas complexas ou linguagens interpretadas pesadas.

Três canais dominam esse cenário: Slack (via webhooks HTTP), Telegram (via Bot API) e email (via SMTP). Cada um tem características próprias de formato e entrega, mas todos podem ser acionados com curl, jq e utilitários Unix tradicionais. Para acompanhar os exemplos, tenha instalados: curl, jq, mailutils (ou sendmail/mutt), e um editor de texto.

2. Envio de notificações para o Slack via Webhook

O Slack oferece Incoming Webhooks, que são URLs únicas geradas por aplicativo. Para criar um:
1. Acesse api.slack.com/apps → Create New App → From scratch.
2. Ative Incoming Webhooks e adicione um webhook ao canal desejado.
3. Copie a URL gerada (ex: https://hooks.slack.com/services/T00/B00/xxxxx).

O payload deve ser JSON. O campo mínimo é text. Exemplo básico:

#!/bin/bash

SLACK_WEBHOOK_URL="https://hooks.slack.com/services/T00/B00/xxxxx"

curl -s -X POST -H "Content-type: application/json" \
  --data '{"text": "Deploy concluído com sucesso!"}' \
  "$SLACK_WEBHOOK_URL"

Para validação, verifique o código HTTP de retorno:

response=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
  -H "Content-type: application/json" \
  --data '{"text": "Teste de notificação"}' \
  "$SLACK_WEBHOOK_URL")

if [ "$response" -ne 200 ]; then
  echo "Erro ao enviar notificação Slack. HTTP $response"
fi

Para mensagens mais ricas, use attachments ou blocks:

payload=$(cat <<EOF
{
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "Servidor: $(hostname)\nStatus: OK\nTimestamp: $(date)"
      }
    }
  ]
}
EOF
)

curl -s -X POST -H "Content-type: application/json" --data "$payload" "$SLACK_WEBHOOK_URL"

3. Envio de mensagens para o Telegram via Bot API

Criar um bot no Telegram é simples:
1. No Telegram, procure por BotFather.
2. Envie /newbot e siga as instruções.
3. Guarde o token gerado (ex: 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11).

O endpoint principal é https://api.telegram.org/bot<TOKEN>/sendMessage. Exemplo de função reutilizável:

#!/bin/bash

TELEGRAM_TOKEN="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
CHAT_ID="-1001234567890"

send_telegram() {
  local message="$1"
  local parse_mode="${2:-HTML}"

  # Escapar caracteres especiais para JSON
  message=$(echo "$message" | sed 's/"/\\"/g')

  curl -s -X POST \
    "https://api.telegram.org/bot$TELEGRAM_TOKEN/sendMessage" \
    -d "chat_id=$CHAT_ID" \
    -d "text=$message" \
    -d "parse_mode=$parse_mode" \
    -d "disable_web_page_preview=true"
}

send_telegram "✅ <b>Backup concluído</b> em $(date)"

O parâmetro parse_mode permite usar HTML ou Markdown para formatação. Use disable_notification=true para silenciar a notificação no celular.

4. Envio de e-mails via SMTP e utilitários Unix

Para e-mail, o shell tem várias opções. A mais direta é mail (do pacote mailutils em Debian/Ubuntu ou mailx em RHEL/CentOS):

echo "Corpo da mensagem" | mail -s "Assunto do e-mail" destinatario@exemplo.com

Para autenticação SMTP, configure o ~/.mailrc ou use variáveis de ambiente com sendmail:

#!/bin/bash

SMTP_SERVER="smtp.exemplo.com:587"
SMTP_USER="seuemail@exemplo.com"
SMTP_PASS="sua_senha"
DESTINO="admin@exemplo.com"

send_email() {
  local subject="$1"
  local body="$2"

  curl --ssl-reqd --mail-from "$SMTP_USER" --mail-rcpt "$DESTINO" \
    --url "smtps://$SMTP_SERVER" \
    -u "$SMTP_USER:$SMTP_PASS" \
    -T <(echo -e "From: $SMTP_USER\nTo: $DESTINO\nSubject: $subject\n\n$body")
}

send_email "Alerta de CPU" "Uso de CPU acima de 90% em $(hostname)"

Para anexar logs, use uuencode (parte do sharutils) ou mutt:

uuencode /var/log/backup.log backup.log | mail -s "Log do backup" admin@exemplo.com

5. Formatação e personalização de mensagens

Mensagens dinâmicas melhoram a legibilidade. Use printf ou heredocs para templates:

#!/bin/bash

STATUS=$?
HOST=$(hostname)
DATA=$(date '+%Y-%m-%d %H:%M:%S')
LOG_LINK="https://logs.exemplo.com/backup/$DATA"

template=$(cat <<EOF
📦 <b>Relatório de Backup</b>
• Servidor: $HOST
• Data: $DATA
• Status: $( [ $STATUS -eq 0 ] && echo "✅ Sucesso" || echo "❌ Falha" )
• Logs: <a href="$LOG_LINK">Visualizar</a>
EOF
)

# Telegram
send_telegram "$template"

# Slack (usando jq para JSON)
slack_payload=$(jq -n --arg text "$template" '{text: $text}')
curl -s -X POST -H "Content-type: application/json" --data "$slack_payload" "$SLACK_WEBHOOK_URL"

O jq é essencial para construir JSON válido sem erros de escape. Exemplo com blocks:

slack_payload=$(jq -n \
  --arg host "$HOST" \
  --arg date "$DATA" \
  --arg status "$STATUS" \
  '{
    blocks: [
      { type: "section", text: { type: "mrkdwn", text: "Servidor: \($host)" } },
      { type: "section", text: { type: "mrkdwn", text: "Data: \($date)" } },
      { type: "section", text: { type: "mrkdwn", text: "Status: \($status)" } }
    ]
  }')

6. Boas práticas de segurança e resiliência

Nunca hardcode tokens ou senhas. Use um arquivo .env:

# .env
SLACK_WEBHOOK_URL="https://hooks.slack.com/..."
TELEGRAM_TOKEN="123:ABC"
SMTP_USER="user@exemplo.com"
SMTP_PASS="senha_segura"

Carregue com source .env e inclua .env no .gitignore.

Para evitar bloqueios por rate limiting, implemente retry com backoff:

retry_with_backoff() {
  local max_retries=3
  local delay=2
  local attempt=1

  while [ $attempt -le $max_retries ]; do
    if "$@"; then
      return 0
    fi
    echo "Tentativa $attempt falhou. Aguardando ${delay}s..."
    sleep $delay
    attempt=$((attempt + 1))
    delay=$((delay * 2))
  done

  return 1
}

retry_with_backoff curl -s -X POST -H "Content-type: application/json" \
  --data '{"text":"Teste"}' "$SLACK_WEBHOOK_URL"

Valide conectividade antes de enviar:

if ! curl -sf --max-time 5 https://api.telegram.org > /dev/null 2>&1; then
  echo "Sem conectividade com Telegram. Pulando notificação."
  exit 1
fi

7. Integração com outros scripts e pipelines

Crie uma função única de notificação que aceita o canal como parâmetro:

notify() {
  local channel="$1"
  local message="$2"

  case "$channel" in
    slack)   notify_slack "$message" ;;
    telegram) notify_telegram "$message" ;;
    email)   notify_email "$message" ;;
    all)     notify_slack "$message"; notify_telegram "$message"; notify_email "$message" ;;
  esac
}

Use traps para capturar erros automaticamente:

trap 'notify all "❌ Script falhou em $(date) - Código: $?"' ERR

# Seu script aqui
./backup.sh
notify slack "✅ Backup concluído com sucesso"

Para integração com cron, redirecione a saída e notifique condicionalmente:

# crontab
0 2 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1 || /opt/scripts/notify.sh "Falha no backup"

8. Conclusão e próximos passos

O Shell Script demonstra ser uma ferramenta extremamente flexível para integrar-se a APIs de notificação. Com curl, jq e alguns utilitários Unix, é possível cobrir Slack, Telegram e email de forma consistente e segura. A abordagem apresentada é leve, portátil e facilmente adaptável a outros canais como Discord, Microsoft Teams ou webhooks customizados.

Para evoluir, considere:
- Agregar logging estruturado em JSON para facilitar análise.
- Implementar health checks que notifiquem automaticamente times.
- Construir uma biblioteca de funções reutilizável para múltiplos projetos.

A simplicidade do shell é sua maior força — com poucas linhas, você conecta seus scripts ao mundo.

Referências