-
-
Save C5H8NNaO4/f799297688f640d15c00e7fee8b4fa26 to your computer and use it in GitHub Desktop.
(function (window) { | |
var DOUBLE_CLICK_DELAY = 550; | |
var OnlineNotifier = (function () { | |
var LOG_LEVEL = 01; | |
var POLL_TIMEOUT = 1E3; | |
var MIN_TIMEOUT = 60E3; | |
var MIN_TIMEOUT_TYPING = 5E3 | |
var DEBUG_CHECK_ALL = false; | |
var DEBUG_CHECK_ONLINE = false; | |
var DEBUG_CHECK_TYPING = false; | |
var DEBUG_CHECK_COUNT = 27 * 3 | |
var DEBUG_TIMEOUT = 1E3 | |
var DEBUG_CHANCE = .33 | |
var NOTIFY_SUBSCRIBE = true; | |
var debug = DEBUG_CHECK_ALL || DEBUG_CHECK_ONLINE || DEBUG_CHECK_TYPING | |
if (debug) { | |
POLL_TIMEOUT = DEBUG_TIMEOUT | |
} | |
var chats = Store.Chat.models.slice (); | |
var msg = { | |
online: "Online", | |
offline:"Offline", | |
typing: "Typing...", | |
unsubscribing: "...unsubscribing %s.", | |
subscribing: "... subscribing %s.", | |
check: "checking state: %s [%s].", | |
handle: "... check sucessfull. calling handler.", | |
look: "looking for people online... found %d.", | |
timeout: "scheduling next check in %dms.", | |
reset:"reseted", | |
started:"started", | |
state: "Last seen: %0", | |
subscribed:"enabled notifications", | |
unsubscribed:"disabled notifications", | |
ppurl: "https://dyn.web.whatsapp.com/pp?t=s&u=%user%&i=%tag%" | |
} | |
var debug_last = "offline"; | |
var debug_time = 0 | |
var debug_state = 0; | |
var checks = { | |
online: function (contact,name) { | |
if (DEBUG_CHECK_ONLINE) { | |
return debug_state === OnlineNotifier.observe.online; | |
} | |
return contact.presence._values.isOnline | |
}, | |
typing: function (contact, name) { | |
if (DEBUG_CHECK_TYPING) { | |
return debug_state === OnlineNotifier.observe.typing; | |
} | |
return contact._values.typing || DEBUG_CHECK_TYPING | |
}, | |
offline: function (contact, name) { | |
return !checks.online.call(this,contact, name) && !checks.typing.call (this,contact, name); | |
} | |
} | |
var util = { | |
extract: function (keys, src, trg) { | |
if (!Array.isArray (keys)) keys = Object.keys (keys); | |
trg = trg || {} | |
return keys.reduce (function (trg,key) { | |
trg [key] = src [key]; | |
return trg; | |
}, trg); | |
} | |
} | |
var handler = { | |
online: function (contact, name) { | |
log (10, "Handler", "online"); | |
var state = this.getState (name); | |
if ( state.changed || +new Date - MIN_TIMEOUT > contact._lastnotification) { | |
log (10, "Handler", "changed", state.changed) | |
notify (contact, "online") | |
} | |
}, | |
typing: function (contact,name) { | |
var state = this.getState (name); | |
if ( state.changed || +new Date - MIN_TIMEOUT_TYPING > contact._lastnotification) { | |
notify (contact, "typing") | |
} | |
}, | |
offline: function (contact,name) { | |
log (10, "Handler","offline") | |
var state = this.getState (name) | |
if (state.state === "online" || state.changed) | |
notify (contact, "offline"); | |
} | |
} | |
var OnlineNotifier = function (startMonitor) { | |
this.watch = OnlineNotifier.observe.online + OnlineNotifier.observe.typing; | |
this.subscribed = []; | |
this.unsubscribed = chats.slice (); | |
this._timeout = 0; | |
this._lastnotification = +new Date - MIN_TIMEOUT | |
this._states = {}; | |
this.load () | |
this.monitor (startMonitor) | |
notify (0,"started"); | |
} | |
OnlineNotifier._notifications = {} | |
OnlineNotifier.storageKey = "mon" | |
OnlineNotifier.LOG_LEVEL = LOG_LEVEL; | |
OnlineNotifier.prototype.timeout = POLL_TIMEOUT; | |
OnlineNotifier.observe = { | |
offline:0, | |
online: 1, | |
typing: 2, | |
} | |
OnlineNotifier.contacts = { | |
byName: function () { | |
return chats.reduce (function (a,b) { | |
var values = b._values; | |
var name = values.name; | |
a [name] = b; | |
return a | |
}, {}); | |
}, | |
byId: function () { | |
return chats.reduce (function (a,b) { | |
var values = b._values; | |
var name = values.id; | |
a [name] = b; | |
return a | |
}, {}); | |
}, | |
filter: { | |
name: filter.bind (0,"name"), | |
id: filter.bind (0,"id") | |
}, | |
gen: { | |
ppurl: function (contact, cb) { | |
var id = contact._values.id; | |
log (9, "Generating Profile Picture Url") | |
Store.Wap.profilePicFind( "ProfilePicThumb", id).then (function (data) { | |
var tag = data.tag; | |
var url = msg.ppurl.replace ("%user%", id).replace ("%tag%",tag) | |
cb (url, tag) | |
}) | |
} | |
} | |
} | |
function notify (contact, status) { | |
if (!contact && status) { | |
return new Notification ("OnlineNotifier", {tag:"system",body:msg[status]}); | |
} | |
if (!contact._lastnotification) contact._lastnotification = 0; | |
//if (+new Date - MIN_TIMEOUT > contact._lastnotification) { | |
var n = OnlineNotifier.contacts.filter.name (contact); | |
m = msg [status] | |
for (var i = 2; i < arguments.length; i++) { | |
m = m.replace ("%"+(i-2), arguments [i]) | |
} | |
log (9,"Preparing Notification for ", n) | |
OnlineNotifier.contacts.gen.ppurl (contact, function (url, tag) { | |
//tag = status + "-" + tag; | |
contact._lastnotification = +new Date | |
log (10,"Displaying notification",tag); | |
OnlineNotifier._notifications [n] = new Notification (n, { | |
body: m, | |
icon: url, | |
tag: tag | |
}); | |
}) | |
//} | |
} | |
function log (lvl) { | |
if (OnlineNotifier.LOG_LEVEL >= lvl) { | |
console.log.apply (console, [].slice.call (arguments, 1)); | |
} | |
} | |
function filter (attr, contacts) { | |
if (!Array.isArray (contacts)) {contacts = [contacts]} | |
return contacts.map (function (a) { | |
return a._values [attr]; | |
}) | |
} | |
OnlineNotifier.prototype.getOnline = function () { | |
if (DEBUG_CHECK_ONLINE || (this.watched & OnlineNotifier.observe.offline) == OnlineNotifier.observe.offline) { | |
return this.subscribed; | |
} | |
return this.subscribed.filter (checks.online); | |
} | |
OnlineNotifier.prototype.monitor = function mon(subscribeTo) { | |
this.save (); | |
var that = this; | |
if (subscribeTo) { | |
this.subscribe (subscribeTo) | |
} | |
var online = this.getOnline (); | |
var state = ""; | |
var oldstate = ""; | |
var newstate; | |
log (4, msg ["look"], online.length); | |
for (var key in OnlineNotifier.observe) { | |
var val = OnlineNotifier.observe [key]; | |
var now = +new Date; | |
if ((this.watch & val) === val) | |
for (var i=0; i<online.length; i++) { | |
var contact = online [i]; | |
var name = OnlineNotifier.contacts.filter.name (contact) [0] | |
log (6, msg ["check"],key,name); | |
if (checks [key].call(this,contact,name) || DEBUG_CHECK_ALL) { | |
log (7, msg ["handle"], key, handler [key]) | |
state = OnlineNotifier.observe[key]; | |
oldstate = this.getState (name).state; | |
newstate = {state: state, t:now, changed: state !== oldstate,id : contact._values.id}; | |
newstate[state] = now | |
util.extract (newstate, newstate, this.getState (name)) | |
handler [key] && handler[key].call (this,contact, name); | |
log (10, "new state", state, oldstate, this.getState(name)); | |
} | |
} | |
} | |
log (9,"check debug", debug_state, debug_time) | |
if ((debug_time % DEBUG_CHECK_COUNT) === 0) { | |
debug_state = (debug_state + 1) % 3 | |
} | |
debug_time++; | |
if (this._timeout == -1) { | |
this._timeout = 0; | |
this.save () | |
} else { | |
this._timeout = setTimeout (function () { | |
mon.call (that); | |
}, this.timeout) | |
this.save() | |
log (7, msg ["timeout"], this.timeout, this._timeout) | |
} | |
} | |
OnlineNotifier.prototype.showStates = function () { | |
for (var key in this._states) { | |
var state = this.getState (key); | |
notify (this.getChatById (state.id), "state", state[1]) | |
} | |
} | |
OnlineNotifier.prototype.subscribe = function (contacts,reverse) { | |
var byName; | |
var srcTrg = [this.unsubscribed, this.subscribed]; | |
var srcInd = 0 + ~~reverse; | |
var msgPre = reverse ? "un":"" | |
var wasRunning = this.isRunning (); | |
if (wasRunning) { | |
log (4, "pausing"); | |
this.cancel (); | |
} | |
if (!Array.isArray (contacts)) { | |
return this.subscribe (typeof contacts === "string"?[contacts]:[], reverse) | |
} else if (typeof contacts [0] == "string") { | |
byName = OnlineNotifier.contacts.byName (); | |
byId = OnlineNotifier.contacts.byId (); | |
contacts = contacts.map (function (a) { | |
if (byId.hasOwnProperty (a)) { | |
return byId [a] | |
} else if(byName.hasOwnProperty (a)){ | |
return byName [a]; | |
} | |
}); | |
} | |
for (var i = 0; i < contacts.length; i++) { | |
var contact = contacts [i] | |
var ind = srcTrg [srcInd].indexOf (contact); | |
srcTrg[(srcInd + 1) % 2].push (srcTrg [srcInd].splice (ind, 1)[0]) | |
log (5,msg [msgPre + "subscribing"], contact._values.name) | |
if (NOTIFY_SUBSCRIBE) { | |
notify (contact, msgPre + "subscribed") | |
} | |
} | |
if (wasRunning) { | |
log (4, "resuming") | |
this.monitor (); | |
} | |
log (3, msg[msgPre+"subscribed"], OnlineNotifier.contacts.filter.name (contacts)) | |
} | |
OnlineNotifier.prototype.unsubscribe = function (contacts) { | |
//var s="subscribed"; | |
//var u="un"+s; | |
//swap (this, s, u); | |
this.subscribe (contacts,true); | |
} | |
OnlineNotifier.prototype.isRunning = function () { | |
return this._timeout > 0 | |
} | |
OnlineNotifier.prototype.cancel = function () { | |
clearTimeout (this._timeout); | |
this._timeout = -1 | |
} | |
OnlineNotifier.prototype.getOptions = function () { | |
var opt = util.extract (["timeout","_timeout"], this); | |
opt._subscribed = this.subscribed.map (function (a) { | |
return a._values.name; | |
}); | |
return opt; | |
} | |
OnlineNotifier.prototype.subscribeAll = function () { | |
return this.subscribe (this.unsubscribed); | |
} | |
OnlineNotifier.prototype.getState = function (name) { | |
if (!this._states [name]) | |
this._states [name] = {state: -1, t:+ new Date, changed: true} | |
return this._states [name] | |
} | |
OnlineNotifier.prototype.save = function () { | |
var opt = this.getOptions (); | |
localStorage [OnlineNotifier.storageKey] = JSON.stringify (opt); | |
} | |
OnlineNotifier.prototype.load = function () { | |
var options; | |
try { | |
options = JSON.parse (localStorage [OnlineNotifier.storageKey]); | |
} catch (e) { | |
options = {} | |
} | |
util.extract (options,options,this); | |
this.subscribe (options._subscribed); | |
} | |
OnlineNotifier.e = util.extract; | |
OnlineNotifier.prototype.onBookmarkTriggered = function (open,dblclick) { | |
delete window.monTriggerTimeout | |
var active = Store.Chat.active (); | |
var chat; | |
if (open) { | |
return; | |
} | |
if (dblclick) { | |
notify (0, "dbc") | |
return ; | |
} | |
if (typeof active == "undefined") { | |
this.reset (); | |
} else { | |
chat = this.getChatById (active); | |
if (!~active.indexOf (this.subscribed)) { | |
this.unsubscribe (active); | |
} else { | |
this.subscribe (active); | |
} | |
} | |
setTimeout (this.monitor.bind(this),0); | |
} | |
OnlineNotifier.prototype.getChatById = function (id) { | |
return OnlineNotifier.contacts.byId ()[id] | |
} | |
OnlineNotifier.prototype.reset = function () { | |
notify (0, "reset") | |
delete localStorage [OnlineNotifier.storageKey]; | |
} | |
return OnlineNotifier | |
})() | |
if (!window.mon ) { | |
window.mon = new OnlineNotifier (); | |
//window.mon.onBookmarkTriggered (true,false); | |
} else if (window.monTriggerTimeout) { | |
clearTimeout (window.monTriggerTimeout); | |
window.mon.onBookmarkTriggered (false,true); | |
} else if (!window.monTriggerTimeout) { | |
window.monTriggerTimeout = window.setTimeout (window.mon.onBookmarkTriggered.bind (window.mon,false,false), DOUBLE_CLICK_DELAY); | |
} | |
})(window); |
Press f12 on WhatsApp Web page, hit the console section copy the whole code paste it there and press Enter !
If done as stated then it will show a popup on bottom right corner.
It doesn't work. The store object was missing so I added the following code :
if (window.Store === undefined) {
webpackJsonp([], {"bcihgfbdeb": (x, y, z) => window.Store = z('"bcihgfbdeb"')}, "bcihgfbdeb");
webpackJsonp([], {"iaeeehaci": (x, y, z) => window.Store.Wap = z('"iaeeehaci"')}, "iaeeehaci");
}
However, now it gives the welcome notification nut none after that!!
It seems to be an interesting code, only if you could get it work please :)
May be if you add an overlaying UI that shows people who are online would be very useful. Thanks.
Could anyone help on how to do it, after i press f12 and go to console and enter the code it says " error reference "
This was supposed to be used as a bookmarklet.
You select the chat you want to be notified for and run the bookmarklet to enable notifications; run again to turn them off.
I don't know if it's still working in 2019
hello, does anyone know if this is working as of 10.9.2020? been trying to make something similar.
Hello
How does it work?