Trilha Avançada
Um chatbot que consulta imóveis de IPTU por CPF/CNPJ com exibição em botões
Nesse tutorial vamos construir um chatbot em que o usuário informa seu CPF ou CNPJ para consultar os imóveis vinculados ao seu cadastro de IPTU.
A partir do documento informado, uma integração será acionada e retornará uma lista de imóveis em formato de botões. Em seguida, o usuário deverá selecionar a opção desejada para continuar o atendimento.
O caminho-feliz do fluxo de conversa seria:
- Usuário: iptu
- Chatbot: IPTU 2026! Para consultar seus débitos, informe seu CPF ou CNPJ.
- Usuário: 12345678901
- Chatbot: Localizamos os seguintes imóveis vinculados ao documento informado:
- Botão: Rua A, 100 - Centro
- Botão: Rua B, 200 - Martins
- Botão: Avenida C, 300 - Brasil
- Chatbot: Escolha o imóvel desejado.
- Usuário: seleciona Rua B, 200 - Martins
- Chatbot: Você selecionou a opção 2. A próxima etapa poderá consultar a inscrição cadastral ou os débitos do imóvel escolhido.
Crie um Motor Rivescript no chatbot com o seguinte script:
! version = 2.0
+ iptu
- 🏠 IPTU 2026!<br><br>
^ Aqui você pode emitir a <b>guia única</b> de pagamento de forma rápida e prática 💳📄<br><br>
^ É só seguir as próximas etapas que eu te ajudo 😉<br><br>
^ Para que eu possa verificar seus débitos, preciso que você digite o seu CPF ou CNPJ 🧾<br><br>
^ 🔢 Informe somente os números (sem pontos, traços ou barras)<br><br>
^ Se preferir, digite sair para encerrar o atendimento 🚪
^ {topic=iptu_documento}
> topic iptu_documento
+ sair
- Atendimento encerrado. Até logo! 👋
^ {topic=random}
+ #
- <set cpfConsulta=<star>>
^ <call>buscarImovel "{'cpf':'<star>','ano':'2026'}"</call>
^ {topic=iptu_inscricao}
+ *
- CPF/CNPJ inválido.<br><br>
^ Informe somente os números, sem pontos, traços ou barras.
< topic
> topic iptu_inscricao
+ 1
- <call>buscarInscricao "{'opcao':'1','cpf':'<get cpfConsulta>','ano':'2026'}"</call>
^ {topic=iptu_debitos}
+ 2
- <call>buscarInscricao "{'opcao':'2','cpf':'<get cpfConsulta>','ano':'2026'}"</call>
^ {topic=iptu_debitos}
+ 3
- <call>buscarInscricao "{'opcao':'3','cpf':'<get cpfConsulta>','ano':'2026'}"</call>
^ {topic=iptu_debitos}
+ sair
- Atendimento encerrado. Até logo! 👋
^ {topic=random}
+ *
- Escolha uma das opções de imóvel abaixo:<br><br>
^ #options|{"label":"Rua A, 100 - Centro","value":"1"},{"label":"Rua B, 200 - Martins","value":"2"},{"label":"Avenida C, 300 - Brasil","value":"3"}|Escolha o imóvel desejado:|button|
^ <br><br>Se preferir, digite <b>sair</b> para encerrar o atendimento 🚪
< topic
> topic iptu_debitos
+ consultar debitos #
- <set inscricaoConsulta=<star>>
^ <call>buscarDebitos "{'inscricao':'<star>','ano':'2026'}"</call>
^ {topic=iptu_pagamento}
+ não
- Tudo bem. Atendimento encerrado. Até logo! 👋
^ {topic=random}
+ sair
- Atendimento encerrado. Até logo! 👋
^ {topic=random}
+ *
- Não entendi sua resposta.<br><br>
^ Escolha uma das opções exibidas ou digite <b>sair</b> para encerrar.
< topic
> topic iptu_pagamento
+ emitir guia #
- <set opcaoDebito=<star>>
^ <call>emitirGuia "{'inscricao':'<get inscricaoConsulta>','opcaoDebito':'<star>','ano':'2026'}"</call>
^ {topic=random}
+ sair
- Atendimento encerrado. Até logo! 👋
^ {topic=random}
+ *
- Opção inválida.<br><br>
^ Escolha uma das opções de débito exibidas ou digite <b>sair</b>.
< topic
A macro buscarImovel irá acionar a Integração de mesmo nome. Essa integração enviará para um endpoint o JSON contendo o CPF/CNPJ informado pelo usuário e o ano de exercício da consulta.
Exemplo de JSON enviado para a integração:
{
"cpf": "12345678901",
"ano": "2026"
}
Da forma como foi programado, espera-se que essa integração retorne uma resposta do tipo texto. Essa resposta será exibida diretamente ao usuário e deverá conter o comando #options para apresentar os imóveis encontrados em formato de botões.
Veja um exemplo abaixo de um endpoint feito em Python com Flask:
@app.route('/buscar-imoveis-options', methods=['POST'])
def buscar_imoveis_options():
obj = request.get_json()
logging.info(obj)
cpf = obj.get('cpf') if obj else None
ano = obj.get('ano') if obj else None
if not cpf or not ano:
mensagem = (
"CPF/CNPJ e ano são obrigatórios.<br><br>"
"Informe somente os números, sem pontos, traços ou barras."
)
return make_response(mensagem)
cpf = ''.join(filter(str.isdigit, cpf))
if len(cpf) not in [11, 14]:
mensagem = (
"CPF/CNPJ inválido.<br><br>"
f"O documento informado possui <b>{len(cpf)} dígitos</b>.<br><br>"
"Informe <b>11 dígitos para CPF</b> ou <b>14 dígitos para CNPJ</b>."
)
return make_response(mensagem)
if cpf == '00000000000':
mensagem = (
"Não localizamos imóveis vinculados ao documento informado.<br><br>"
"Confira os dados digitados e tente novamente.<br><br>"
"Se preferir, digite <b>sair</b> para encerrar o atendimento 🚪"
)
return make_response(mensagem)
mensagem = (
"🏠 Localizamos os seguintes imóveis vinculados ao documento informado:<br><br>"
"#options|"
'{"label":"Rua A, 100 - Centro","value":"1"},'
'{"label":"Rua B, 200 - Martins","value":"2"},'
'{"label":"Avenida C, 300 - Brasil","value":"3"}'
"|Escolha o imóvel desejado:|button|<br><br>"
"Se preferir, digite <b>sair</b> para encerrar o atendimento 🚪"
)
return make_response(mensagem)
Uso de tópicos no Rivescript
O Rivescript permite organizar as regras em tópicos.
Neste exemplo, o tópico iptu_documento é usado para aguardar o CPF/CNPJ informado pelo usuário. Após o envio do documento, o chatbot aciona a integração buscarImovel e muda o atendimento para o tópico iptu_inscricao.
O tópico iptu_inscricao é usado para aguardar que o usuário selecione uma das opções de imóvel exibidas em formato de botão.
Enviando dados para uma integração
A chamada para a integração é feita com a macro <call>, informando o nome da integração e um JSON com os dados necessários.
No exemplo, a chamada ficou assim:
<call>buscarImovel "{'cpf':'<star>','ano':'2026'}"</call>
O valor <star> representa o conteúdo digitado pelo usuário, ou seja, o CPF ou CNPJ informado na conversa.
Atenção! O JSON montado nessa chamada é definido entre aspas duplas e utiliza aspas simples para delimitar os campos e valores.
Guardando o CPF/CNPJ informado pelo usuário
Antes de chamar a integração, o CPF/CNPJ informado é armazenado em uma variável de contexto chamada cpfConsulta.
Isso é feito com o comando:
<set cpfConsulta=<star>>
Essa variável poderá ser reutilizada nas próximas etapas do atendimento, por exemplo, para buscar a inscrição cadastral do imóvel escolhido ou consultar os débitos vinculados ao documento.
Validação do CPF/CNPJ
O Rivescript usa o gatilho + # para aceitar apenas mensagens numéricas nesse ponto do fluxo.
Mesmo assim, a validação principal deve permanecer no backend, pois é ele que garante se o documento possui 11 dígitos para CPF ou 14 dígitos para CNPJ.
Caso o usuário informe um documento inválido, o endpoint pode retornar uma mensagem orientando o preenchimento correto.
Montando a lista de imóveis dinamicamente
No exemplo apresentado, a lista de imóveis é fixa apenas para fins de demonstração.
Em um cenário real, o endpoint provavelmente faria uma consulta em banco de dados, serviço legado ou API externa. A resposta textual seria montada dinamicamente, criando uma opção em formato de botão para cada imóvel encontrado.
Exemplo conceitual:
opcoes_imoveis = ""
for indice, imovel in enumerate(imoveis, start=1):
if opcoes_imoveis:
opcoes_imoveis += ","
opcoes_imoveis += (
f'{{"label":"{imovel["endereco"]}","value":"{indice}"}}'
)
mensagem = (
"🏠 Localizamos os seguintes imóveis vinculados ao documento informado:<br><br>"
"#options|"
f"{opcoes_imoveis}"
"|Escolha o imóvel desejado:|button|<br><br>"
"Se preferir, digite <b>sair</b> para encerrar o atendimento 🚪"
)
Depois que o usuário escolhe uma opção, o fluxo pode ser evoluído para uma nova integração, por exemplo buscarInscricao, responsável por recuperar a inscrição cadastral correspondente ao imóvel selecionado.
Exemplo de chamada possível:
<call>buscarInscricao "{'opcao':'<star>','cpf':'<get cpfConsulta>','ano':'2026'}"</call>
A partir dessa inscrição, o chatbot poderá consultar os débitos do imóvel e, nas próximas etapas, permitir a emissão da guia única de pagamento.