Problema
Quando um usuário abre um Link enviado através da API oficial do WhatsApp em um aparelho Android, os seguintes problema são apresentados:
-
Popups nativos do sistema operacional, que deveriam ser abertos em elementos de entrada de dados (
<input>), como calendário, seletor de hora e seletor de cores não funcionam, impedindo o preenchimento destes campos. -
Não há suporte para captura de fotos diretamente da câmera em elementos de upload (
< input type="file">). Ao invés de abrir a câmera, ele abre a galeria do celular.
Este não é um problema que ocorre exclusivamente com o Latromi, mas sim com qualquer página HTML, como pode ser observado nessa simulação:
- Simulação no Android (com problema)
- Simulação no iPhone (problema não ocorre)
Causa
Em Outubro de 2025, a Meta mudou a forma como links são abertos em mensagens automatizadas recebidas pelo WhatsApp, enviadas através da API oficial. Ao invés da página ser aberta no navegador do usuário, ela é aberta em um navegador embarcado no WhatsApp, uma componente conhecido como WebView.
O objetivo da implementação do WebView, é trazer mais segurança para os usuários, uma vez que a Meta passa a ter mais controle sobre o quê a página pode fazer, mitigando golpes e ataques cibernéticos.
No entanto, a implementação do WebView da Meta para o Android, apresenta estes problemas.
No iPhone o problema não acontece, porque ele só aceita o WebView produzido pela própria Apple, e que tem total suporte à comunicação com o sistema operacional. Já no caso do Android, ao que tudo indica, a Meta criou o seu próprio WebView para manter compatibilidade com aparelhos mais antigos.
Solução
Por enquanto, a única solução para contornar este problema, é instruir o usuário a abrir a página no navegador, seguindo as instruções oficiais WhatsApp
Mas como sabemos que não é fácil comunicar isso aos usuários, criamos um código JavaScript que faz o seguinte:
-
Identifica que o acesso está sendo feito através de um componente WebView do WhatsApp para Android.
-
Se sim, cobre a página com um elemento que contém instruções para o usuário abrir a página no navegador.
Este código pode ser usado no JavaScript Público e cobrir todos os Formulários ou ser carregado apenas nos Formulários onde for necessário fazer este tratamento:
(function () {
// Adiciona Callbacks no Formulário
latromi.formManager.setOnFormCreatedCallback(onFormCreated);
latromi.formManager.setOnEventFiringCallback(onEventFiring);
latromi.formManager.setOnFieldValueChangedCallback(onFieldValueChanged);
// Ocorre logo após o form ser inicializado
function onFormCreated(ev) {
// Se a página foi carregada no WebView desenvolvido pela meta para o Android,
// obriga o usuário a abrir a página no navegador. Isso foi necessário para
// manter o funcionamento adequado dos componentes input que usam a interface
// do aparelho (date, datetime-local, etc) e também para permitir que o campo
// de upload abra diretamente a camera. No Apple, este problema não ocorre.
const ua = navigator.userAgent || "";
if (ua.includes('WA4A')) {
createInstruction();
}
}
// Ocorre quando um evento é disparado no Form
function onEventFiring(ev) { }
// Ocorre quando o valor de um campo é alterado no Form
function onFieldValueChanged(ev) { }
function createInstruction() {
const instructionElement = document.createElement('div');
instructionElement.style.margin = '1.25rem';
instructionElement.innerHTML = `
<h2 style="font-weight: 700; font-size:1.25rem">Ação Necessária</h2>
<p>Para continuar, você precisa abrir essa página <strong>fora do WhatsApp</strong>. Siga estas etapas:</p>
<ol>
<li style="margin-bottom:0.5rem">Toque no ícone <i class="fa fa-ellipsis-v" aria-hidden="true"></i> no canto superior direito da tela.</li>
<li style="margin-bottom:0.5rem">Em seguida, toque em <strong>Abrir no navegador</strong></li>
<ol>
`;
const instructionContainer = document.createElement('div');
instructionContainer.style.position = 'absolute';
instructionContainer.style.top = 0;
instructionContainer.style.left = 0;
instructionContainer.style.right = 0;
instructionContainer.style.bottom = 0;
instructionContainer.style.backgroundColor = 'White';
instructionContainer.appendChild(instructionElement);
// Adiciona a seta
instructionElement.style.marginRight = '4rem';
instructionContainer.style.backgroundColor = 'White';
instructionContainer.appendChild(instructionElement);
instructionContainer.style.backgroundPositionX = 'right';
instructionContainer.style.backgroundPositionY = '20px';
instructionContainer.style.backgroundRepeat = 'no-repeat';
instructionContainer.style.backgroundImage = "url('data:image/png;base64,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MIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMIBMMAAAAAAAAAAAAABG9V9kCbwRK7b0uAAAAABJRU5ErkJggg==')";
instructionContainer.style.backgroundSize = '3.75rem';
// Adiciona instruções na página
document.body.appendChild(instructionContainer);
}
// Todas as funções acima são "privadas", e não podem ser chamadas externamente.
// As únicas funções que podem ser chamadas externamente são as que compões o resultado a seguir:
return {
test: function() { }
}
})();
O resultado será este:
