OlΓ‘, Marcelo.
Para esse cenΓ‘rio, eu avaliaria utilizar o External Contacts como uma camada de armazenamento operacional das informaΓ§Γ΅es dos clientes, em vez de distribuir os aproximadamente 20 mil registros entre vΓ‘rias Data Tables.
Em fluxos de chamadas inbound, o Genesys Cloud disponibiliza a variΓ‘vel nativa:
Call.ExternalContactId
Quando a interaΓ§Γ£o jΓ‘ estΓ‘ associada a um External Contact, essa variΓ‘vel contΓ©m o identificador interno do contato. Nesse caso, nΓ£o vejo necessidade de criar uma Data Action customizada apenas para pesquisar o registro.
O fluxo poderia utilizar diretamente a aΓ§Γ£o nativa Get External Contact, passando:
Call.ExternalContactId
A lΓ³gica seria semelhante a:
Chamada inbound
β
Call.ExternalContactId estΓ‘ preenchido?
βββ Sim
β β
β Get External Contact
β β
β InformaΓ§Γ΅es necessΓ‘rias estΓ£o preenchidas?
β βββ Sim β continuar o atendimento
β βββ NΓ£o β consultar a API do cliente
β
βββ NΓ£o
β
Consultar a API do cliente pelo ClientID
β
Utilizar as informaΓ§Γ΅es retornadas
β
Criar ou atualizar o External Contact
Na implementaΓ§Γ£o que utilizo atualmente, o comportamento Γ© parecido:
- O fluxo verifica se existe um External Contact associado Γ interaΓ§Γ£o.
- Quando existe, recupera as informaΓ§Γ΅es jΓ‘ armazenadas.
- Se os campos necessΓ‘rios estiverem preenchidos, o fluxo continua sem consultar o backend do cliente.
- Se o contato nΓ£o existir ou estiver sem as informaΓ§Γ΅es necessΓ‘rias, o fluxo consulta a API do cliente.
- A resposta da API pode ser utilizada para criar ou enriquecer o External Contact, permitindo que interaΓ§Γ΅es futuras utilizem as informaΓ§Γ΅es jΓ‘ armazenadas.
Esse modelo reduz a dependΓͺncia de consultas em tempo real ao sistema do cliente e utiliza o External Contacts como uma espΓ©cie de cache operacional.
Um ponto importante Γ© que Call.ExternalContactId depende de a interaΓ§Γ£o jΓ‘ ter sido associada a um contato.
Como vocΓͺ comentou que o ANI nem sempre Γ© confiΓ‘vel, podem existir chamadas em que a variΓ‘vel esteja vazia ou NOT_SET. Nesse cenΓ‘rio, o fallback por ClientID ainda seria necessΓ‘rio.
Mesmo assim, isso nΓ£o significa que todas as chamadas precisariam consultar o backend. A consulta seria realizada apenas quando:
- O External Contact nΓ£o estivesse identificado.
- O contato ainda nΓ£o tivesse sido criado.
- As informaΓ§Γ΅es necessΓ‘rias nΓ£o estivessem preenchidas.
- Os dados estivessem vencidos ou precisassem ser recalculados.
Para os dados adicionais, como propensΓ£o de reclamaΓ§Γ£o ou classificaΓ§Γ£o do cliente, poderiam ser utilizados custom fields do External Contact.
AtualizaΓ§Γ£o das informaΓ§Γ΅es
No meu caso atual, nΓ£o tenho necessidade de atualizar constantemente os dados jΓ‘ armazenados.
Entretanto, se as informaΓ§Γ΅es precisassem permanecer sincronizadas com o sistema de origem, vejo duas alternativas principais.
A primeira, e que considero mais eficiente, seria o sistema do cliente enviar um webhook para o backend de integraΓ§Γ£o quando alguma informaΓ§Γ£o fosse modificada:
AlteraΓ§Γ£o no sistema do cliente
β
Webhook para o backend
β
AtualizaΓ§Γ£o do External Contact
Dessa forma, somente os registros alterados seriam atualizados.
A segunda alternativa seria utilizar uma trigger programada para iniciar um Workflow ou chamar um backend responsΓ‘vel por consultar os registros modificados desde a ΓΊltima sincronizaΓ§Γ£o:
Scheduled Trigger
β
Workflow ou backend
β
Consulta por registros modificados
β
AtualizaΓ§Γ£o dos External Contacts
Eu evitaria varrer os 20 mil registros a cada execuΓ§Γ£o. O ideal seria utilizar algum campo como:
updatedAt
lastModifiedDate
lastSyncDate
para executar uma sincronizaΓ§Γ£o incremental.
Volume e limites
Se o volume de chamadas simultΓ’neas ou de atualizaΓ§Γ΅es fosse muito alto, eu tambΓ©m recomendaria abrir um ticket com o suporte da Genesys.
O objetivo do ticket seria solicitar uma avaliaΓ§Γ£o de capacidade e dos limites aplicΓ‘veis ao caso de uso, apresentando informaΓ§Γ΅es como:
- Chamadas por minuto no horΓ‘rio de pico.
- Quantidade de consultas por interaΓ§Γ£o.
- NΓΊmero esperado de atualizaΓ§Γ΅es.
- ConcorrΓͺncia mΓ‘xima.
- Crescimento projetado.
- Endpoints utilizados.
A partir desses dados, a Genesys poderia avaliar se os limites atuais atendem ao cenΓ‘rio ou se existe alguma possibilidade de ajuste.
Minha proposta arquitetural seria:
External Contacts
= cache operacional no Genesys Cloud
API do cliente
= fonte oficial das informaΓ§Γ΅es
Call.ExternalContactId + Get External Contact
= consulta nativa dentro do fluxo
Webhook ou sincronizaΓ§Γ£o incremental
= atualizaΓ§Γ£o dos dados
API em tempo real
= fallback
Esse modelo nΓ£o elimina completamente a API do cliente, mas evita chamΓ‘-la em todas as interaΓ§Γ΅es.
A consulta ao backend acontece apenas quando o Genesys Cloud ainda nΓ£o possui um contato identificado ou quando os dados armazenados nΓ£o sΓ£o suficientes.
VocΓͺ jΓ‘ avaliou utilizar Call.ExternalContactId com a aΓ§Γ£o nativa Get External Contact dessa forma?
Hi Marcelo,
For this scenario, I would consider using External Contacts as an operational storage layer for customer information instead of distributing approximately 20,000 records across multiple Data Tables.
In inbound call flows, Genesys Cloud provides the following built-in variable:
Call.ExternalContactId
When the interaction is already associated with an External Contact, this variable contains the contact's internal identifier. In that situation, I do not see a need to create a custom Data Action only to search for the record.
The flow could directly use the native Get External Contact action and pass:
Call.ExternalContactId
The logic could be structured as follows:
Inbound call
β
Is Call.ExternalContactId populated?
βββ Yes
β β
β Get External Contact
β β
β Are the required fields populated?
β βββ Yes β continue the customer journey
β βββ No β query the customer API
β
βββ No
β
Query the customer API using ClientID
β
Use the returned information
β
Create or update the External Contact
The implementation I currently use follows a similar pattern:
- The flow verifies whether an External Contact is associated with the interaction.
- When a contact exists, the flow retrieves the information already stored in Genesys Cloud.
- If the required fields are populated, the flow continues without querying the customer's backend.
- If the contact does not exist or does not contain the required information, the flow calls the customer API.
- The API response can be used to create or enrich the External Contact so that future interactions can use the stored information.
This approach reduces the dependency on real-time calls to the customer's system and uses External Contacts as an operational cache.
One important consideration is that Call.ExternalContactId depends on the interaction already being associated with a contact.
Since you mentioned that ANI is not always reliable, there may be calls where this variable is empty or NOT_SET. In that situation, the fallback lookup using ClientID would still be required.
However, this does not mean that every interaction must query the backend. The API call would only be necessary when:
- The External Contact was not identified.
- The contact has not yet been created.
- The required information is missing.
- The stored data has expired or must be recalculated.
Additional information, such as complaint propensity or customer classification, could be stored in External Contact custom fields.
Keeping the information updated
In my current implementation, I do not need to continuously refresh information that has already been stored.
However, if the information had to remain synchronized with the source system, I would consider two main approaches.
The first, and in my opinion the most efficient, would be for the customer's system to send a webhook to the integration backend whenever a record changes:
Change in the customer system
β
Webhook to the backend
β
Update the External Contact
This way, only changed records would be updated.
The second option would be to use a scheduled trigger to start a Workflow or call a backend service responsible for retrieving records modified since the last synchronization:
Scheduled Trigger
β
Workflow or backend
β
Retrieve modified records
β
Update External Contacts
I would avoid scanning all 20,000 records during every execution. An incremental synchronization should preferably use a field such as:
updatedAt
lastModifiedDate
lastSyncDate
Volume and platform limits
If the expected volume of concurrent calls or contact updates were high, I would also recommend opening a support ticket with Genesys.
The objective would be to request a capacity and rate-limit assessment for the use case, including information such as:
- Peak calls per minute.
- Number of lookups per interaction.
- Expected number of updates.
- Maximum concurrency.
- Projected growth.
- APIs and endpoints involved.
Based on these details, Genesys could evaluate whether the existing limits support the scenario or whether any adjustment is possible.
My proposed architecture would be:
External Contacts
= operational cache in Genesys Cloud
Customer API
= source of truth
Call.ExternalContactId + Get External Contact
= native lookup inside Architect
Webhook or incremental synchronization
= data-update mechanism
Real-time API lookup
= fallback
This model does not completely eliminate the customer API, but it avoids calling it during every interaction.
The backend is queried only when Genesys Cloud does not yet have an identified contact or when the stored information is insufficient.
Have you considered using Call.ExternalContactId together with the native Get External Contact action in this way?
------------------------------
Matheus Mendonca
------------------------------