Ir para o conteúdo

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.