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();
@bendash
Copy link

bendash commented Aug 1, 2018

It works if i keep switcvhing between the chats but gives only one notification if i opened asingle chat

@yiorenl
Copy link

yiorenl commented Aug 20, 2018

Hi there, i'm facing the same issues as @bendash. Is there a workaround to solve that problem? It only sees the first time some is online. The other status are not recorded.

@philbarney
Copy link

philbarney commented Sep 8, 2018

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.

@troublie
Copy link

Tried twice right now but it seems to do nothing, I click on the bookmark and nothing happens while whatsappweb opened.

Is this not working?

@shahidcodes
Copy link

@philbarney could you gist your adapted code?

@ergoamox
Copy link

Hi there, i'm facing the same issues as @bendash. Is there a workaround to solve that problem? It only sees the first time some is online. The other status are not recorded.

This JS code works fine on Whatsapp with an english interface. Change your language from your smartphone to English. Otherwise the recording doesn't work.

@StefanSOD
Copy link

Hi there, i'm facing the same issues as @bendash. Is there a workaround to solve that problem? It only sees the first time some is online. The other status are not recorded.

This JS code works fine on Whatsapp with an english interface. Change your language from your smartphone to English. Otherwise the recording doesn't work.

What lines do we need to change in order to let this work, when using another language than the default (en)?

@StefanSOD
Copy link

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...

@StefanSOD
Copy link

@StefanSOD
Copy link

@schurik222
Copy link

I am too stupid...where can I find the file ?

@george5th
Copy link

First I open whatsapp in Firefox and open a chat, than I push F12 and copy the script in the console. I push ENTER and on screen I see "stalk". And now ??? What must I do know or ist it a mistake ? Please help me.

@gnncl
Copy link

gnncl commented May 9, 2019

The display language of your android or ios device must be in english.
Sample View

@Maynstream
Copy link

It's a pity you have to refresh to get multiple notifications. Now it only registers the first one.

@kirinsoo-byte
Copy link

any possibility for logging the activity of the stalked subject?

@kirinsoo-byte
Copy link

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.

mind uploading the code

@Craxxer
Copy link

Craxxer commented Jan 1, 2020

Something new on the script? It only save one entry...

@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