Is WAScheduler - WA Message Scheduler safe?
WADeck reads your WhatsApp phone number and sends URLs from private conversations to third-party link-preview servers.
The extension reads the signed-in user's phone number from WhatsApp Web's localStorage and transmits it, along with a persistent install ID and browser fingerprint, to an Alibaba Cloud logging endpoint. When a message containing a URL is sent, the extension forwards that URL to one of three external link-preview proxy servers — unaffiliated with WhatsApp — to fetch page metadata.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
WhatsApp message URLs sent to preview proxy servers
When a WhatsApp Web message contains a URL, WAScheduler sends it to an external proxy: a GET to wajsapi.titanchat.com.br/v1/link-preview/fetch-data.png, with the outgoing message URL in the url query parameter.
You send a WhatsApp Web message that contains a URL.
The extension requests link-preview metadata from an external proxy endpoint.
The URL from the message is placed in the request's query string.
| Field | Value | Why it matters | |
|---|---|---|---|
Message URL | https://example.com/article (illustrative) | This is the web address typed into your WhatsApp message. It can reveal the site or content being discussed in that conversation. |
- wajsapi.titanchat.com.br
Receives the message URL in a link-preview fetch request; this was the host named in the confirmed verification.
- cobrancas.uppermesh.com.br
Configured as an alternate link-preview proxy host in the shipped extension code.
- wppc-linkpreview.cloudtrix.com.br
Configured as an alternate link-preview proxy host in the shipped extension code.
The injected WhatsApp helper sends the message URL to a preview proxy
case 16:
i["default"].prototype.$injectEl = this.appLoc,
this.appendScriptTag(e.runtime.getURL("qpqp.js")),
this.appendScriptTag(e.runtime.getURL("inject.bundle.js")),
this.appendTagTo(this.appLoc, O.toobarId),
new i["default"]({
i18n: b["a"],
store: this.store,
render: function(e) {
return e(s["a"])
}
}).$mount("#" + O.toobarId)t.prepareLinkPreview = function() {
var e = _asyncToGenerator(_regeneratorRuntime.mark((function e(t, r) {
var n, o, i, a;
return _regeneratorRuntime.wrap((function(e) {
while (1) switch (e.prev = e.next) {
case 0:
if (r.linkPreview) {
e.next = 2;
break
}
return e.abrupt("return", t);
case 2:
if (!r.linkPreview) {
e.next = 16;
break
}
if (n = "object" == _typeof(r.linkPreview) ? r.linkPreview : {}, o = "chat" === t.type ? t.body : "", !o) {
e.next = 16;
break
}
if (e.prev = 5, i = (0, f.findFirstWebLink)(o), !i) {
e.next = 12;
break
}
return e.next = 10, (0, f.fetchLinkPreview)(i);
case 10:
a = e.sent, (null == a ? void 0 : a.data) && (r.linkPreview = Object.assign(Object.assign({}, a.data), n));
case 12:
e.next = 16;
break;
case 14:
e.prev = 14, e.t0 = e["catch"](5);
case 16:
return "object" == _typeof(r.linkPreview) && (t.subtype = "url", t = Object.assign(Object.assign({}, t), r.linkPreview)), e.abrupt("return", t);
case 18:
case "end":
return e.stop()
}
}), e, null, [
[5, 14]
])
})));
return function(t, r) {
return e.apply(this, arguments)
}
}();t.fetchRemoteLinkPreviewData = function() {
var e = _asyncToGenerator(_regeneratorRuntime.mark((function e(t) {
var r, n, o, i, a, u, s;
return _regeneratorRuntime.wrap((function(e) {
while (1) switch (e.prev = e.next) {
case 0:
if (!p[t]) {
e.next = 2;
break
}
return e.abrupt("return", (l("Link preview found in the cache", t), p[t]));
case 2:
r = new TextDecoder, n = f.length - 1;
case 4:
if (!(n >= 0)) {
e.next = 21;
break
}
return o = f[n], l("Fetching link preview using ".concat(o), t), i = "".concat(o, "/v1/link-preview/fetch-data.png?url=") + encodeURI(t), e.next = 10, (0, c.fetchDataFromPNG)(i).then((function(e) {
return r.decode(e)
})).then((function(e) {
return JSON.parse(e)
})).catch((function() {
return null
}));
case 10:
if (a = e.sent, null !== a && ("title" in a || "status" in a)) {
e.next = 14;
break
}
return l("The server ".concat(o, " is unavailable for link preview")), f.splice(n, 1), e.abrupt("continue", 18);
case 14:
if (a.title || 200 === a.status) {
e.next = 16;
break
}
return e.abrupt("continue", 18);
case 16:
return u = /^video/.test(a.mediaType), s = {
title: a.title,
description: a.description,
canonicalUrl: a.url,
matchedText: t,
richPreviewType: u ? 1 : 0,
doNotPlayInline: !u,
imageUrl: a.image
}, e.abrupt("return", (p[t] = s, setTimeout((function() {
delete p[t]
}), 3e5), s));
case 18:
n--, e.next = 4;
break;
case 21:
return e.abrupt("return", null);
case 22:
case "end":
return e.stop()
}
}), e)
})));
return function(t) {
return e.apply(this, arguments)
}
}()var o = n(r(17833)),
i = r(91491),
a = r(14647),
u = r(52757),
s = r(97016),
c = r(24298),
l = (0, o.default)("WA-JS:link-preview"),
f = i.config.linkPreviewApiServers || ["https://cobrancas.uppermesh.com.br:8000", "https://wajsapi.titanchat.com.br", "https://wppc-linkpreview.cloudtrix.com.br"],
d = 140,
p = {},
v = {};
! function(e) {
for (var t = e.length - 1; t > 0; t--) {
var r = Math.floor(Math.random() * (t + 1)),
n = [e[r], e[t]];
e[t] = n[0], e[r] = n[1]
}
}(f)