Failover multiusuário e multicanal usando a Dispatch API
Este tutorial mostra como enviar uma mensagem para uma lista de usuários com failover automático.
A ideia é que você tenha uma lista de usuários e que cada um deles tenha dois ou mais canais designados, sendo que o último deles é o canal de reserva final. É feita uma tentativa de enviar a mensagem ao primeiro usuário da lista de prioridade, em seus canais designados. Cada canal é processado por vez, com uma condição de failover adequada.
Se todas as tentativas de fazer com que a mensagem seja lida por um usuário falharem, o processamento passa para o próximo usuário na lista de prioridades.
A título de exemplo, imagine que seu servidor principal tenha apresentado uma falha e você queira notificar uma lista de administradores de sistema que estão de plantão. Cada administrador pode ter vários canais pelos quais pode ser contatado. A lista de usuários seria processada até que pelo menos um dos administradores tivesse lido a mensagem importante.
Cenário de exemplo
Talvez a melhor maneira de entender esse caso de uso seja dar uma olhada no arquivo de configuração de exemplo, sample.json:
{
"APP": {
"APP_ID": "abcd1234-8238-42d0-a03a-abcd1234...",
"PRIVATE_KEY": "private.key"
},
"FROM": {
"MESSENGER": "COMPANY MESSENGER ID",
"VIBER": "COMPANY VIBER ID",
"WHATSAPP": "COMPANY WHATSAPP NUMBER",
"SMS": "COMPANY SMS NAME/NUMBER"
},
"USERS": [
{
"name": "Tony",
"channels": [
{
"type": "messenger",
"id_num": "USER MESSENGER ID"
},
{
"type": "sms",
"id_num": "USER PHONE NUMBER"
}
]
},
{
"name": "Michael",
"channels": [
{
"type": "viber_service_msg",
"id_num": "USER PHONE NUMBER"
},
{
"type": "whatsapp",
"id_num": "USER PHONE NUMBER"
},
{
"type": "sms",
"id_num": "USER PHONE NUMBER"
}
]
}
]
}
A parte mais importante desses arquivos de configuração é o USERS seção. Aqui você tem uma lista de prioridade dos usuários. Nesse caso, o aplicativo tentará enviar a mensagem para o Tony e, se o Tony não ler a mensagem em nenhum dos canais designados dentro do prazo de validade, o processo será repetido para o Michael.
NOTA: A condição de failover para cada canal de read com prazo de validade de 600 atualmente está codificado diretamente no aplicativo, mas poderia ser adicionado ao arquivo de configuração (consulte caso-3 (veja o código para saber como fazer isso).
Observe que se aplicam as seguintes condições:
- O usuário deve ter pelo menos dois canais.
- O usuário pode combinar qualquer número de canais e tipos, desde que haja pelo menos dois canais. Por exemplo, um usuário poderia ter três números de SMS e um ID do Messenger.
- O último canal especificado para um usuário será considerado o canal de fallback final. Ele é tratado de maneira um pouco diferente, pois não possui uma condição de failover associada a ele no modelo de fluxo de trabalho. Se houver falha nesse canal, o próximo usuário da lista será processado.
- O canal de reserva final não precisa ser o SMS, embora normalmente seja.
- Um fluxo de trabalho é criado individualmente para cada usuário, mas é possível definir um fluxo de trabalho específico para cada um deles.
- Procura-se aplicar um fluxo de trabalho a cada usuário na ordem em que eles estão listados no arquivo de configuração.
- A transição de um canal para o outro é automática e gerenciada de forma transparente pela Dispatch API.
Código-fonte
O código-fonte em Python deste projeto está disponível na comunidade Repositório do GitHub. Na verdade, há três casos de uso incluídos no código-fonte, mas este tutorial descreve apenas case-2. O código para case-2 pode ser encontrado, especificamente aqui. Há dois arquivos — o arquivo de configuração de exemplo, sample.json e o aplicativo, app.py.
Pré-requisitos
- Criar um Account na Vonage
- Instalar o Node.js - necessário para utilizar a Interface de Linha de Comando (CLI) da Vonage.
- Instale o CLI da Vonage
- Saiba como testar seu servidor de webhooks localmente
- Python 3 instalado
- Flask instalado
- Tenha contas nos canais que você deseja utilizar, como Facebook, Viber e WhatsApp.
Você também pode achar útil consultar os seguintes tópicos de visão geral:
Se você pretende testar esse caso de uso com o Facebook Messenger, é recomendável que você siga as etapas descritas em este tutorial primeiro.
As etapas
Depois que os pré-requisitos forem atendidos, as etapas são as seguintes:
- Criar uma aplicação da Vonage
- Configure o Ngrok
- Execute seu servidor de webhooks
- Analise o código do aplicativo
- Teste o aplicativo
Existem várias maneiras de obter o mesmo resultado com o Vonage. Este tutorial mostra apenas uma maneira específica de fazer as coisas; por exemplo, você verá como usar a linha de comando para criar o aplicativo, em vez do Painel de Controle. Outros tutoriais demonstram outras maneiras de fazer as coisas.
Crie sua aplicação Vonage
Se ainda não tiver feito isso, crie um novo diretório para o seu projeto, como, por exemplo, multi-user-dispatch. Vá para este diretório.
Use a CLI para criar seu aplicativo Vonage:
Anote o ID do aplicativo gerado. Você também pode verificar isso no painel de controle.
Esse comando também criará uma chave privada, multi_user_dispatch_app.key no diretório atual, bem como atualizar/criar vonage_app.json.
Este comando também configura os dois webhooks por meio dos quais ocorre toda a interação entre seu aplicativo e a Vonage. É necessário que você tenha um servidor em execução e acessível à Vonage nessas URLs
Configure o Ngrok
Certifique-se de que o Ngrok esteja em execução para realizar testes localmente. Para iniciar o Ngrok, digite:
Para gerar uma URL temporária do Ngrok. Se você for um assinante pago, pode digitar:
NOTA: Nesse caso, o Ngrok redirecionará os webhooks do Vonage que você especificou ao criar seu aplicativo do Vonage para localhost:9000.
Execute seu servidor de webhooks
Você precisa colocar seu servidor de webhooks em funcionamento para que os webhooks sejam reconhecidos e os detalhes das mensagens enviadas possam ser registrados. Seu servidor de webhooks seria semelhante ao seguinte:
from flask import Flask, request, jsonify
from pprint import pprint
app = Flask(__name__)
@app.route('/webhooks/inbound', methods=['POST'])
def inbound_message():
print ("** inbound_message **")
data = request.get_json()
pprint(data)
return ("inbound_message", 200)
@app.route('/webhooks/status', methods=['POST'])
def message_status():
print ("** message_status **")
data = request.get_json()
pprint(data)
return ("message_status", 200)
if __name__ == '__main__':
app.run(host="localhost", port=9000)
Adicione este código a um arquivo chamado server.py e salve-o.
Execute localmente com:
Analise o código do aplicativo
Por uma questão de praticidade, o código está contido em um único arquivo app.py. Há apenas isso e seu arquivo de configuração JSON, config.json, que pode ser criado inicialmente copiando sample.json.
Mais importante ainda, o arquivo de configuração armazena a lista de usuários a serem contatados em ordem de prioridade, além dos canais designados para cada um. Cada usuário deve ter pelo menos dois canais nesta implementação, mas pode haver qualquer combinação conveniente de canais por usuário. Por exemplo, um usuário pode ter três números de SMS, enquanto outro pode ter um ID do Messenger, um Viber e dois números de SMS adicionais.
O último canal listado para cada usuário é considerado como o recurso final antes da alternância para outro usuário. Para cada usuário, será enviada uma mensagem a cada canal por meio da Dispatch API, com automático mudar para o próximo canal caso a mensagem não seja lida em 600 segundos.
A primeira parte do código do aplicativo, app.py, lê o arquivo de configuração e carrega as variáveis e estruturas de dados importantes. Presume-se que sua empresa ofereça suporte a todos os quatro canais suportados pela Dispatch API, messenger, viber_service_msg, whatsapp e sms, embora seja possível atribuir aos usuários-alvo apenas seus canais preferidos. Alguns usuários, por exemplo, podem ser contatados apenas por SMS.
Existe uma função auxiliar, set_field_types, para lidar com o fato de que alguns canais utilizam numbers e alguns usam ids, e o Viber, que utiliza ambos ids e numbers.
A principal funcionalidade para esse caso de uso está no build_user_workflow função. Esse código cria um fluxo de trabalho como o seguinte:
{
"template": "failover",
"workflow": [
{
"from": {
"type": "messenger",
"id": "from_messenger"
},
"to": {
"type": "messenger",
"id": "user_id_num"
},
"message": {
"content": {
"type": "text",
"text": "This is a Facebook Messenger message sent using the Dispatch API"
}
},
"failover": {
"expiry_time": "600",
"condition_status": "read"
}
},
{
"from": {
"type": "viber_service_msg",
"id": "from_viber"
},
"to": {
"type": "viber_service_msg",
"number": "user_id_num"
},
"message": {
"content": {
"type": "text",
"text": "This is a Viber Service Message sent using the Dispatch API"
}
},
"failover": {
"expiry_time": "600",
"condition_status": "read"
}
},
{
"from": {
"type": "sms",
"number": "from_sms"
},
"to": {
"type": "sms",
"number": "user_id_num"
},
"message": {
"content": {
"type": "text",
"text": "This is an SMS sent using the Dispatch API"
}
}
}
]
}
A função build_user_workflow também garante que os valores lidos do arquivo de configuração sejam incorporados ao fluxo de trabalho.
Você provavelmente percebeu que o expiry_time e condition_status estão codificados de forma fixa no fluxo de trabalho como recursos integrados build_user_workflow. Isso foi feito para manter o código o mais simples possível, mas você poderia adicionar esses parâmetros ao arquivo de configuração individualmente para cada canal. Nesse caso, alguns usuários poderiam ter um tempo de expiração de 300 segundos em determinados canais, e você também poderia especificar a condição de failover de read ou delivered por canal. Isso já foi implementado para você em caso-3 mas não é abordado mais detalhadamente neste tutorial, pois todo o código é fornecido, juntamente com o arquivo de configuração de exemplo modificado.
Depois que o fluxo de trabalho estiver criado, você usa o Dispatch API para enviar a mensagem:
r = requests.post('https://api.nexmo.com/v0.1/dispatch', headers=headers, data=workflow)
Um JWT é gerado para autenticar a chamada à API. É por isso que você precisou anotar o app_id e private_key valores definidos quando você criou seu aplicativo Vonage. Eles precisam ser adicionados ao seu arquivo de configuração.
Teste o aplicativo
Copiar sample.json para config.json.
Certifique-se de ter definido os valores adequados em config.json para parâmetros como app_id, private_key e os detalhes dos diversos canais compatíveis. Certifique-se de ter configurado sua lista de usuários de acordo com a forma como deseja realizar os testes.
DICA: Vale a pena validar seu arquivo de configuração modificado neste momento usando um Validador de JSON.
Em seguida, você pode executar o aplicativo com:
O aplicativo processará o arquivo de configuração e entrará em contato com cada usuário, um por um, até que a mensagem seja lida.
SMS
Você pode usar qualquer celular capaz de receber SMS para testar este tutorial.
Facebook Messenger
Para realizar testes com o Facebook Messenger, são necessárias algumas etapas adicionais. Elas foram abordadas em detalhes em este tutorial, por isso essa informação não foi repetida aqui.
Viber
Você precisa de um ID de mensagem de serviço do Viber para testar este tutorial com o Viber.
Você precisa de um account comercial do WhatsApp para testar este tutorial com o WhatsApp. Além disso, é necessário enviar um MTM ao usuário de destino para que ele possa receber mensagens da sua empresa.
Resumo
Neste tutorial, você viu um caso de uso em que é possível tentar enviar uma mensagem para uma lista de usuários, sendo que cada usuário possui vários canais. O aplicativo é encerrado quando a mensagem é lida.