A integração via Webhook tem como objetivo disponibilizar em real time os eventos gerados a partir das plataformas Invenio Center e Invenio Live.
- Mensagens enviadas e atualização de status de entrega
- Mensagens recebidas e atualização de status de recebimento
- KPI Eventos inseridos no ambiente (sejam eles feitos por usuário ou sistema)
- Campanhas e atualização de status
- Carteiras e atualização ou edição de suas configurações
- Status de templates HSM, bem como sua qualidade e alterações
- Status de linhas WhatsApp, bem como sua qualidade e alterações
- Relação de usuários, logs e alterações
- Protocolos com suas estatísticas e dados relacionados
Manual de Integração #
Como funciona a integração via Webhook+Enpoint? #
Este serviço serve como receptor de todas interações que constam no banco de dados Robbu, os objetos enviados em blocos JSON são: [contact], [event] ,[messageincoming], [messageoutgoing], [campaign], [template], [protocol], [wallet], [whatsapp numbers], [status].
Esse serviço enviará blocos de 30 arquivos JSON em um intervalo médio de 2 segundos.
Configuração #
1 – Download do projeto #
Comece fazendo o download do projeto de referência em:
Localize o arquivo Script_Tabelas_Robbu.sql, é nesse schema de tabelas que o serviço webhook irá popular as tabelas do banco de dados do endpoint.
Obs: O script de criação das tabelas foi criado em SQL, assim como os métodos de inserção dos dados estão considerando esse banco de dados. Trazemos dessa forma para que funcione como um facilitador, porém fica a critério da empresa a definição das tecnologias a serem utilizados, ficando sob total responsabilidade do próprio cliente manter em funcionamento.
2 – Publicação do Projeto: #
Essa solução é a interpretadora dos blocos JSON que o webhook irá disparar ao endpoint destino. Ela fica responsável por separar cada tipo de interação e salvar as informações no banco de dados externo.
Caso você já possua uma infraestrutura cloud/on-premises e queira reaproveitá-la, você pode publicar nossa solução neste mesmo servidor disponível.
Fique à vontade para utilizar um servidor novo. A prioridade aqui é que serviço de disparo consiga acessar externamente a partir de uma rota de execução.
3 – Recomendações para o deploy: #
O arquivo root da solução é apiv1.ashx. Ele é o responsável por fazer com que o processamento seja iniciado.
Sobre versionamento do .NET Framework, ele deve ser 4.6.1. e 4.8. Atente-se aos .NET instalados no servidor para que tenham compatibilidade com a solução.
A URL da solução publicada não contém restrições. É possível publicá-la a partir de qualquer rota e pode ser exposta em rota HTTP ou HTTPS. Recomendamos HTTPS pela segurança.
Também se faz necessária a liberação da relação de IP’s abaixo no firewall para garantir a conectividade da integração:
104.41.15.44, 104.41.14.184, 104.41.13.132, 104.41.12.97, 104.41.56.229, 104.41.30.250, 20.206.191.81, 191.235.52.58, 191.235.52.65, 191.235.52.78, 191.235.52.195, 191.235.52.245, 191.235.53.35, 191.235.53.57, 191.235.53.74, 191.235.53.158, 191.235.54.48, 191.235.54.59, 104.41.13.179
4- Recomendações iniciais de infraestrutura: #
Para um servidor endpoint de ambiente de produção recomendamos o setup mínimo:
- SSD de 250 GB
- 16 GB de RAM
- CPU com 4 núcleos.
Não recomendamos a utilização de um HD devido a velocidade e volume de mensagens de entrada, saída e eventos. O baixo desempenho pode gerar gargalos com a carga das replicações.
Esta é uma recomendação técnica inicial. A área de TI deve manter a gestão contínua da infraestrutura usada na solução devido a necessidade futura de escala. A solução a ser executada no servidor endpoint é desenvolvida em .NET, desta forma orientamos a usar produtos Microsoft. Recomendamos também a utilização de banco de dados SQL Server.
5 – Configuração final: #
Após configurar toda infraestrutura de servidor, banco de dados, liberações de firewall e publicação externamente do serviço webhook, acesse:
https://inveniocenter.robbu.com.br/painel/configuracoes > Webhook
Clique em gerenciar:
Adicione a URL final que foi gerada pelo Visual Studio ou pela IDE que foi utilizada e salve.
Após essa etapa aguarde em aproximadamente 60 minutos você deverá começar a receber as requisições em seu endpoint.
Mapeamento de Campos #
Abaixo apresentamos a estrutura de campos e tabelas para manipulação dos dados recebidos:
Tabela Message #
Campo | Descrição | Tipo |
MessageSentToProviderAt | Data e Hora do envio da mensagem ao provedor | Datetime |
MessageDeliveredAt | Data e Hora de entrega da mensagem | Datetime |
MessageReadAt | Data e Hora da leitura da mensagem | Datetime |
MessageFailedAt | Data e Hora da falha na entrega da mensagem | Datetime |
MessagemSentAt | Data e Hora do envio da mensagem | Datetime |
MessageReceivedAt | Data e Hora do recebimento da mensagem | Datetime |
MessageCampaignid | Id da campanha | Int |
MessageType | Tipo do envio da mensagem. | String |
MessageDirection | Informa se a mensagem é Outcoming(Saída) ou Incoming(Entrada). | String |
MessageId | Id da Mensagem | Long |
MessageChannel | Enumerador referente à mensagem. 1 – E-mail 2 – SMS 3 – Whatsapp 4 – Chat 5 – Facebook 6 – Telegram 7 – Voz 8 – Instagram 9 – Viber | Int |
MessageText | Texto da mensagem | String |
MessageSourceCountryCode | Código do país do remetente | Int |
MessageSourcePhoneNumber | Número de telefone do remetente | Long |
MessageSourceEmail | Email do remetente | String |
MessageDestinationCountryCode | Código do pais do destinatário | Int |
MessageDestinationPhoneNumber | Número de telefone do destinatário | Long |
MessageDestinationEmail | Email do destinatário | String |
ContactRobbuId | ID do contato na Robbu | Long |
ContactName | Nome do contato | String |
ContactID | Id do contato | String |
ContactCustomCode | Cod.Cliente do Contato | String |
ContactMainEmail | Email principal do contato | String |
ContactMainWhatsAppCountryCode | Código do pais da linha principal do WhatsApp do contato | Int |
ContactMainWhatsAppPhoneNumber | Número de telefone principal de WhatsApp do contato | Long |
ContactMainSmsCountryCode | Código do pais da linha principal de SMS do contato | Int |
ContactMainSmsPhoneNumber | Número de telefone principal de Sms do contato | long |
QueueWaitingSince | Data e Hora de início da espera do contato na fila da operação. | Datetime |
QueueFirstAnswerAt | Data e Hora da primeira resposta ao contato | Datetime |
ContactLastWalletCode | Código do último segmento do contato | String |
ContactLastWalletName | Nome do último segmento do contato | String |
ContactLastChannelDescripton | Descrição do último canal do contato | String |
ContactCreatedAt | Data e Hora da inclusão do contato | Datetime |
ContactLastAnswearAt | Data e Hora da última mensagem enviada ao contato pela operação | Datetime |
ContactLastIncomingMessageAt | Data e Hora da última mensagem recebida pelo contato | Datetime |
DigitalPostman | Informa se o envio é via Carteiro Digital | Bool |
LocationLatitude | Latitude da localização | Double |
LocationLongitude | Longitude da localização | Double |
FileUrl | URL do arquivo | String |
FileName | Nome do arquivo | String |
FileExtension | Extensão do arquivo | String |
ProtocolMessageId | Id do Protocolo | Long |
ProtocolMessageNumber | Número do Protocolo | String |
MessageErrorCode | Código da falha na entrega da mensagem | String |
ErrorMessage | Descrição da mensagem de erro | String |
MessageChannelDescription | Descrição do Canal | String |
MessageTemplateName | Nome do Template | String |
MessageTemplateId | Id do Template | Long |
Tabela Event #
Campo | Descrição | Tipo |
ID | Id do evento | Long |
Type | Tipo do evento: Negativo, Neutro ou Positivo | Datetime |
Description | Descrição do evento | String |
Note | Observação do evento | String |
CustomCode | Código customizado do evento | String |
Sender | Usuário responsável pelo evento | String |
Finalized | Indica se é um evento finalizador | Bool |
Type | Tipo do evento: negativo, neutro ou positivo | String |
ProtocolNumber | Número do protocolo | String |
ProtocolID | Id do Protocolo | Long |
ContactRobbuId | Id único do contato na Robbu | Long |
ContactName | Nome do contato | String |
ContactID | Id do contato | String |
ContactCustomCode | Cod.Cliente do Contato | String |
ContactMainEmail | Email principal do contato | String |
ContactMainWhatsAppCountryCode | Código do pais da linha principal do WhatsApp do contato | Int |
ContactMainWhatsAppPhoneNumber | Número de telefone principal de WhatsApp do contato | Long |
ContactMainSmsCountryCode | Código do pais da linha principal de SMS do contato | Int |
ContactMainSmsPhoneNumber | Número de telefone principal de Sms do contato | long |
QueueWaitingSince | Data e Hora de início da espera do contato na fila da operação. | Datetime |
QueueFirstAnswerAt | Data e Hora da primeira resposta ao contato | Datetime |
ContactLastWalletCode | Código do último segmento do contato | String |
ContactLastWalletName | Nome do último segmento do contato | String |
ContactLastChannelDescripton | Descrição do último canal do contato | String |
ContactCreatedAt | Data e Hora da inclusão do contato | Datetime |
ContactLastAnswearAt | Data e Hora da última mensagem enviada ao contato pela operação | Datetime |
ContactLastIncomingMessageAt | Data e Hora da última mensagem recebida pelo contato | Datetime |
Tabela Campaign #
Campo | Descrição | Tipo |
CreatedAt | Data e Hora de criação da campanha | Datetime |
CreatedBy | Usuário responsável pela campanha | String |
Id | Id da Campanha | Int |
Channel | Enumerador referente aos canais da campanha 1 – E-mail 2 – SMS 3 – Whatsapp 4 – Chat 5 – Facebook 6 – Telegram 7 – Voz 8 – Instagram 9 – Viber | Int |
ChannelDescription | Descrição do Canal | String |
StartAt | Data e Hora de início da campanha | Datetime |
Size | Quantidade de mensagens a serem enviadas | Int |
Message | Template enviado na campanha | String |
HoursToDiscard | Quantidade de horas definida, para caso o contato já esteja sendo atendido através de outros canais para ser removido da campanha da campanha realizada | Int |
TypeCampaignCode | Código interno do tipo de campanha • “EM” – E-mail • “SL” – SMS Long • “SS” – SMS Short • “VW” – Voz Way • “WB” – Whatsapp Broadcast • “WE” – WhatsApp Oficial Exclusivo • “WP” – Whastapp Prospect Convencional • “WO” ou “WC” – Whatsapp Oficial Compartilhado | String |
TypeCampaignDescription | Descrição do tipo de Campanha [1-SMS; 2- WhatsApp; 3- Email; 4- Voz] | String |
SplitSendPercentage | Percentual de intervalo para processar o número total de contatos no público selecionado | Double |
SplitSendMinutes | Intervalo de minutos para envio das mensagens | Int |
MailingDescription | Descrição do mailing | String |
MailingImportedAt | Data e hora da importação do mailing | Datetime |
MailingImportedBy | Usuário responsável pela importação do mailing | String |
MailingSize | Quantidade de registros no mailing | Int |
MailingWalletClientCode | Código da carteira do mailing | String |
TotalSent | Quantidade total de mensagens enviadas | Int |
CampaignLastSentAt | Data e Hora da última mensagem enviada | Datetime |
CampaignStatusCode | Código do status da campanha “C” – Cancelada “E” – Campanha não enviada “F” – Finalizada “I” – Iniciada “P” – Aguardando Processamento | String |
CampaignDescription | Descrição do tipo de campanha | String |
Tabela Template #
Campo | Descrição | Tipo |
Id | Id do Template | Long |
Name | Nome do Template | String |
Event | Status da ação realizada ao template: Updated, Created | String |
EventAt | Data e Hora inclusão/alteração | Datetime |
Status | Status do template na Meta [Approved; Reject; Deleted; Disabled] | String |
Quality | Qualidade do template na Meta: [Green; Yellow; Red; Deleted; Disabled] | String |
Category | Informa a categoria do template na Meta [Utility; Marketing; Service; Authentication] | String |
Language | Idioma do template | String |
Tabela Protocol #
Campo | Descrição | Tipo |
Event | Status da ação realizada ao protocolo [Updated; Created] | String |
EventAt | Data e Hora inclusão do protocolo | Datetime |
Id | Id do protocolo | Long |
Number | Número do protocolo | String |
GeneratedAt | Data e Hora geração do protocolo | Datetime |
GenerationChannelDescription | Descrição do Canal do protocolo gerado | String |
GenerationWalletName | Nome do segmento do protocolo gerado | String |
GenerationWalletCode | Código do segmento do protocolo gerado | String |
GenerationWalletId | Id do segmento gerado | Long |
SegmentId | Id do Segmento | Long |
SegmentName | Nome do Segmento | String |
ContactProtocolId | Id do protocolo do contato | String |
ContactProtocolRobbuId | Id do protocolo na Robbu | Long |
FirstMessageIdrAt | Data e Hora primeira mensagem IDR | Datetime |
LastMessageIdrAt | Data e Hora última mensagem IDR | Datetime |
IdrClosedAt | Data e Hora encerramento do atendimento na IDR | Datetime |
LastMessageContactIdrAt | Data e Hora última mensagem do contato enviada a IDR | Datetime |
FirstMessageFromHumanAttendanceAt | Data e Hora primeira mensagem da Operação | Datetime |
IdrMessagesCount | A soma total de mensagens enviada pela IDR | Long |
HumanAttendanceMessagesCount | A soma total de mensagens trocadas por atendentes no protocolo | Long |
IncomingMessagesCount | A soma total de mensagens recebidas no protocolo | Long |
HumanAttendanceAnswersCount | A soma total de respostas de atendentes no protocolo | Long |
ContactAnswersCount | A soma total de respostas do contato no protocolo | Long |
HumanAttendanceAnswersTotalTimeInSeconds | A soma total em segundos das respostas da operação no protocolo | Long |
ContactAnswersTotalTimeInSeconds | A soma total em segundos das respostas do contato no protocolo | Long |
IdrAnswersTotalTimeInSeconds | A soma total em segundos das respostas da IDR | Long |
IdrAnswersCount | A soma total de respostas da Idr no protocolo | Long |
ClosedAt | Data e Hora encerramento do protocolo | Datetime |
ClosingUserInfo | Nome do usuário encerramento do protocolo | String |
ClosingEventId | Id do evento encerramento | Long |
ClosingEventName | Nome do evento encerramento | String |
ClosingEventCode | Código do evento encerramento | String |
AbandonedAt | Data e Hora abandono protocolo | Datetime |
Tabela User #
Campo | Descrição | Tipo |
Id | Id do usuário | Long |
Name | Nome do usuário | String |
Event | Status da ação realizada ao usuário [Updated; Created] | String |
EventAt | Data e Hora criação/edição do usuário | Datetime |
Completename | Nome completo do usuário | String |
AcessGroup | Grupo de acesso do usuário | String |
AcessGroupDescription | Descrição do grupo de acesso do usuário | String |
EmailAddress | Endereço de email do usuário | String |
LastLoginAt | Data e Hora do último login do usuário | Datetime |
IsActive | Informa se o usuário esta ativo ou inativo na plataforma | Bool |
LastQueueUpdateAt | Data e Hora da última atualização da fila de atendimento | Datetime |
LastPasswordChangeAT | Data e Hora da última troca de senha do usuário | Datetime |
IsLogged | Informa se o usuário esta logado na plataforma | Bool |
Tabela Wallet #
Campo | Descrição | Tipo |
Id | Id do segmento | Long |
Name | Nome do segmento | String |
Code | Código do segmento | String |
Event | Status da ação realizada ao segmento [Updated; Created; Deleted] | String |
EventAt | Data e Hora da criação/edição do segmento | Datetime |
DistributionMethod | Método de distribuição de contatos do segmento | String |
DistributionMethodDescription | Descrição do metodo de distribuição | String |
Tabela WhatsApp Numbers #
Campo | Descrição | Tipo |
Event | Status da ação realizada a linha de WhatsApp [Created; Updated] | String |
EventAt | Data e Hora inclusão/alteração da linha WhatsApp | Datetime |
Id | Id da linha WhatsApp | Long |
WalletId | Id do segmento | Long |
Status | Qualidade da linha WhatsApp na Meta [Green; Yellow; Red; Unknown] | String |
CountryCode | Código do país | String |
AreaCode | Código de Area | String |
PhoneNumber | Número de telefone da linha WhatsApp | String |
IsActive | Informa se a linha WhatsApp está ativa | Bool |
BroadCastLimitPerDay | Limite de envios diário por dia (Informação recebida da Meta) | Int |
CanSendHsm | Informa se a linha está habilitada para envio de HSM | Bool |
Tabela Status #
Campo | Descrição | Tipo |
MessageStatusId | Id do status da mensagem | Long |
SourceStatusSender | Remetente do status de origem | String |
MessageStatusSentToProviderAt | Data e Hora do envio da mensagem ao provedor | Datetime |
MessageStatusDeliveredAt | Data e Hora da entrega da mensagem | Datetime |
MessageStatusReadAt | Data e Hora da leitura da mensagem | Datetime |
MessageStatusSentAt | Data e Hora envio da mensagem | Datetime |
MessageStatusFailedAt | Data e Hora da falha do envio da mensagem | Datetime |
MessageStatusDigitalPostman | Informa se a mensagem é do tipo de envio Carteiro Digital | Bool |
MessageStatusErrorCode | Código de erro da mensagem | String |
MessageStatusErrorMessage | Descrição do erro da mensagem enviada | String |
ContactStatusRobbuId | Id do status do contato na Robbu | Long |
Mensagem de entrada – Exemplo de json #
[{
"message": {
"receivedAt": "2020-01-31T02:01:03",
"direction": "incoming",
"id": 13232322244444,
"channel": 3,
"text": "Olá, teste whats!",
"source": {
"countryCode": 55,
"phoneNumber": 11999999992
},
"destination": {
"countryCode": 55,
"phoneNumber": 11944497777
},
"location": {
"latitude": -23.5535317,
"longitude": -46.6631181
},
"file": {
"url": "http://s.robbu.com.br/arquivo?hash=ROBBU",
"name": "robbu",
"extension": "pdf"
},
"contact": {
"robbuid": 11111111111,
"name": "TESTE ROBBU",
"customCode": "1372511",
"id": "00000000000",
"mainWhatsapp": {
"countryCode": 55,
"phoneNumber": 11999999992
},
"mainSMS": {
"countryCode": 55,
"phoneNumber": 11999999992
},
"mainEmail": "teste@robbu.global"
}
}
}]
Mensagem de Saida- Exemplo de json #
[{
"message": {
"sentAt": "2020-01-31T02:05:21.2900000",
"direction": "outgoing",
"id": 1323232224455555,
"channel": 3,
"type": "",
"text": "Teste envio whats!",
"campaignId": 1234,
"source": {
"countryCode": 55,
"phoneNumber": 11944497777,
"sender": ""
},
"destination": {
"countryCode": 55,
"phoneNumber": 11999999992
},
"file": {
"url": "http://s.robbu.com.br/arquivo?hash=ROBBU",
"name": "robbu",
"extension": "pdf"
},
"contact": {
"robbuid": 11111111111,
"name": "TESTE ROBBU",
"customCode": "1372511",
"id": "00000000000",
"mainWhatsapp": {
"countryCode": 55,
"phoneNumber": 11999999992
},
"mainSMS": {
"countryCode": 55,
"phoneNumber": 11999999992
},
"mainEmail": "teste@robbu.global",
"queue": {
"waitingSince": "2021-03-08 12:00:00",
"firstAnswerAt": "2021-03-08 11:30:00"
}
}
}
}]
Status de Mensagem – Exemplo de json #
[{
"status": {
"message": {
"id": 1323232224455555,
"source": {
"sender": "User1"
},
"sentToProviderAt": "2020-01-31T15:50:39.9312405",
"deliveredAt": "2020-01-31T15:51:52.9707831",
"readAt": "2020-01-31T15:53:14.6399299"
}
}
}]
Eventos – Exemplo de json #
[{
"event": {
"createdAt": "2020-01-31T02:05:21.0566667",
"id": 13232322244599998,
"description": "[CR] Saudacao Final",
"note": "Saudacao Final",
"customCode": "298",
"finalized": false,
"sender": "",
"type": "Neutro",
"contact": {
"robbuid": 11111111111,
"name": "TESTE ROBBU",
"customCode": "1372511",
"id": "00000000000",
"mainWhatsapp": {
"countryCode": 55,
"phoneNumber": 11999999992
},
"mainSMS": {
"countryCode": 55,
"phoneNumber": 11999999992
},
"mainEmail": "teste@robbu.global"
}
}
}]
Campanha – Exemplo de json #
[{
"campaign": {
"createdAt": "2020-01-27T22:01:12.2766667",
"createdBy": "User Robbu",
"id": 994545,
"channel": 1,
"startAt": "2020-01-27T21:59:00",
"size": 3102,
"message": "<html><body>Envio campanha email!<\/body><\/html>",
"hoursToDiscard": 0,
"type": {
"code": "EM",
"description": "EMAIL"
},
"splitSend": {
"percentage": 100.00,
"minutes": 0
},
"mailing": {
"description": "disparo_email",
"importedAt": "2020-01-27T21:54:16.5500000",
"importedBy": "User Robbu",
"size": 3102,
"walletClientCode": "1000"
}
}
}]
Campanha status – Exemplo de json #
[{
"status": {
"campaign": {
"id": 994545,
"totalSent": 91,
"lastSentAt": "2020-01-31T16:10:12.0633333",
"statusCode": "F"
}
}
}]