https://a.storyblok.com/f/270183/209892/f768baaf7b/how-to-build-a-dashboard-of-live-conversations-with-flask-and-react-2.png

Como criar um painel de conversas em tempo real com Flask e React

Publicado em November 11, 2020

Tempo de leitura: 10 minutos

A Vonage lançou recentemente a Conversation API. Essa API permite que você utilize diferentes formas de comunicação (voz, mensagens e vídeo) e as conecte entre si.

Agora é possível que várias conversas dentro de um aplicativo ocorram simultaneamente e que o contexto seja mantido em todos esses canais! A possibilidade de registrar e trabalhar com o histórico de uma conversa é extremamente valiosa tanto para as empresas quanto para os clientes; portanto, como você pode imaginar, estamos muito animados com isso.

O que o painel faz

Este tutorial explica como criar um painel com Flask e React que monitora todas as conversas em andamento em um aplicativo. O objetivo é apresentar dados relevantes das conversas que estão ocorrendo no momento, em tempo real.

Quando uma única conversa é selecionada na lista de conversas atuais, os membros e eventos serão exibidos. Um membro específico pode então ser selecionado para revelar ainda mais informações relacionadas a esse usuário.

dashboard gifdashboard gif

O que a Conversation API faz?

A API de Conversação da Vonage Conversation API permite que você desenvolva recursos de conversação nos quais a comunicação pode ocorrer por meio de diversos canais, incluindo mensagens IP, Voice PSTN, SMS e áudio e Video WebRTC. O contexto das conversas é mantido ao longo de cada evento de comunicação que ocorre dentro de uma conversa, independentemente do canal utilizado.

Pense em uma conversa como um conjunto de mensagens trocadas entre dois ou mais usuários. Pode se tratar de uma única interação ou de todo o histórico de todas as interações entre eles.

A API também permite criar Eventos e Etapas para possibilitar comunicações por texto, voz e Video entre dois Usuários e armazená-las em Conversas.

Fluxo de trabalho do aplicativo

flow of appflow of app

Criar uma aplicação da Vonage

Este tutorial também pressupõe que você estará executando o Ngrok para executar seu webhook localmente.

Caso você não esteja familiarizado com o Ngrok, consulte nosso tutorial do Ngrok antes de continuar.

Primeiro, você precisará criar uma Application:

nexmo app:create "Conversation App" http://demo.ngrok.io:3000/webhooks/answer http://demo.ngrok.io:3000/webhooks/event --keyfile private.key

Em seguida, supondo que você já tenha alugado um número da Vonage (NEXMO_NUMBER), você pode vincular seu número da Vonage ao seu aplicativo por meio da linha de comando:

nexmo link:app NEXMO_NUMBER APP_ID

Clonar repositório Git

Para colocar este aplicativo em funcionamento na sua máquina local, comece clonando este repositório:

git clone https://github.com/nexmo-community/nexmo-python-capi

Em seguida, instale as dependências:

npm install

Copie o arquivo de exemplo .env.example com o seguinte comando:

cp .env.example > .env

Abra esse novo .env arquivo e preencha o ID do aplicativo e o caminho para o seu private.key que acabamos de gerar ao criar nosso aplicativo Nexmo.

Backend do Flask

O arquivo importante a ser analisado em nossos arquivos do Flask é o server.py esse, pois ele define todos os diferentes endpoints que o Conversation API.

A função, make_capi_request() conecta-se ao Vonage e autentica o aplicativo:

def make_capi_request(api_uri):
   nexmo_client = nexmo.Client(
       application_id=os.getenv("APPLICATION_ID"), private_key=os.getenv("PRIVATE_KEY")
   )
   try:
       response = nexmo_client._jwt_signed_get(request_uri=api_uri)
   except nexmo.errors.ClientError:
       response = {}

   return jsonify(response)

Em seguida, criamos as rotas necessárias:

@app.route("/")
def index():  # Index page structure
   return render_template("index.html")

@app.route("/conversations")
def conversations():  # List of conversations
   return make_capi_request(api_uri="/beta/conversations")


@app.route("/conversation")
def conversation():# Conversation detail
   cid = request.args.get("cid")
   return make_capi_request(api_uri=f"/beta/conversations/{cid}")

@app.route("/user")
def user():  # User detail
   uid = request.args.get("uid")
   return make_capi_request(api_uri=f"/beta/users/{uid}")

@app.route("/events")
def events(): # Event detail
   cid = request.args.get("cid")
   return make_capi_request(api_uri=f"/beta/conversations/{cid}/events")

Após a autenticação, cada uma dessas rotas acessa a Conversation API com base no ID do aplicativo e, eventualmente, no ID da conversa ou do usuário.

Front-end React

Vamos aproveitar a capacidade do React de dividir nosso código em componentes modulares e reutilizáveis. Os componentes de que precisaremos são:

components - react treecomponents - react tree

No App.js nível, observe que o "/conversations" endpoint é chamado dentro do construtor. Isso significa que, se houver alguma conversa em andamento no aplicativo, ela será exibida imediatamente na página.

fetch("/conversations").then(response =>
  response.json().then(
    data => {
      this.setState({ conversations: data._embedded.conversations });
    },
    err => console.log(err)
  )
);

O usuário terá então a opção de selecionar uma das conversas da lista, e os metadados dessa conversa, como nome e data e hora, serão exibidos.

<div>
  <article className="message is-info">
    <div className="message-header">
      <p>{this.props.conversation.uuid}</p>
    </div>
    <div className="message-body">
      <ul>
        <li>Name: {this.props.conversation.name}</li>
        <li>ttl: {this.props.conversation.properties.ttl}</li>
        <li>Timestamp: {this.props.conversation.timestamp.created}</li>
      </ul>
    </div>
  </article>
  <Tabs
    members={this.props.conversation.members}
    events={this.props.events}
    conversation={this.props.conversation}
  />
</div>

Observe que, assim que uma determinada conversation for selecionado, duas abas ficam visíveis: Events e Members.

Members é definido como o estado padrão, o que significa que é exibido primeiro. É nesse momento que o "/conversation" e "/events" são chamados. Ao usar o cid que é passado dentro do estado, os detalhes dos membros e eventos atuais agora estão disponíveis.

refreshMembers = () => {
  fetch("/conversation?cid=" + this.props.conversation.uuid)
    .then(results => results.json())
    .then(data => {
      this.setState({ members: data.members });
    });
};

refreshEvents = () => {
  fetch("/events?cid=" + this.props.conversation.uuid)
    .then(results => results.json())
    .then(data => {
      this.setState({ events: data });
    });
};

O MembersList.js componente chamará o /user ponto de extremidade para recuperar ainda mais dados sobre esse usuário específico, que são então exibidos no MemberDetail.js componente.

showMemberDetails = user_id => {
  fetch("/user?uid=" + user_id)
    .then(results => results.json())
    .then(data => {
      this.setState({ member: data });
    });
};

Conecte tudo isso

Para iniciar o backend, execute o comando do Flask:

export FLASK_APP=server.py && flask run

E, em outra aba do seu terminal, execute o comando do React:

cd frontend-react && npm start

Abra http://localhost:3000 em um navegador, e seu aplicativo estará pronto para funcionar!

Todas as conversas que estiverem em andamento nesse aplicativo conectado passarão a ficar visíveis neste painel.

Parabéns! Você acabou de criar uma aplicação com Flask, React e a Conversation API. Agora você pode monitorar todo tipo de informação relacionada às conversas do seu aplicativo. Recomendamos que você continue experimentando e explorando os recursos dessa API.

Contribuições e próximos passos

A Conversation API está atualmente em fase beta e está em constante evolução com base nas suas sugestões e comentários. Como sempre, ficaremos felizes em ajudar com qualquer dúvida em nosso Slack da comunidade.

Compartilhar:

https://a.storyblok.com/f/270183/250x250/708316e4e8/laurenlee.png
Lauren LeeEx-funcionários da Vonage

Um professor de inglês que se tornou um engenheiro de software empático. Um otimista curioso, apaixonado por criar conteúdo acessível e ajudar desenvolvedores a aprimorar suas habilidades.