Skip to content

Instantly share code, notes, and snippets.

@parthpower
Last active June 20, 2024 08:17
Show Gist options
  • Save parthpower/d0fb6a1196fd8cefebde to your computer and use it in GitHub Desktop.
Save parthpower/d0fb6a1196fd8cefebde to your computer and use it in GitHub Desktop.
Simple JS to monitor offline and online time of a contact.

WhatsApp On Web Monitor

What It does

It gives notifications when someone goes online or offline or typing. Open chat of the contact you want to monitor and start script.

Simple Way

Tweet me @parthpower for bug reports or feature request. Special thanks to @jdcpower1994 for helping.

javascript:var csvContent="data:text/csv;charset=utf-8,Name,Status,Time,Date\n",globIntId=-1,buttonAdded=!1;function f(){try{b=document.querySelector("#main > header > div>div>span").textContent,name=document.querySelectorAll("#main > header > div>div>div>span")[1].textContent}catch(e){return}if("typing…"===b&&typing&&(typing=!1,checkPermission())){new Notification(name+" Typing");tm=new Date,csvContent+=name+",2,"+tm.toLocaleTimeString()+","+tm.toLocaleDateString()+"\n"}if(("online"===b||"typing…"===b)&&("online"===b&&(typing=!0),(!online||name!==lastName||ft)&&(online=!0,lastName=name,ft=!1,onlineTimeObj=new Date,onlineTimeMs=onlineTimeObj.getTime(),onlineTimeStr=onlineTimeObj.toLocaleString(),console.log(name+",1,"+onlineTimeObj.toLocaleTimeString()+","+onlineTimeObj.toLocaleDateString()+"\n"),csvContent+=name+",1,"+onlineTimeObj.toLocaleTimeString()+","+onlineTimeObj.toLocaleDateString()+"\n",checkPermission())))new Notification(name+" Online",{body:onlineTimeStr});if(-1<b.search("last seen")&&(online||ft||name!==lastName)&&(online=!1,ft=!1,lastName=name,typing=!0,offlineTimeObj=new Date,offlineTimeMs=offlineTimeObj.getTime(),offlineTimeStr=offlineTimeObj.toLocaleString(),console.log(name+",0,"+offlineTimeObj.toLocaleTimeString()+","+offlineTimeObj.toLocaleDateString()+"\n"),csvContent+=name+",0,"+offlineTimeObj.toLocaleTimeString()+","+offlineTimeObj.toLocaleDateString()+"\n",checkPermission()))new Notification(name+" Offline",{body:b})}function stalk(e){e=e||!1,ft=!0,online=!1,typing=!0,csvContent="data:text/csv;charset=utf-8,Name,Status,Time,Date\n",buttonAdded||(putCSVLink(),putStopStalkButton(),buttonAdded=!0);try{lastName=document.querySelector("#main > header > div.chat-body > div.chat-main > h2 > span")}catch(e){return}return!1!==e?(clearInterval(e),globIntId=-1,!0):(interval=setInterval(f,1e3),globIntId=interval,alert("Stalking"),interval)}function checkPermission(){return"Notification"in window?"granted"===Notification.permission||void("denied"!==Notification.permission&&Notification.requestPermission(function(e){if("granted"===e)return!0})):flase}function getCSV(e){e=encodeURI(e);var t=document.createElement("a");t.setAttribute("href",e),t.setAttribute("download","stalk_data.csv"),document.body.appendChild(t),t.click()}function getStalkData(){getCSV(csvContent)}function putCSVLink(){var e=document.createElement("button");e.textContent="GetStalkCSV",e.className="stalker",e.onclick=getStalkData,document.querySelector("#side > header").appendChild(e)}function toggleStalk(){-1===globIntId?(stalk(),this.textContent="Stop"):(clearInterval(globIntId),globIntId=-1,alert("Stalking Stopped"),this.textContent="Start",console.log("Stopped Stalking"))}function putStopStalkButton(){var e=document.createElement("button");e.className="stalker",e.textContent="ToggleStalk",e.onclick=toggleStalk,document.querySelector("#side > header").appendChild(e)}stalk();
//WhatsApp on Web stalker JS
//Copyright (c) 2016 Parh Parikh
//Distributed under MIT License
//Usage
//Open the chat you want to monitor
//stalk() to start stalking, return intervalId
//stalk(intervalId) to stop stalking
//Output is in console
//Quick Start
//Open Browser console, copy the code in console, write stalk()
//Happy stalking :)
var csvContent = "data:text/csv;charset=utf-8,Name,Status,Time,Date\n";
var globIntId = -1;
var buttonAdded = false;
function f() {
try {
b = document.querySelector('#main > header > div>div>span').textContent;
name = document.querySelectorAll('#main > header > div>div>div>span')[1].textContent;
} catch (TypeError) {
return;
}
if (b === "typing…" && typing) {
typing = false;
if (checkPermission()) {
var not = new Notification(name + " Typing");
tm = new Date();
csvContent += name + ",2," + tm.toLocaleTimeString() + "," + tm.toLocaleDateString() + "\n";
}
}
if (b === "online" || b === "typing…") {
if (b === "online") {
typing = true;
}
if (!online || name !== lastName || ft) {
online = true;
lastName = name;
ft = false;
onlineTimeObj = new Date();
onlineTimeMs = onlineTimeObj.getTime();
onlineTimeStr = onlineTimeObj.toLocaleString();
console.log(name + ",1," + onlineTimeObj.toLocaleTimeString() + "," + onlineTimeObj.toLocaleDateString() + "\n");
csvContent += name + ",1," + onlineTimeObj.toLocaleTimeString() + "," + onlineTimeObj.toLocaleDateString() + "\n";
if (checkPermission()) {
var not = new Notification(name + " Online",{
body: onlineTimeStr
});
}
}
}
if (b.search("last seen") > -1) {
if (online || ft || name !== lastName) {
online = false;
ft = false;
lastName = name;
typing = true;
offlineTimeObj = new Date();
offlineTimeMs = offlineTimeObj.getTime();
offlineTimeStr = offlineTimeObj.toLocaleString();
console.log(name + ",0," + offlineTimeObj.toLocaleTimeString() + "," + offlineTimeObj.toLocaleDateString() + "\n");
csvContent += name + ",0," + offlineTimeObj.toLocaleTimeString() + "," + offlineTimeObj.toLocaleDateString() + "\n";
if (checkPermission()) {
var not = new Notification(name + " Offline",{
body: b
});
}
}
}
}
function stalk(intervalId) {
intervalId = intervalId || false;
ft = true;
online = false;
typing = true;
csvContent = "data:text/csv;charset=utf-8,Name,Status,Time,Date\n";
if (!buttonAdded) {
putCSVLink();
putStopStalkButton();
buttonAdded = true;
}
try {
lastName = document.querySelector("#main > header > div.chat-body > div.chat-main > h2 > span");
} catch (TypeError) {
//stalk();
return;
}
if (intervalId !== false) {
clearInterval(intervalId);
globIntId = -1;
return true;
}
interval = setInterval(f, 1000);
globIntId = interval;
alert("Stalking");
//document.querySelector("#side > header > div.pane-list-user").textContent += "Stalking";
return interval;
}
//Modified Code from Notifiaction API example from MDN
function checkPermission() {
// Let's check if the browser supports notifications
if (!("Notification"in window)) {
return flase;
}// Let's check whether notification permissions have already been granted
else if (Notification.permission === "granted") {
// If it's okay let's create a notification
return true;
}// Otherwise, we need to ask the user for permission
else if (Notification.permission !== 'denied') {
Notification.requestPermission(function(permission) {
// If the user accepts, let's create a notification
if (permission === "granted") {
return true;
}
});
}
// At last, if the user has denied notifications, and you
// want to be respectful there is no need to bother them any more.
}
function getCSV(data) {
data = encodeURI(data);
var link = document.createElement("a");
link.setAttribute("href", data);
link.setAttribute("download", "stalk_data.csv");
document.body.appendChild(link);
link.click();
}
function getStalkData() {
getCSV(csvContent);
}
function putCSVLink() {
var button = document.createElement("button");
button.textContent = "GetStalkCSV";
button.className = "stalker";
button.onclick = getStalkData;
var sideBar = document.querySelector("#side > header");
sideBar.appendChild(button);
}
function toggleStalk() {
if (globIntId === -1) {
stalk();
this.textContent = "Stop";
} else {
clearInterval(globIntId);
globIntId = -1;
alert("Stalking Stopped");
this.textContent = "Start";
console.log("Stopped Stalking");
}
}
function putStopStalkButton() {
var button = document.createElement("button");
button.className = "stalker";
button.textContent = "ToggleStalk";
button.onclick = toggleStalk;
var sideBar = document.querySelector("#side > header");
sideBar.appendChild(button);
}
stalk();
@zkxnkj
Copy link

zkxnkj commented Jan 25, 2020

Gives notification only once then again I have to press stop stalking and start and then again it gives notification once

it is the same for me. one notification and it does not show when the person goes offline

@zkxnkj
Copy link

zkxnkj commented Jan 25, 2020

Hi,
Great job, thanks a lot for this code. I slightly adapted it to also track when the status is changing from online to offline.

I know it's been awhile, but could you share the link?

@zkxnkj
Copy link

zkxnkj commented Jan 25, 2020

I think I found a couple of bugs...

  • On line 13 you set the var cvsContent, which I think you overwrite in line 75 (function stalk());
    Why do we need that again?
  • Line 102 says "flase", where it should be "false";

Fact is, that there is never more logged than 1 event, although I'm pretty sure there are more events... What could I check?

please be gentle, I'm a noob when it comes to JS and programming. Still learning...

did you manage to get it to work?

@Craxxer
Copy link

Craxxer commented Jan 26, 2020

This chrome extension ist working:
https://github.com/supernova13892/whatsapp_stalker

@zkxnkj
Copy link

zkxnkj commented Jan 26, 2020

This chrome extension ist working:
https://github.com/supernova13892/whatsapp_stalker

thank you, so much! this seems to be working with multiple users as well. nice!

edit: sadly, it is not working for me for whatever reason, as no entries get recorded

@zkxnkj
Copy link

zkxnkj commented Jan 26, 2020

This chrome extension ist working:
https://github.com/supernova13892/whatsapp_stalker

I found another one that works and shows offline time as well, but has no notifications and you can only view one contact at a time: https://gist.github.com/rkhayyat/0f93f9f51ae40d6df3daf123182ee27b

@robertolopez92
Copy link

not showing typing.

@meins-rbg
Copy link

Hallo,

is with this function the user asked to change permission in his app with a message?
or what does this mean?

//Modified Code from Notifiaction API example from MDN
function checkPermission() {
// Let's check if the browser supports notifications
if (!("Notification"in window)) {
return flase;
}// Let's check whether notification permissions have already been granted
else if (Notification.permission === "granted") {
// If it's okay let's create a notification
return true;
}// Otherwise, we need to ask the user for permission
else if (Notification.permission !== 'denied') {
Notification.requestPermission(function(permission) {
// If the user accepts, let's create a notification
if (permission === "granted") {
return true;

@parthpower
Copy link
Author

@meins-rbg that's right, it is to check if the browser supports notifications API and check/ask permission to allow notifications.

From https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API

@meins-rbg
Copy link

Thanks, is there a solution for only "registers the first one" without changing the language?

@rizwansoaib
Copy link

@dee2499
Copy link

dee2499 commented Jan 8, 2021

Hello everyone.
How to build an app like whatsdog, that checks online-offline notification of a contact.

@uakg
Copy link

uakg commented Nov 11, 2022

Hello buys, can u give me a basic "documentation" how to use this script. I dont understand it completly. Thx in advance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment