Pular para o conteúdo principal

Chatwoot

O que é?

Chatwoot é uma plataforma opensource de customer engagement que funciona como interface unificada para gerenciar conversas de múltiplos canais (WhatsApp, Instagram, Webchat, Email, etc.).

Website oficial: https://www.chatwoot.com Documentação: https://www.chatwoot.com/docs

Função no Sistema

  • Interface de mensageria: Recebe e envia mensagens de todos os canais
  • Gestão de conversas: Organiza conversas por status (aberta, resolvida, pendente)
  • Interface para atendentes: Dashboard web para atendimento humano
  • Roteamento: Distribui conversas entre agentes humanos e bots

Versão Utilizada

v4.0.1 (Docker)

Imagem Docker:

chatwoot/chatwoot:v4.0.1

Componentes

Quando instalado via EasyPanel, o Chatwoot cria 4 serviços:

  1. chatwoot (main): Aplicação web principal
  2. chatwoot-sidekiq: Workers para processar jobs assíncronos
  3. chatwoot-postgres: Banco de dados PostgreSQL
  4. chatwoot-redis: Cache e sistema de filas

Configurações Personalizadas

Para o funcionamento correto no sistema INCI, as seguintes variáveis de ambiente foram configuradas (tanto no serviço chatwoot quanto no sidekiq):

# Email (via SendGrid)
[email protected]
SMTP_ADDRESS=smtp.sendgrid.net
SMTP_AUTHENTICATION=plain
SMTP_DOMAIN=incibrasil.com.br
SMTP_ENABLE_STARTTLS_AUTO=true
SMTP_PORT=587
SMTP_USERNAME=apikey
SMTP_PASSWORD=<SENDGRID_API_KEY>

# Email Inbound
RAILS_INBOUND_EMAIL_SERVICE=sendgrid
RAILS_INBOUND_EMAIL_PASSWORD=<INBOUND_PASSWORD>
MAILER_INBOUND_EMAIL_DOMAIN=chat.incibrasil.com.br

# Storage (Google Cloud Storage)
ACTIVE_STORAGE_SERVICE=google
GCS_PROJECT=inci-api
GCS_CREDENTIALS=<GCP_SERVICE_ACCOUNT_JSON>
GCS_BUCKET=inci-chatwoot

# Performance
ENABLE_RACK_ATTACK_WIDGET_API=false
ENABLE_RACK_ATTACK=false
SIDEKIQ_CONCURRENCY=20
SIDEKIQ_TIMEOUT=30
Credenciais

As credenciais reais estão armazenadas com segurança nas variáveis de ambiente do EasyPanel.

File Mounts Personalizados

O Chatwoot foi customizado com file mounts para localização PT-BR e personalização de emails. Esses mounts devem ser configurados tanto no serviço chatwoot quanto no sidekiq através da aba Storage no EasyPanel.

/app/config/locales/pt_BR.yml

Arquivo de tradução para português brasileiro. Contém todas as strings da interface traduzidas, incluindo:

  • Mensagens de erro e validação
  • Notificações de sistema
  • Interface de atendimento
  • Templates de emails
Ver conteúdo completo do arquivo pt_BR.yml
pt_BR:
hello: 'Olá, mundo'
messages:
reset_password_success: Legal! A solicitação de alteração de senha foi bem sucedida. Verifique seu e-mail para obter instruções.
reset_password_failure: Uh ho! Não conseguimos encontrar nenhum usuário com o e-mail especificado.
inbox_deletetion_response: Seu pedido de exclusão da caixa de entrada será processado dentro de algum tempo.
errors:
validations:
presence: não pode ficar em branco
webhook:
invalid: Eventos inválidos
signup:
disposable_email: Não permitimos e-mails descartáveis
blocked_domain: Este domínio não é permitido. Se você acredita que isso é um erro, por favor contate o suporte.
invalid_email: Você digitou um email inválido
email_already_exists: 'Você já se cadastrou para uma conta com %{email}'
invalid_params: 'Inválido, por favor, verifique os parâmetros de inscrição e tente novamente'
failed: Registro falhou
# ... (arquivo completo com mais de 350 linhas de traduções)

/app/app/views/mailers/conversation_reply_mailer/email_reply.html.erb

Template para resposta individual de email (quando o contato responde por email):

<% if @message.content %>
<% if (message.content_type == 'input_csat' && message.message_type == 'template') %>
<p>Clique <a href="<%= message.conversation.csat_survey_link %>" _target="blank">aqui</a> para avaliar essa conversa.</p>
<% elsif message.content.present? %>
<%= ChatwootMarkdownRenderer.new(message.content).render_message %>
<% end %>
<% end %>
<% if @message.attachments %>
<% @message.attachments.each do |attachment| %>
Arquivos [<a href="<%= attachment.file_url %>" _target="blank">clique aqui para visualizar</a>]
<% end %>
<% end %>

/app/app/views/mailers/conversation_reply_mailer/reply_with_summary.html.erb

Template para email com resumo de múltiplas mensagens:

<p>Olá <%= @contact.name %>, tudo bem?</p>

<p>Há novas mensagens na conversa que você iniciou. Você pode responder esse e-mail para continuar a conversa!</p>

<% @messages.each do |message| %>
<tr>
<td>
<b><%= message.incoming? ? 'Você' : message.sender&.available_name || message.sender&.name || 'Robô' %></b>
</td>
</tr>
<tr>
<td style="padding: 0px 16px; margin: 4px 0 8px 0; background: #F5FAFF; border-radius: 5px; display: inline-block;">
<% if (message.content_type == 'input_csat' && message.message_type == 'template') %>
<p>Clique <a href="<%= message.conversation.csat_survey_link %>" _target="blank">aqui</a> para avaliar essa conversa.</p>
<% elsif message.content.present? %>
<%= ChatwootMarkdownRenderer.new(message.content).render_message %>
<% end %>
<% if message.attachments.count.positive? %>
<p>
<% if message.content.present? %>
<hr style="border: 0; border-bottom: 1px solid #AEC3D5;"/>
<% end %>
Essa mensagem contém <%= message.attachments.count > 1 ? 'arquivos' : 'um arquivo' %>.
<% message.attachments.each do |attachment| %>
<br />- Veja o arquivo <a href="<%= attachment.file_url %>" _target="blank">aqui</a>.
<% end %>
</p>
<% end %>
</td>
</tr>
<% end %>

/app/app/views/mailers/conversation_reply_mailer/reply_without_summary.html.erb

Template para emails sem resumo:

<% @messages.each do |message| %>
<p style="font-family: Roboto,'Helvetica Neue',Tahoma,Arial,sans-serif; text-align: start; unicode-bidi: plaintext;">
<% if message.content %>
<%= ChatwootMarkdownRenderer.new(message.content).render_message %>
<% end %>
<% if message.attachments %>
<% message.attachments.each do |attachment| %>
Arquivos [<a href="<%= attachment.file_url %>" _target="blank">clique aqui para visualizar</a>]
<% end %>
<% end %>
</p>
<% end %>

Como Aplicar os Mounts

  1. Acesse o EasyPanel
  2. Entre no projeto e vá até o serviço chatwoot
  3. Clique na aba Storage
  4. Adicione cada mount com o path e conteúdo correspondente
  5. Repita o processo para o serviço sidekiq
  6. Aplique as mudanças e faça o deploy em ambos os serviços

Instalação via EasyPanel

  1. No EasyPanel, vá em + New Service
  2. Selecione a aba Templates
  3. Escolha Chatwoot
  4. Configure as variáveis de ambiente listadas acima
  5. Aguarde o deploy automático

URL de Acesso: https://chatwoot.zamply.com.br

Próximos Passos

  • Consulte Dify para configurar a base de conhecimento
  • Veja N8N para entender a orquestração de workflows