Using Android or a desktop browser, please visit this WhatsApp test page and click the Send
button. If WhatsApp is not installed it will show you a message.
How does the code detection on that page work? I tried the following but nothing happens.
try {
location.href = 'whatsapp://send/?phone=62812345678&text=test';
} catch (e) {
console.log(e);
}
Using Android or a desktop browser, please visit this WhatsApp test page and click the Send
button. If WhatsApp is not installed it will show you a message.
How does the code detection on that page work? I tried the following but nothing happens.
try {
location.href = 'whatsapp://send/?phone=62812345678&text=test';
} catch (e) {
console.log(e);
}
Share
Improve this question
edited Jan 7, 2020 at 0:38
cbr
13.7k3 gold badges42 silver badges67 bronze badges
asked Jan 6, 2020 at 23:02
uingteauingtea
6,5242 gold badges31 silver badges44 bronze badges
5
|
3 Answers
Reset to default 14Looking at the page, it appears that at least on Chrome, they programmatically open an iframe with the src of whatsapp://send/?phone=<number>&text=test
. They then start a 1000ms timeout after which the "Looks like you don't have WhatsApp installed!" text is shown. This timeout is cancelled by an blur
event handler, meaning that their check is based on your device opening WhatsApp when that URL is loaded, which blurs the window.
The function which triggers after the timeout also seems to check if the timeout took longer than 1250ms. I suspect that this handles the case where your phone's browser stops executing JS timers when it changes apps.
On IE, they use window.navigator.msLaunchUri
, which accepts a noHandlerCallback
.
See for yourself by opening your browser's devtools and searching for WhatsAppApiOpenUrl
. On Chrome, the Search can be found from the devtools' menu:
Here's some example code.
const detectWhatsapp = (phone, text) => {
const uri = `whatsapp://send/?phone=${encodeURIComponent(
phone
)}&text=${encodeURIComponent(text)}`;
const onIE = () => {
return new Promise((resolve) => {
window.navigator.msLaunchUri(
uri,
() => resolve(true),
() => resolve(false)
);
});
};
const notOnIE = () => {
return new Promise((resolve) => {
const a =
document.getElementById("wapp-launcher") || document.createElement("a");
a.id = "wapp-launcher";
a.href = uri;
a.style.display = "none";
document.body.appendChild(a);
const start = Date.now();
const timeoutToken = setTimeout(() => {
if (Date.now() - start > 1250) {
resolve(true);
} else {
resolve(false);
}
}, 1000);
const handleBlur = () => {
clearTimeout(timeoutToken);
resolve(true);
};
window.addEventListener("blur", handleBlur);
a.click();
});
};
return window.navigator.msLaunchUri ? onIE() : notOnIE();
};
Please note that it adds an event listener each time it's called. If you're rolling this out into production, please use window.removeEventListener
to remove handleBlur
after the promise resolves. It also appends a DOM node into the body, if that matters to you.
Usage example:
detectWhatsapp('<your number here>', 'test').then(hasWhatsapp =>
alert(
'You ' +
(hasWhatsapp ? 'have WhatsApp' : "don't have WhatsApp")
)
)
Here my testing on Android:
Built-in Browser (Webview) and Firefox
if WA installed You can useiframe
to auto open WhatsAppChrome and Opera
Need user click action
and this simple code to check if WhatsApp are installed
let clickTimeout;
document.querySelector('#openWA').addEventListener('click', function() {
let start = Date.now();
clickTimeout = setTimeout(function() {
if (Date.now() - start > 1250)
return;
alert('WA not installed')
}, 1e3);
// reset the setTimeout or the alert will always be fired
window.addEventListener("blur", function() {
clearTimeout(clickTimeout)
});
})
<a href="whatsapp://send/?phone=62812345678&text=test" id="openWA">Send to WhatsApp</button>
<!-- Auto open on WebView and Firefox -->
<iframe id="launcher" src="whatsapp://send/?phone=62812345678&text=test" style="display: none;"></iframe>
If you have jquery, bassed on the code above if whats app does not open open a new page using whatsapp web instead of iframe launcher:
$('a[href^="whatsapp://send?"]').click(function() {
var button = this,
f = Date.now(),
j = setTimeout(function() {
if (Date.now() - f > 1025){
return;
}else{
var newLink = button.getAttribute('href').replace("whatsapp://send?", "https://web.whatsapp.com/send?");
button.setAttribute('href', newLink);
button.setAttribute('target', "_blank");
$(button).closest('div').append('<a class="hide new" href="' + newLink + '" target="_blank" ></a>');
$(button).closest('div').find('a.new')[0].click();
}
}, 1e3);
})
Linking
? how the code in plain JS – uingtea Commented Jan 6, 2020 at 23:10How the code detection on that page work?
- you can look at the client-side code yourself using dev tools (F12 key) in Google Chrome desktop. The network tab will show all code added to the page. – Dave S Commented Jan 6, 2020 at 23:21blocked by CORS policy
– uingtea Commented Jan 6, 2020 at 23:27whatsapp://...
the javascript is very large and minified/unreadable I can't find where the code for the listener. – uingtea Commented Jan 6, 2020 at 23:30