Plano de Integração — RD Station Conversas + Agente Vila Secreta¶
Versão: 2.0
Data: 16/04/2026
API de referência: RD Station Conversas v2
Base URL da API:https://api.tallos.com.br/v2
1. Visão Geral¶
Integrar o agente de IA da Vila Secreta como canal de atendimento dentro do RD Station Conversas, complementando os fluxos que o cliente já possui. O cenário principal é: o cliente já usa RD Station Conversas com seus próprios fluxos de atendimento e quer que, em um momento específico da conversa, o fluxo "chame" nosso agente de IA para responder.
Canais suportados pela API¶
A API v2 do RD Station Conversas suporta exclusivamente mensagens de WhatsApp.
Arquitetura proposta — Flow chama Agente IA¶
┌──────────────┐ ┌─────────────────┐
│ Cliente │───WhatsApp────▶│ RD Station │
│ (WhatsApp) │ │ Conversas │
└──────────────┘ │ │
▲ │ ┌────────────┐ │
│ │ │ Flow do │ │
│ │ │ cliente │ │
│ │ │ (etapas │ │
│ │ │ existentes)│ │
│ │ └─────┬──────┘ │
│ │ │ │
│ │ forward-to │
│ │ "Flow IA" │
│ │ │ │
│ │ ┌─────▼──────┐ │
│ │ │ Flow IA │ │ ┌─────────────────────┐ ┌──────────────┐
│ │ │ (webhook) │──────▶│ unified_bot.py │────▶│ root_agent │
│ │ └────────────┘ │ │ /rdstation/webhook │ │ (Gemini) │
│ │ │ └──────────┬──────────┘ └──────────────┘
│ │ │ │
│ │◀─ send message ──────────────────┘
│◀─────────WhatsApp────────│ │
│ └─────────────────┘
2. Autenticação¶
A API segue OAuth 2.0 (RFC 6750). Todas as requisições usam o header:
Authorization: Bearer <seu_token_jwt>
Como obter o token¶
- Acessar o RD Station Conversas
- Ir em Apps e Integrações > API
- Copiar o token JWT gerado
Erros de autenticação¶
| Código | Descrição |
|---|---|
| 401 | Token ausente ou inválido |
| 403 | Token válido, mas sem permissão |
Variáveis de ambiente necessárias¶
RDSTATION_CONVERSAS_API_TOKEN=<jwt_token>
RDSTATION_CONVERSAS_WEBHOOK_SECRET=<secret_para_validar_webhooks>
3. Como o Fluxo do Cliente "Chama" o Agente de IA¶
Este é o cenário principal: o cliente já possui fluxos configurados no RD Station Conversas e quer que, em determinado ponto da conversa, o agente de IA Vila Secreta assuma o atendimento.
3.1 Conceito: Dois Fluxos + Forward¶
A API do RD Station Conversas oferece o endpoint POST /v2/forward-to-customer que permite encaminhar um contato de um fluxo para outro. A estratégia é:
- "Flow IA": um fluxo dedicado dentro do RD Station que serve como ponte — cada mensagem recebida nesse fluxo é encaminhada via webhook para nosso servidor
- Forward-to: quando o fluxo existente do cliente quer chamar a IA, ele usa
forward-to-customerpara mover o contato para o "Flow IA" - Retorno: quando a IA termina (handoff ou fim do atendimento), nosso servidor chama
forward-to-customerpara devolver o contato ao fluxo original ou à fila de atendentes
3.2 Fluxo Detalhado¶
Fluxo do Cliente Nossa API Agente IA
──────────────── ───────── ─────────
1. Cliente conversa normalmente
no fluxo existente do RD Station
2. Chega no ponto onde precisa da IA
(ex: etapa "Consultar catálogo",
"Falar com assistente virtual")
3. Fluxo executa ação:
POST /v2/forward-to-customer
{ customer: "<id>", flow: "<flow_ia_id>" }
4. RD Station move contato para
o "Flow IA"
5. "Flow IA" recebe a mensagem e
dispara webhook HTTP para
POST /rdstation/webhook ──────▶ Recebe webhook
{ contact_id, message, phone, com contexto
flow_origin: "<flow_original>" }
6. Busca histórico (opcional):
GET /v2/messages/history
?customer_id=<id>
7. Envia para ADK Runner ────▶ Processa com Gemini
Busca catálogo (BigQuery)
Gera resposta
8. ◀──── Resposta do agente
9. Envia resposta via API:
POST /v2/messages/<id>/send
{ message: "...", sent_by: "bot" }
10. Cliente recebe resposta no WhatsApp
11. Cliente envia nova mensagem
→ "Flow IA" dispara webhook novamente
→ Repete passos 5-10 (loop conversacional)
12. Quando a IA detecta handoff
(frustração, pedido explícito):
POST /v2/forward-to-customer
{ customer: "<id>",
flow: "<flow_humano_id>" }
13. Contato volta para fila de atendentes
ou para outro fluxo do cliente
3.3 Configuração no Painel do RD Station Conversas¶
O cliente precisa configurar no painel do RD Station:
Passo 1 — Criar o "Flow IA"¶
Criar um novo Flow (fluxo de chatbot) com:
- Nome: "Assistente IA Vila Secreta" (ou similar)
- Trigger: Nenhum trigger automático (será chamado via forward-to-customer)
- Etapa única: Webhook HTTP que chama nosso endpoint
- URL: https://<cloud-run-url>/rdstation/webhook
- Método: POST
- Headers: X-Webhook-Secret: <secret_compartilhado>
- Body: incluir contact_id, message, phone, metadados
Passo 2 — Modificar o Fluxo Existente¶
No fluxo atual do cliente, no ponto onde quer chamar a IA: - Adicionar uma etapa de "Encaminhar" (ou ação HTTP) que chame:
POST /v2/forward-to-customer
{
"customer": "{{contact_id}}",
"flow": "<id_do_flow_ia>"
}
Alternativamente, se o Flow Builder do RD Station suportar ação de "Encaminhar para outro fluxo" diretamente na interface, basta selecionar o "Flow IA" como destino.
Passo 3 — Obter o ID do Flow IA¶
Listar os fluxos via API para obter o ID:
curl -X GET https://api.tallos.com.br/v2/flows \
-H 'Authorization: Bearer <token>' \
-H 'Accept: application/json'
Resposta:
{
"flows": [
{ "id": "abc123...", "title": "Assistente IA Vila Secreta" },
{ "id": "def456...", "title": "Fluxo de Vendas" }
]
}
3.4 Modelos de Integração¶
Dependendo da necessidade do cliente, há dois modelos:
Modelo A — Single-Turn (Pergunta e Resposta)¶
O fluxo do cliente manda uma pergunta para a IA e espera uma resposta. Depois, o fluxo continua normalmente.
Flow do cliente → Forward para "Flow IA" → Webhook → IA responde → Forward de volta
Ideal para: consultas rápidas ao catálogo, verificação de disponibilidade, informações sobre experiências.
Implementação: O webhook recebe a mensagem, processa com o agente, envia a resposta, e imediatamente faz forward-to-customer para devolver ao fluxo original.
Modelo B — Multi-Turn (Conversa Livre com IA)¶
O fluxo do cliente "entrega" o contato para a IA, que mantém uma conversa livre até resolver a demanda ou fazer handoff para humano.
Flow do cliente → Forward para "Flow IA" → IA conversa livremente → Forward para humano ou de volta
Ideal para: atendimento consultivo, exploração do cardápio, dúvidas complexas, experiências sob demanda.
Implementação: O "Flow IA" mantém o contato em loop — cada mensagem gera um webhook, a IA responde, e o contato continua no "Flow IA" até:
- A IA resolver a demanda → forward-to-customer para fluxo de encerramento
- Handoff necessário → forward-to-customer para fila de atendentes
- Timeout (sem interação por X minutos) → forward-to-customer para fluxo padrão
3.5 Endpoint do Webhook para o "Flow IA"¶
@app.post("/rdstation/webhook")
async def rdstation_webhook(request: Request):
"""
Recebe mensagens do "Flow IA" do RD Station Conversas.
Payload esperado (configurable no Flow Builder):
{
"contact_id": "abc123",
"phone": "5511999998888",
"message": "Quais experiências vocês oferecem?",
"contact_name": "João",
"flow_origin": "def456" # ID do fluxo que originou
}
"""
# 1. Validar secret
# 2. Parsear para IncomingMessage
# 3. Processar com ConversationProcessor
# 4. Enviar resposta via POST /v2/messages/{contact_id}/send
# 5. Se handoff: POST /v2/forward-to-customer
3.6 Mapeamento de APIs para Cada Ação¶
| Ação | Endpoint API | Quem chama |
|---|---|---|
| Mover contato para "Flow IA" | POST /v2/forward-to-customer |
Flow do cliente (RD Station) |
| Receber mensagem do contato | Webhook HTTP configurado no "Flow IA" | RD Station → nosso servidor |
| Enviar resposta ao contato | POST /v2/messages/{contact_id}/send |
Nosso servidor |
| Buscar histórico da conversa | GET /v2/messages/history?customer_id=<id> |
Nosso servidor (opcional) |
| Devolver contato ao fluxo original | POST /v2/forward-to-customer |
Nosso servidor |
| Buscar dados do contato | GET /v2/contacts/{phone}/exists |
Nosso servidor |
| Listar fluxos disponíveis | GET /v2/flows |
Setup inicial |
3.7 Gestão de Estado entre Fluxos¶
Para o Modelo B (multi-turn), precisamos rastrear:
# Redis key: rdstation:session:{contact_id}
{
"contact_id": "abc123",
"phone": "5511999998888",
"flow_origin": "def456", # Para onde devolver
"adk_session_id": "sess_xyz", # Sessão do ADK
"started_at": "2026-04-16T...",
"last_message_at": "2026-04-16T...",
"mode": "multi_turn" # ou "single_turn"
}
3.8 Considerações sobre o Histórico¶
O endpoint GET /v2/messages/history tem requisitos importantes:
- Disponível apenas no plano Advanced
- Requer criptografia (dados retornam criptografados)
- Paginação por offset (page e limit, máximo 100 por página)
- Filtros: channel, sent_by (customer/operator/bot), type, start_date, end_date
Se o cliente tem plano Advanced, podemos buscar o histórico recente da conversa para dar contexto ao agente antes de responder. Se não tem, o agente começa a conversa sem contexto prévio do RD Station (mas pode ter contexto da sessão ADK se já houve interação anterior).
4. Endpoints da API que utilizaremos¶
4.1 Encaminhar contato entre fluxos (Forward)¶
POST /v2/forward-to-customer
Este é o endpoint central da integração. Permite mover um contato de um fluxo para outro.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| customer | string | Sim | ID do contato no RD Station |
| flow | string | Sim | ID do fluxo de destino |
Exemplo:
curl -X POST https://api.tallos.com.br/v2/forward-to-customer \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{"customer": "abc123", "flow": "def456"}'
Resposta: {"message": "Customer forwarded successfully"}
Usos na integração: - Fluxo do cliente → "Flow IA" (inicio do atendimento IA) - "Flow IA" → Fila de atendentes (handoff para humano) - "Flow IA" → Fluxo original (retorno após atendimento)
4.2 Receber mensagens (Webhook do Flow IA)¶
O "Flow IA" (criado na Seção 3.3) encaminha cada mensagem recebida para nosso endpoint via webhook HTTP configurado no Flow Builder.
4.3 Enviar mensagens¶
POST /v2/messages/{contact_id}/send
Parâmetros:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| contact_id | string | Sim (path) | ID do contato no RD Station |
| message | string | Sim | Texto da mensagem |
| sent_by | enum | Sim | bot ou operator |
| integration | string | Não | Chip de integração WhatsApp |
| operator | string | Não | ID do operador |
| attach | file | Não | Arquivo para enviar |
Exemplo:
curl -X POST https://api.tallos.com.br/v2/messages/{contact_id}/send \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'message=Olá! Como posso ajudar?&sent_by=bot'
Tipos de arquivo suportados: - Imagem: jpg, jpeg, png, bmp, ico, gif, svg - Áudio: mp3, wav, ogg, opus - Documento: pdf - Office: doc, docx, xls, xlsx, ppt, pptx - Texto: txt, csv - Compactados: zip, rar
4.4 Enviar mensagens via Template¶
POST /v2/messages/template/send
Útil para iniciar conversas proativas (fora da janela de 24h do WhatsApp).
4.5 Consultar contatos¶
GET /v2/contacts/{phone} # Por telefone
GET /v2/contacts/cpf/{cpf} # Por CPF
POST /v2/contacts # Criar múltiplos contatos
PATCH /v2/contacts/phone/{phone} # Atualizar por telefone
4.6 Listar integrações WhatsApp¶
GET /v2/whatsapp/integrations # Todas as integrações
GET /v2/whatsapp/official/integrations # Integrações oficiais
4.7 Workflows e Flows¶
GET /v2/workflows # Listar workflows (com stages)
GET /v2/flows # Listar fluxos do chatbot
POST /v2/flows/reset # Reiniciar fluxos de clientes
4.8 Analytics¶
GET /v2/analytics/attendances/retention # Retenção do chatbot
GET /v2/analytics/attendances/reviews/average # Média de reviews
5. Plano de Implementação¶
Fase 1 — Adapter RD Station Conversas¶
Criar messaging/adapters/rdstation_conversas_adapter.py seguindo o padrão existente (MessagingAdapter).
class RDStationConversasAdapter(MessagingAdapter):
"""
Adaptador para RD Station Conversas via API v2.
Base URL: https://api.tallos.com.br/v2
Auth: Bearer JWT token
Canal: WhatsApp
Integração: forward-to-customer + webhook do "Flow IA"
"""
def _validate_config(self) -> None:
# Requer: api_token, webhook_secret, flow_ia_id
...
async def setup(self) -> None:
# Inicializa httpx client com base_url e auth header
...
async def parse_incoming(self, request) -> IncomingMessage:
# Parsea webhook do "Flow IA" → IncomingMessage
...
async def send_message(self, message: OutgoingMessage) -> bool:
# POST /v2/messages/{contact_id}/send com sent_by=bot
...
async def forward_to_flow(self, contact_id: str, flow_id: str) -> bool:
# POST /v2/forward-to-customer — mover contato entre fluxos
...
async def get_contact(self, phone: str) -> dict:
# GET /v2/contacts/{phone}/exists — buscar dados do contato
...
async def handle_webhook_verification(self, request) -> dict:
# Valida X-Webhook-Secret do header
...
Tarefas:
- [ ] Criar classe
RDStationConversasAdapteremmessaging/adapters/ - [ ] Implementar client HTTP com
httpxe retry - [ ] Implementar
forward_to_flow()para encaminhar entre fluxos - [ ] Mapear payload do webhook do "Flow IA" →
IncomingMessage - [ ] Mapear
OutgoingMessage→ chamadaPOST /v2/messages/{contact_id}/send - [ ] Suporte a envio de arquivos (attach)
Fase 2 — Endpoint no unified_bot.py¶
Adicionar rota dedicada no FastAPI:
@app.post("/rdstation/webhook")
async def rdstation_webhook(request: Request):
"""
Webhook chamado pelo "Flow IA" do RD Station Conversas.
Recebe mensagens quando o fluxo do cliente encaminha
o contato para o agente de IA via forward-to-customer.
"""
...
Tarefas:
- [ ] Adicionar endpoint
POST /rdstation/webhook - [ ] Registrar adapter na
AdapterFactory(rdstation_conversas) - [ ] Configurar variáveis de ambiente no Cloud Run
- [ ] Adicionar endpoint no
ADAPTER_CLASSESda factory
Fase 3 — Gestão de Contatos, Sessão e Estado entre Fluxos¶
Mapear contatos do RD Station para nosso sistema de sessões e rastrear o fluxo de origem para poder devolver o contato.
# Redis key: rdstation:session:{contact_id}
{
"contact_id": "abc123",
"phone": "5511999998888",
"flow_origin": "def456", # Fluxo que originou o forward
"adk_session_id": "sess_xyz", # Sessão do ADK
"mode": "multi_turn", # ou "single_turn"
"started_at": "2026-04-16T...",
"last_message_at": "2026-04-16T..."
}
Tarefas:
- [ ] Mapear
contact_id→user_id+session_idpara sessão ADK - [ ] Consultar dados do contato via
GET /v2/contacts/{phone}/exists - [ ] Armazenar mapeamento + estado do forward no Redis
- [ ] Implementar timeout: se sem interação por X minutos, devolver ao fluxo original
Fase 4 — Configuração no Painel do RD Station Conversas¶
O cliente precisa configurar no painel do RD Station (ver detalhes na Seção 3.3):
- Criar o "Flow IA" com webhook apontando para
https://<cloud-run-url>/rdstation/webhook - Obter o ID do Flow IA via
GET /v2/flows - No fluxo existente, adicionar etapa de forward para o "Flow IA" no ponto onde quer chamar a IA
- Testar com contato de teste via WhatsApp
Fase 5 — Handoff (IA → Humano ou Fluxo Original)¶
Quando o agente detecta necessidade de handoff:
- O agente sinaliza handoff (já implementado no
PROMPT.md) - O adapter chama
POST /v2/forward-to-customerpara: - Fila de humanos: encaminha para fluxo de atendimento humano
- Fluxo original: devolve ao fluxo que originou (usando
flow_origindo Redis) - Remove a sessão RD Station do Redis
# Handoff para humano
await adapter.forward_to_flow(contact_id, FLOW_HUMANO_ID)
# OU devolver ao fluxo original
session = await redis.get(f"rdstation:session:{contact_id}")
await adapter.forward_to_flow(contact_id, session["flow_origin"])
Fase 6 — Testes e Validação¶
- [ ] Testes unitários do adapter (mock HTTP)
- [ ] Teste e2e: mensagem WhatsApp → RD Station → webhook → agente → resposta
- [ ] Teste de handoff IA → humano
- [ ] Cenários de avaliação no formato
.test.json - [ ] Teste de reconexão e retry em caso de falha na API
6. Variáveis de Ambiente¶
# RD Station Conversas
RDSTATION_CONVERSAS_API_TOKEN=<jwt_token_do_rdstation>
RDSTATION_CONVERSAS_WEBHOOK_SECRET=<secret_para_webhook>
RDSTATION_CONVERSAS_BASE_URL=https://api.tallos.com.br/v2
RDSTATION_CONVERSAS_WHATSAPP_INTEGRATION=<id_integracao_whatsapp>
RDSTATION_CONVERSAS_FLOW_IA_ID=<id_do_flow_ia>
RDSTATION_CONVERSAS_FLOW_HUMANO_ID=<id_do_flow_atendimento_humano>
# Adicionar ao MESSAGING_PLATFORMS
MESSAGING_PLATFORMS=sse,whatsapp_official,rdstation_conversas
7. Registro na AdapterFactory¶
Adicionar ao messaging/factory.py:
from .adapters.rdstation_conversas_adapter import RDStationConversasAdapter
ADAPTER_CLASSES = {
...
"rdstation_conversas": RDStationConversasAdapter,
}
8. Diagrama de Sequência¶
Cliente WhatsApp RD Station Nosso Server ADK Agent
│ │ Conversas (Cloud Run) (Gemini)
│──msg──────▶│ │ │ │
│ │───────────────▶│ │ │
│ │ │ forward-to │ │
│ │ │ "Flow IA" │ │
│ │ │──webhook POST──▶│ │
│ │ │ │──run_async()──▶│
│ │ │ │◀──resposta─────│
│ │ │◀─POST send msg─│ │
│ │◀───────────────│ │ │
│◀──msg──────│ │ │ │
│ │ │ │ │
│ (handoff) │ │◀─forward-to───│ │
│ │ │ flow humano │ │
│ │ │─────▶atendente │ │
9. Considerações Importantes¶
Regras de negócio (manter alinhamento com PROMPT.md)¶
- Reservas → site: manter comportamento de direcionar para
canonical_url - Handoff → forward-to-customer: quando necessário handoff para humano, usar
POST /v2/forward-to-customerpara mover o contato para o fluxo de atendimento humano no RD Station - Preços com "a partir de": mantido
- Não inventar informações: mantido
- Retorno ao fluxo original: após o agente resolver a demanda, usar
forward-to-customerpara devolver ao fluxo que originou
Limitações conhecidas¶
- A API do RD Station Conversas suporta apenas WhatsApp como canal
- Não há webhook nativo de "nova mensagem" — usamos o "Flow IA" com webhook como ponte
- O endpoint
GET /v2/messages/historyrequer plano Advanced e criptografia - A API pode ter limites de rate limiting (não documentados publicamente)
- O
forward-to-customerrequer o_idinterno do contato (não o telefone)
Segurança¶
- Token JWT armazenado em Secret Manager do GCP, nunca no código
- Validar assinatura/secret em todos os webhooks recebidos
- HTTPS obrigatório em todas as comunicações
- Sanitizar input antes de enviar ao agente
10. Cronograma Sugerido¶
| Fase | Descrição | Dependências |
|---|---|---|
| 1 | Criar adapter RDStationConversasAdapter |
— |
| 2 | Endpoint /rdstation/webhook no unified_bot.py |
Fase 1 |
| 3 | Mapeamento de contatos e sessões | Fase 1, 2 |
| 4 | Configurar no painel RD Station (Flow + webhook) | Fase 2 (deploy) |
| 5 | Implementar handoff IA → humano | Fase 1, 2, 3 |
| 6 | Testes e validação | Todas |