sauruspro-bail 0.0.0-stage → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -2
- package/WAProto/GenerateStatics.sh +3 -0
- package/WAProto/WAProto.proto +6754 -0
- package/WAProto/fix-imports.js +85 -0
- package/WAProto/index.d.ts +79257 -0
- package/WAProto/index.js +242946 -0
- package/docs/CHANGELOG.md +43 -0
- package/docs/NEWSLETTER-STATUS.md +120 -0
- package/docs/SPR.md +51 -0
- package/engine-requirements.js +10 -0
- package/lib/Defaults/index.js +135 -0
- package/lib/Signal/Group/ciphertext-message.js +12 -0
- package/lib/Signal/Group/group-session-builder.js +30 -0
- package/lib/Signal/Group/group_cipher.js +82 -0
- package/lib/Signal/Group/index.js +12 -0
- package/lib/Signal/Group/keyhelper.js +18 -0
- package/lib/Signal/Group/sender-chain-key.js +26 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +63 -0
- package/lib/Signal/Group/sender-key-message.js +66 -0
- package/lib/Signal/Group/sender-key-name.js +48 -0
- package/lib/Signal/Group/sender-key-record.js +41 -0
- package/lib/Signal/Group/sender-key-state.js +84 -0
- package/lib/Signal/Group/sender-message-key.js +26 -0
- package/lib/Signal/libsignal.js +431 -0
- package/lib/Signal/lid-mapping.js +277 -0
- package/lib/Socket/Client/index.js +3 -0
- package/lib/Socket/Client/types.js +11 -0
- package/lib/Socket/Client/websocket.js +54 -0
- package/lib/Socket/MessageBuilder.js +3729 -0
- package/lib/Socket/business.js +379 -0
- package/lib/Socket/chats.js +1198 -0
- package/lib/Socket/communities.js +431 -0
- package/lib/Socket/dinonic-handler.d.ts +27 -0
- package/lib/Socket/dinonic-handler.js +882 -0
- package/lib/Socket/graphql.js +716 -0
- package/lib/Socket/groups.js +374 -0
- package/lib/Socket/index.js +96 -0
- package/lib/Socket/interop.js +463 -0
- package/lib/Socket/luxu.js +387 -0
- package/lib/Socket/message-builder.js +556 -0
- package/lib/Socket/messages-recv.js +1942 -0
- package/lib/Socket/messages-send.js +1541 -0
- package/lib/Socket/mex.js +54 -0
- package/lib/Socket/newsletter.js +641 -0
- package/lib/Socket/privacy.js +318 -0
- package/lib/Socket/socket.js +1115 -0
- package/lib/Socket/username.js +236 -0
- package/lib/Store/index.js +10 -0
- package/lib/Store/keyed-db.js +108 -0
- package/lib/Store/make-cache-manager-store.js +85 -0
- package/lib/Store/make-in-memory-store.js +244 -0
- package/lib/Store/make-ordered-dictionary.js +75 -0
- package/lib/Store/object-repository.js +32 -0
- package/lib/Types/Auth.js +2 -0
- package/lib/Types/Bussines.js +2 -0
- package/lib/Types/Call.js +2 -0
- package/lib/Types/Chat.js +8 -0
- package/lib/Types/Contact.js +2 -0
- package/lib/Types/Events.js +2 -0
- package/lib/Types/GroupMetadata.js +2 -0
- package/lib/Types/Label.js +25 -0
- package/lib/Types/LabelAssociation.js +7 -0
- package/lib/Types/Message.js +11 -0
- package/lib/Types/Mex.js +111 -0
- package/lib/Types/Product.js +2 -0
- package/lib/Types/Signal.js +2 -0
- package/lib/Types/Socket.js +3 -0
- package/lib/Types/State.js +56 -0
- package/lib/Types/USync.js +2 -0
- package/lib/Types/index.js +26 -0
- package/lib/Utils/MessageBuilder.d.ts +215 -0
- package/lib/Utils/MessageBuilder.js +3991 -0
- package/lib/Utils/a2ui.d.ts +202 -0
- package/lib/Utils/a2ui.js +732 -0
- package/lib/Utils/airich-registry.js +3 -0
- package/lib/Utils/auth-utils.js +302 -0
- package/lib/Utils/baileys-event-stream.js +58 -0
- package/lib/Utils/bot-signature.d.ts +22 -0
- package/lib/Utils/bot-signature.js +124 -0
- package/lib/Utils/browser-utils.js +48 -0
- package/lib/Utils/business.js +231 -0
- package/lib/Utils/chat-utils.js +872 -0
- package/lib/Utils/companion-reg-client-utils.js +35 -0
- package/lib/Utils/crypto.js +118 -0
- package/lib/Utils/decode-wa-message.js +350 -0
- package/lib/Utils/dinonic-spr.d.ts +26 -0
- package/lib/Utils/dinonic-spr.js +521 -0
- package/lib/Utils/event-buffer.js +622 -0
- package/lib/Utils/extras.d.ts +449 -0
- package/lib/Utils/extras.js +1377 -0
- package/lib/Utils/generics.js +403 -0
- package/lib/Utils/history.js +134 -0
- package/lib/Utils/html-app.d.ts +39 -0
- package/lib/Utils/html-app.js +291 -0
- package/lib/Utils/identity-change-handler.js +50 -0
- package/lib/Utils/index.js +38 -0
- package/lib/Utils/link-preview.js +85 -0
- package/lib/Utils/logger.js +3 -0
- package/lib/Utils/lt-hash.js +8 -0
- package/lib/Utils/make-mutex.js +33 -0
- package/lib/Utils/message-composer.js +273 -0
- package/lib/Utils/message-retry-manager.js +265 -0
- package/lib/Utils/messages-media.js +870 -0
- package/lib/Utils/messages.js +1394 -0
- package/lib/Utils/metaai.d.ts +438 -0
- package/lib/Utils/metaai.js +911 -0
- package/lib/Utils/modern-messages.d.ts +150 -0
- package/lib/Utils/modern-messages.js +496 -0
- package/lib/Utils/native-flow.d.ts +14 -0
- package/lib/Utils/native-flow.js +118 -0
- package/lib/Utils/newsletter-status.d.ts +163 -0
- package/lib/Utils/newsletter-status.js +694 -0
- package/lib/Utils/noise-handler.js +201 -0
- package/lib/Utils/offline-node-processor.js +40 -0
- package/lib/Utils/payment-messages.d.ts +59 -0
- package/lib/Utils/payment-messages.js +156 -0
- package/lib/Utils/pre-key-manager.js +106 -0
- package/lib/Utils/process-message.js +630 -0
- package/lib/Utils/reporting-utils.js +258 -0
- package/lib/Utils/scheduled-message.d.ts +82 -0
- package/lib/Utils/scheduled-message.js +113 -0
- package/lib/Utils/signal.js +201 -0
- package/lib/Utils/stanza-ack.js +38 -0
- package/lib/Utils/status-stickers.d.ts +78 -0
- package/lib/Utils/status-stickers.js +261 -0
- package/lib/Utils/sticker.js +133 -0
- package/lib/Utils/sync-action-utils.js +49 -0
- package/lib/Utils/tc-token-utils.js +163 -0
- package/lib/Utils/use-multi-file-auth-state.js +121 -0
- package/lib/Utils/use-sqlite-auth-state.js +162 -0
- package/lib/Utils/validate-connection.js +203 -0
- package/lib/WABinary/constants.js +1301 -0
- package/lib/WABinary/decode.js +262 -0
- package/lib/WABinary/encode.js +220 -0
- package/lib/WABinary/generic-utils.js +204 -0
- package/lib/WABinary/index.js +6 -0
- package/lib/WABinary/jid-utils.js +98 -0
- package/lib/WABinary/types.js +2 -0
- package/lib/WAM/BinaryInfo.js +10 -0
- package/lib/WAM/constants.js +22853 -0
- package/lib/WAM/encode.js +150 -0
- package/lib/WAM/index.js +4 -0
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +53 -0
- package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +43 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +54 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
- package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +58 -0
- package/lib/WAUSync/Protocols/USyncLIDProtocol.js +30 -0
- package/lib/WAUSync/Protocols/USyncPictureProtocol.js +32 -0
- package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +28 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +39 -0
- package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +38 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +27 -0
- package/lib/WAUSync/Protocols/index.js +12 -0
- package/lib/WAUSync/USyncQuery.js +151 -0
- package/lib/WAUSync/USyncUser.js +56 -0
- package/lib/WAUSync/index.js +3 -0
- package/lib/index.js +67 -0
- package/package.json +147 -5
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { airichRegistry as _MBModule } from './airich-registry.js';
|
|
2
|
+
import * as crypto from 'crypto';
|
|
3
|
+
let _AIRich;
|
|
4
|
+
function getAIRich() {
|
|
5
|
+
if (!_AIRich) {
|
|
6
|
+
_AIRich = _MBModule.AIRich;
|
|
7
|
+
}
|
|
8
|
+
return _AIRich;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const HTML_APP_MESSAGE_CEILING = 1024 * 1024;
|
|
12
|
+
|
|
13
|
+
const HTML_APP_BYTE_BUDGET = 960 * 1024;
|
|
14
|
+
|
|
15
|
+
const HTML_APP_BYTE_LIMIT = HTML_APP_BYTE_BUDGET;
|
|
16
|
+
|
|
17
|
+
const HTML_MIME_TYPE = 'text/html';
|
|
18
|
+
|
|
19
|
+
const wireBytes = (html) => Buffer.byteLength(
|
|
20
|
+
JSON.stringify(String(html)).replace(/[\u007f-\uffff]/g, (c) => '\\u' + c.charCodeAt(0).toString(16).padStart(4, '0')),
|
|
21
|
+
'utf-8'
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const STORAGE_APIS = ['localStorage', 'sessionStorage', 'indexedDB', 'document.cookie', 'caches'];
|
|
25
|
+
|
|
26
|
+
const strip = (html) => html
|
|
27
|
+
.replace(/<!--[\s\S]*?-->/g, '')
|
|
28
|
+
.replace(/data:[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]*;base64,[A-Za-z0-9+/=]+/gi, 'data:');
|
|
29
|
+
|
|
30
|
+
const hasVisibilityGuard = (source) => /document\.(hidden|visibilityState)|visibilitychange|IntersectionObserver|cancelAnimationFrame|clearInterval/.test(source);
|
|
31
|
+
|
|
32
|
+
const checkHtmlApp = (html, { height, maxBytes = HTML_APP_BYTE_BUDGET } = {}) => {
|
|
33
|
+
if (typeof html !== 'string') {
|
|
34
|
+
throw new TypeError('checkHtmlApp requires an HTML string');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const bytes = Buffer.byteLength(html, 'utf-8');
|
|
38
|
+
const wire = wireBytes(html);
|
|
39
|
+
const source = strip(html);
|
|
40
|
+
const problems = [];
|
|
41
|
+
const warnings = [];
|
|
42
|
+
|
|
43
|
+
if (wire > maxBytes) {
|
|
44
|
+
problems.push(`${Math.round(wire / 1024)}KB on the wire, over the ${Math.round(maxBytes / 1024)}KB budget`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (wire > bytes * 1.15) {
|
|
48
|
+
warnings.push(`escaping inflates this page from ${Math.round(bytes / 1024)}KB to ${Math.round(wire / 1024)}KB`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const remote = [...source.matchAll(/\b(?:src|href)\s*=\s*["']?(https?:)?\/\//gi)];
|
|
52
|
+
if (remote.length) {
|
|
53
|
+
problems.push(`${remote.length} remote subresource(s) — embed as data: URIs instead`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (/\bfetch\s*\(|XMLHttpRequest|navigator\.sendBeacon|new\s+EventSource/.test(source)) {
|
|
57
|
+
problems.push('a call over HTTP stack — use offline/embedded storage');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const storage = STORAGE_APIS.filter(api => source.includes(api));
|
|
61
|
+
if (storage.length) {
|
|
62
|
+
problems.push(`${storage.join(', ')} — every storage API throws SecurityError in an opaque origin`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return { ok: problems.length === 0, bytes, wireBytes: wire, problems, warnings };
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const lockHeight = (height) => {
|
|
69
|
+
const px = Number(height);
|
|
70
|
+
if (!Number.isFinite(px) || px <= 0) {
|
|
71
|
+
throw new TypeError('lockHeight requires a positive number of pixels');
|
|
72
|
+
}
|
|
73
|
+
return '<style>html,body{height:' + Math.round(px) + 'px;max-height:' + Math.round(px) + 'px;overflow:hidden}</style>';
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const autoHeight = ({ min = 60, max = 900, settleMs = 120, maxReports = 24 } = {}) => {
|
|
77
|
+
const low = Number(min);
|
|
78
|
+
const high = Number(max);
|
|
79
|
+
const wait = Number(settleMs);
|
|
80
|
+
const cap = Number(maxReports);
|
|
81
|
+
if (!Number.isFinite(low) || low <= 0) {
|
|
82
|
+
throw new TypeError('autoHeight min must be a positive number of pixels');
|
|
83
|
+
}
|
|
84
|
+
if (!Number.isFinite(high) || high <= low) {
|
|
85
|
+
throw new TypeError('autoHeight max must be greater than min');
|
|
86
|
+
}
|
|
87
|
+
return '<style>html,body{margin:0;padding:0}</style>'
|
|
88
|
+
+ '<script>(function(){'
|
|
89
|
+
+ 'var LOW=' + low + ',HIGH=' + high + ',WAIT=' + wait + ',CAP=' + cap + ';'
|
|
90
|
+
+ 'var sent=[],timer=null,stopped=false;'
|
|
91
|
+
+ 'function measure(){var d=document.documentElement,b=document.body;'
|
|
92
|
+
+ 'var h=Math.max(d?d.scrollHeight:0,b?b.scrollHeight:0,b?b.offsetHeight:0);'
|
|
93
|
+
+ 'return Math.min(HIGH,Math.max(LOW,Math.ceil(h)))}'
|
|
94
|
+
+ 'function report(){if(stopped)return;var h=measure();'
|
|
95
|
+
+ 'if(sent.length&&sent[sent.length-1]===h)return;'
|
|
96
|
+
+ 'sent.push(h);if(sent.length>=CAP)stopped=true;'
|
|
97
|
+
+ 'if(window.AndroidBridge&&typeof window.AndroidBridge.updateSize==="function"){'
|
|
98
|
+
+ 'try{window.AndroidBridge.updateSize(h)}catch(e){}}}'
|
|
99
|
+
+ 'function ping(){if(timer!==null)clearTimeout(timer);timer=setTimeout(report,WAIT)}'
|
|
100
|
+
+ 'if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",ping);else ping();'
|
|
101
|
+
+ 'window.addEventListener("load",ping);'
|
|
102
|
+
+ 'if(typeof ResizeObserver==="function"){try{new ResizeObserver(ping).observe(document.body)}catch(e){}}'
|
|
103
|
+
+ '})();<' + '/script>';
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const scrollControls = ({ step = 120, holdMs = 60, target = 'body', side = 'right', inset = 8, size = 36 } = {}) => {
|
|
107
|
+
const px = Number(step);
|
|
108
|
+
const hold = Number(holdMs);
|
|
109
|
+
const box = Number(size);
|
|
110
|
+
const edge = Number(inset);
|
|
111
|
+
return '<style>'
|
|
112
|
+
+ '#__sc{position:fixed;' + side + ':' + edge + 'px;bottom:' + edge + 'px;z-index:2147483647;'
|
|
113
|
+
+ 'display:none;flex-direction:column;gap:' + Math.round(box / 6) + 'px}'
|
|
114
|
+
+ '#__sc button{width:' + box + 'px;height:' + box + 'px;padding:0;border:0;'
|
|
115
|
+
+ 'border-radius:' + Math.round(box / 4) + 'px;background:rgba(0,0,0,.6);color:#fff;'
|
|
116
|
+
+ 'font:' + Math.round(box / 2) + 'px/1 system-ui;touch-action:none;cursor:pointer;'
|
|
117
|
+
+ '-webkit-tap-highlight-color:transparent}'
|
|
118
|
+
+ '#__sc button:disabled{opacity:.3}'
|
|
119
|
+
+ '</style>'
|
|
120
|
+
+ '<script>(function(){'
|
|
121
|
+
+ 'var STEP=' + px + ',HOLD=' + hold + ',SEL=' + JSON.stringify(target) + ';'
|
|
122
|
+
+ 'var box,up,down,timer=null;'
|
|
123
|
+
+ 'function pane(){return document.querySelector(SEL)||document.scrollingElement||document.body}'
|
|
124
|
+
+ 'function room(){var p=pane();return p?p.scrollHeight-p.clientHeight:0}'
|
|
125
|
+
+ 'function sync(){if(!box)return;var p=pane(),r=room();'
|
|
126
|
+
+ 'box.style.display=r>4?"flex":"none";if(r<=4)return;'
|
|
127
|
+
+ 'up.disabled=p.scrollTop<=0;down.disabled=p.scrollTop>=r-1}'
|
|
128
|
+
+ 'function move(by){var p=pane();if(!p)return;p.scrollTop+=by;sync()}'
|
|
129
|
+
+ 'function stop(){if(timer!==null){clearInterval(timer);timer=null}}'
|
|
130
|
+
+ 'function press(e,by){e.preventDefault();e.stopPropagation();stop();move(by);'
|
|
131
|
+
+ 'timer=setInterval(function(){move(by)},HOLD)}'
|
|
132
|
+
+ 'function make(label,by){var b=document.createElement("button");b.type="button";'
|
|
133
|
+
+ 'b.textContent=label;b.setAttribute("aria-label",by<0?"scroll up":"scroll down");'
|
|
134
|
+
+ 'b.addEventListener("touchstart",function(e){press(e,by)},{passive:false});'
|
|
135
|
+
+ 'b.addEventListener("touchend",function(e){e.preventDefault();stop()},{passive:false});'
|
|
136
|
+
+ 'b.addEventListener("touchcancel",stop);'
|
|
137
|
+
+ 'b.addEventListener("mousedown",function(e){press(e,by)});'
|
|
138
|
+
+ 'b.addEventListener("mouseup",stop);b.addEventListener("mouseleave",stop);'
|
|
139
|
+
+ 'b.addEventListener("click",function(e){e.preventDefault();e.stopPropagation()});'
|
|
140
|
+
+ 'return b}'
|
|
141
|
+
+ 'function start(){if(box)return;'
|
|
142
|
+
+ 'box=document.createElement("div");box.id="__sc";'
|
|
143
|
+
+ 'up=make("\\u25b2",-STEP);down=make("\\u25bc",STEP);'
|
|
144
|
+
+ 'box.appendChild(up);box.appendChild(down);document.body.appendChild(box);'
|
|
145
|
+
+ 'var p=pane();if(p&&p.addEventListener)p.addEventListener("scroll",sync,{passive:true});'
|
|
146
|
+
+ 'if(typeof ResizeObserver==="function"){try{new ResizeObserver(sync).observe(document.body)}catch(e){}}'
|
|
147
|
+
+ 'addEventListener("load",sync);sync()}'
|
|
148
|
+
+ 'if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",start);else start();'
|
|
149
|
+
+ 'window.__scrollControls={by:move,sync:sync};'
|
|
150
|
+
+ '})();<' + '/script>';
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const AI_RICH_HTML_PRIMITIVE = 'GenAIaeacdsnwHtmlPrimitive';
|
|
154
|
+
|
|
155
|
+
const htmlSection = (html, { trustedSources = [], height, typename = AI_RICH_HTML_PRIMITIVE } = {}) => {
|
|
156
|
+
if (typeof html !== 'string' || html.trim() === '') {
|
|
157
|
+
throw new TypeError('htmlSection requires a non-empty HTML string');
|
|
158
|
+
}
|
|
159
|
+
return getAIRich().newLayout('Single', {
|
|
160
|
+
payload: height === undefined ? html : lockHeight(height) + html,
|
|
161
|
+
trusted_sources: Array.isArray(trustedSources) ? trustedSources.map(String) : [],
|
|
162
|
+
__typename: typename
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* sendHtmlApp: sends an HTML app with automatic anti-unduh (bypass download)
|
|
168
|
+
* and full dual support for WhatsApp Business and regular WhatsApp.
|
|
169
|
+
*/
|
|
170
|
+
const sendHtmlApp = async (sock, jid, html, {
|
|
171
|
+
title = '',
|
|
172
|
+
label,
|
|
173
|
+
trustedSources = [],
|
|
174
|
+
height,
|
|
175
|
+
autoHeight: auto,
|
|
176
|
+
scrollButtons,
|
|
177
|
+
typename,
|
|
178
|
+
id,
|
|
179
|
+
bypassDownload = true,
|
|
180
|
+
guard = 'warn',
|
|
181
|
+
botJid = '867051314767696@bot',
|
|
182
|
+
contextInfo = {},
|
|
183
|
+
...options
|
|
184
|
+
} = {}) => {
|
|
185
|
+
if (!sock) {
|
|
186
|
+
throw new TypeError('sendHtmlApp requires a socket as the first argument');
|
|
187
|
+
}
|
|
188
|
+
if (!jid) {
|
|
189
|
+
throw new TypeError('sendHtmlApp requires a target jid');
|
|
190
|
+
}
|
|
191
|
+
if (auto && height !== undefined) {
|
|
192
|
+
throw new TypeError('sendHtmlApp takes either height or autoHeight, not both');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (auto) {
|
|
196
|
+
html = autoHeight(auto === true ? undefined : auto) + html;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (scrollButtons) {
|
|
200
|
+
html += scrollControls(scrollButtons === true ? undefined : scrollButtons);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (guard !== false) {
|
|
204
|
+
const report = checkHtmlApp(html, { height });
|
|
205
|
+
if (!report.ok && guard === true) {
|
|
206
|
+
throw new TypeError('this html app will not behave in the WebView:\n ' + report.problems.join('\n '));
|
|
207
|
+
}
|
|
208
|
+
if (guard === 'warn') {
|
|
209
|
+
for (const problem of report.problems) {
|
|
210
|
+
sock.logger?.warn({ jid }, 'html app: ' + problem);
|
|
211
|
+
}
|
|
212
|
+
for (const warning of report.warnings) {
|
|
213
|
+
sock.logger?.warn({ jid }, 'html app: ' + warning);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const rich = new (getAIRich())(sock);
|
|
219
|
+
|
|
220
|
+
if (title) {
|
|
221
|
+
rich.setTitle(title);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
rich._addContent(
|
|
225
|
+
htmlSection(html, { trustedSources, height, ...(typename ? { typename } : {}) }),
|
|
226
|
+
label ? { messageType: 2, messageText: String(label) } : undefined,
|
|
227
|
+
id ? { id } : {}
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
const mergedContextInfo = {
|
|
231
|
+
forwardingScore: 1,
|
|
232
|
+
isForwarded: true,
|
|
233
|
+
forwardedAiBotMessageInfo: { botJid },
|
|
234
|
+
forwardOrigin: 4,
|
|
235
|
+
...(typeof global !== 'undefined' && global.owner ? {
|
|
236
|
+
businessMessageForwardInfo: { businessOwnerJid: global.owner + '@s.whatsapp.net' }
|
|
237
|
+
} : {}),
|
|
238
|
+
...contextInfo
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
return rich.send(jid, {
|
|
242
|
+
bypassDownload,
|
|
243
|
+
botJid,
|
|
244
|
+
contextInfo: mergedContextInfo,
|
|
245
|
+
...options
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const sendHtmlDocument = async (sock, jid, html, { fileName = 'app.html', caption, ...options } = {}) => {
|
|
250
|
+
if (!sock) {
|
|
251
|
+
throw new TypeError('sendHtmlDocument requires a socket as the first argument');
|
|
252
|
+
}
|
|
253
|
+
if (!jid) {
|
|
254
|
+
throw new TypeError('sendHtmlDocument requires a target jid');
|
|
255
|
+
}
|
|
256
|
+
if (typeof html !== 'string' || html.trim() === '') {
|
|
257
|
+
throw new TypeError('sendHtmlDocument requires a non-empty HTML string');
|
|
258
|
+
}
|
|
259
|
+
const name = String(fileName);
|
|
260
|
+
if (!/\.html?$/i.test(name)) {
|
|
261
|
+
throw new TypeError('sendHtmlDocument fileName must end with .html or .htm');
|
|
262
|
+
}
|
|
263
|
+
return sock.sendMessage(jid, {
|
|
264
|
+
document: Buffer.from(html, 'utf-8'),
|
|
265
|
+
mimetype: HTML_MIME_TYPE,
|
|
266
|
+
fileName: name,
|
|
267
|
+
...(caption ? { caption: String(caption) } : {}),
|
|
268
|
+
...options
|
|
269
|
+
});
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
const fileArtifact = (typename) => (url, { title = '', fileExtension = 'html', fileLength = 0, pageCount, previewImage } = {}) => {
|
|
273
|
+
if (typeof url !== 'string' || url.trim() === '') {
|
|
274
|
+
throw new TypeError('a file section requires a non-empty url');
|
|
275
|
+
}
|
|
276
|
+
return getAIRich().newLayout('Single', {
|
|
277
|
+
title: String(title),
|
|
278
|
+
url,
|
|
279
|
+
file_extension: String(fileExtension).replace(/^\./, ''),
|
|
280
|
+
file_length: Number(fileLength) || 0,
|
|
281
|
+
page_count: pageCount === undefined ? undefined : Number(pageCount) || 0,
|
|
282
|
+
preview_image: previewImage,
|
|
283
|
+
__typename: typename
|
|
284
|
+
});
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
const fileSection = fileArtifact('GenAIFilePrimitive');
|
|
288
|
+
|
|
289
|
+
const fileLinkSection = fileArtifact('GenAIFileLinkPrimitive');
|
|
290
|
+
|
|
291
|
+
export { HTML_APP_MESSAGE_CEILING, HTML_APP_BYTE_BUDGET, HTML_APP_BYTE_LIMIT, HTML_MIME_TYPE, wireBytes, checkHtmlApp, lockHeight, autoHeight, scrollControls, htmlSection, sendHtmlApp, sendHtmlDocument, fileSection, fileLinkSection };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import NodeCache from '@cacheable/node-cache';
|
|
2
|
+
import { areJidsSameUser, getBinaryNodeChild, jidDecode } from '../WABinary/index.js';
|
|
3
|
+
import { isStringNullOrEmpty } from './generics.js';
|
|
4
|
+
export async function handleIdentityChange(node, ctx) {
|
|
5
|
+
const from = node.attrs.from;
|
|
6
|
+
if (!from) {
|
|
7
|
+
return { action: 'invalid_notification' };
|
|
8
|
+
}
|
|
9
|
+
const identityNode = getBinaryNodeChild(node, 'identity');
|
|
10
|
+
if (!identityNode) {
|
|
11
|
+
return { action: 'no_identity_node' };
|
|
12
|
+
}
|
|
13
|
+
ctx.logger.info({ jid: from }, 'identity changed');
|
|
14
|
+
const decoded = jidDecode(from);
|
|
15
|
+
if (decoded?.device && decoded.device !== 0) {
|
|
16
|
+
ctx.logger.debug({ jid: from, device: decoded.device }, 'ignoring identity change from companion device');
|
|
17
|
+
return { action: 'skipped_companion_device', device: decoded.device };
|
|
18
|
+
}
|
|
19
|
+
const isSelfPrimary = ctx.meId && (areJidsSameUser(from, ctx.meId) || (ctx.meLid && areJidsSameUser(from, ctx.meLid)));
|
|
20
|
+
if (isSelfPrimary) {
|
|
21
|
+
ctx.logger.info({ jid: from }, 'self primary identity changed');
|
|
22
|
+
return { action: 'skipped_self_primary' };
|
|
23
|
+
}
|
|
24
|
+
if (ctx.debounceCache.get(from)) {
|
|
25
|
+
ctx.logger.debug({ jid: from }, 'skipping identity assert (debounced)');
|
|
26
|
+
return { action: 'debounced' };
|
|
27
|
+
}
|
|
28
|
+
ctx.debounceCache.set(from, true);
|
|
29
|
+
const isOfflineNotification = !isStringNullOrEmpty(node.attrs.offline);
|
|
30
|
+
const hasExistingSession = await ctx.validateSession(from);
|
|
31
|
+
if (!hasExistingSession.exists) {
|
|
32
|
+
ctx.logger.debug({ jid: from }, 'no old session, skipping session refresh');
|
|
33
|
+
return { action: 'skipped_no_session' };
|
|
34
|
+
}
|
|
35
|
+
ctx.logger.debug({ jid: from }, 'old session exists, will refresh session');
|
|
36
|
+
if (isOfflineNotification) {
|
|
37
|
+
ctx.logger.debug({ jid: from }, 'skipping session refresh during offline processing');
|
|
38
|
+
return { action: 'skipped_offline' };
|
|
39
|
+
}
|
|
40
|
+
ctx.onBeforeSessionRefresh?.(from);
|
|
41
|
+
try {
|
|
42
|
+
await ctx.assertSessions([from], true);
|
|
43
|
+
return { action: 'session_refreshed' };
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
ctx.logger.warn({ error, jid: from }, 'failed to assert sessions after identity change');
|
|
47
|
+
return { action: 'session_refresh_failed', error };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=identity-change-handler.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export * from './generics.js';
|
|
2
|
+
export * from './decode-wa-message.js';
|
|
3
|
+
export * from './messages.js';
|
|
4
|
+
export * from './messages-media.js';
|
|
5
|
+
export * from './validate-connection.js';
|
|
6
|
+
export * from './crypto.js';
|
|
7
|
+
export * from './signal.js';
|
|
8
|
+
export * from './noise-handler.js';
|
|
9
|
+
export * from './history.js';
|
|
10
|
+
export * from './chat-utils.js';
|
|
11
|
+
export * from './lt-hash.js';
|
|
12
|
+
export * from './auth-utils.js';
|
|
13
|
+
export * from './use-multi-file-auth-state.js';
|
|
14
|
+
export * from './use-sqlite-auth-state.js';
|
|
15
|
+
export * from './link-preview.js';
|
|
16
|
+
export * from './event-buffer.js';
|
|
17
|
+
export * from './process-message.js';
|
|
18
|
+
export * from './message-retry-manager.js';
|
|
19
|
+
export * from './browser-utils.js';
|
|
20
|
+
export * from './companion-reg-client-utils.js';
|
|
21
|
+
export * from './identity-change-handler.js';
|
|
22
|
+
export * from './stanza-ack.js';
|
|
23
|
+
export * from './message-composer.js';
|
|
24
|
+
export * from './newsletter-status.js';
|
|
25
|
+
export { sPR, selectiveRelay } from './dinonic-spr.js';
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
27
|
+
export * from './a2ui.js';
|
|
28
|
+
export * from './html-app.js';
|
|
29
|
+
export { AIRichMessage, AI_RICH_HTML_PRIMITIVE, AI_RICH_HTML_PRIMITIVE_CLASS, AI_RICH_INLINE_ENTITIES, AI_RICH_ITEMS, AI_RICH_LAYOUTS, AI_RICH_NESTED_UNIFIED_RESPONSE_TYPENAME, AI_RICH_NODES, AI_RICH_PRIMITIVES, AI_RICH_PRIMITIVES_WEB_RENDERED, AI_RICH_PRIMITIVES_WITHOUT_SCHEMA, AI_RICH_PRIMITIVE_INTERFACE, AI_RICH_RESPONSE_KEYS, AI_RICH_SECTION_TYPENAME, AI_RICH_SUBMESSAGE_CONTENT_ITEMS, AI_RICH_SUBMESSAGE_INLINE_IMAGE, AI_RICH_SUBMESSAGE_KINDS, AI_RICH_SUBMESSAGE_TABLE, AI_RICH_SUBMESSAGE_TEXT, AI_RICH_UNIFIED_RESPONSE_TYPENAME, AI_RICH_UNIFIED_RESPONSE_TYPENAME_APP, AddonActionType, DividerType, EMBEDDED_SCREEN_CONTEXTUAL_TYPENAME, EMBEDDED_SCREEN_PRESENTATION, EMBEDDED_SCREEN_SINGLE_TYPENAME, EMBEDDED_SCREEN_TABBED_TYPENAME, EMBEDDED_SCREEN_TAB_TYPENAME, EMBEDDED_SCREEN_TYPENAME, FooterActionType, HTML_APP_BRIDGE, ImagineStatus, ImagineType, SourceProvider, TaskStatus, ThinkingIcon, a2uiFallback, a2uiInfoCard, a2uiListCard, aiRichContentItems, aiRichInlineImage, aiRichSubmessage, aiRichTable, aiRichText, botMediaMetadata, botSourcesMetadata, buildA2UISection, collectTypenames, dataUri, decodeAIRich, decodeBloksWidget, dividerSection, embeddedScreen, embeddedTab, embeddedTabbedContent, footerActionSection, htmlMedia, imageSection, latexSection, prepareFileArtifact, progressSection, readEmbeddedSections, readEmbeddedTabs, readRichMessage, sendA2UIBloks, sendAIRichMessage, sendHtmlArtifact, spacerSection, taskSection, thinkingSection } from './extras.js';
|
|
30
|
+
export { AccountLinkingIntegration, AccountLinkingStatus, ActionListRowType, AddonActionAlignment, CalendarEventOperation, CalendarEventState, ClippyArtifactType, CodeBlockType, CompactEntityActionType, CompactEntityType, FollowUpSuggestionCategory, ImageAssetQueryStatus, InformTreatmentRenderingType, MapItemMarkerType, MapQueryStatus, MediaHorizontalAlignment, MediaShape, MediaVerticalAlignment, MultipleResponseLayoutType, OrchestratorSearchEngine, PlaceDetailsItemType, PlaceOpeningStatus, PlacePriceLevel, PostOrientation, PostType, ProductSourceType, ProfessionalConsentStatus, QuotaUpsellMeterUsageType, SearchPlannerStepStatus, SocialEntityItemType, SourceApp, SportsGameStatus, SportsLeague, SportsSeasonType, ThreadSurfingActionType, ThreadSurfingEntityType, UnifiedResponseMessageGroupKind, UnifiedResponseSectionType, WidgetCtaKind, WidgetCtaState, accountLinkingApp, accountLinkingSection, actionGroupButton, actionGroupSection, actionListRow, actionListSection, addonActionSection, bloomCardSection, calendarEvent, calendarWidgetSection, chainOfThoughtSection, chainingSuggestionSection, commentSection, compactEntitySection, contextualSourcesSection, customSection, forwardRichResponse, fusedComparisonColumn, fusedComparisonCta, fusedComparisonRow, fusedComparisonSection, locationPermissionSection, mapSection, mediaGridSection, mediaItem, multipleResponseSection, placeEntityItem, placeItem, plannerSnippetSection, plannerStep, productEntityItem, professionalConsentSection, quizQuestion, quizSection, quotaUpsellButton, quotaUpsellSection, readSignedRichResponse, reminderSection, searchAdSection, searchPlannerSection, searchResultV2Section, sideBySideSurveyItem, socialEntityItem, sportsSection, threadSurfingItem, timestampPlaceholderSection, transparencySection, transparencySignal, verifyRichResponseSignature, videoSection } from './metaai.js';
|
|
31
|
+
export * from './modern-messages.js';
|
|
32
|
+
export * from './native-flow.js';
|
|
33
|
+
export * from './payment-messages.js';
|
|
34
|
+
export * from './scheduled-message.js';
|
|
35
|
+
export * from './status-stickers.js';
|
|
36
|
+
export * from './bot-signature.js';
|
|
37
|
+
export * from './baileys-event-stream.js';
|
|
38
|
+
export * as DinonicBuilder from './MessageBuilder.js';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { prepareWAMessageMedia } from './messages.js';
|
|
2
|
+
import { extractImageThumb, getHttpStream } from './messages-media.js';
|
|
3
|
+
const THUMBNAIL_WIDTH_PX = 192;
|
|
4
|
+
/** Fetches an image and generates a thumbnail for it */
|
|
5
|
+
const getCompressedJpegThumbnail = async (url, { thumbnailWidth, fetchOpts }) => {
|
|
6
|
+
const stream = await getHttpStream(url, fetchOpts);
|
|
7
|
+
const result = await extractImageThumb(stream, thumbnailWidth);
|
|
8
|
+
return result;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Given a piece of text, checks for any URL present, generates link preview for the same and returns it
|
|
12
|
+
* Return undefined if the fetch failed or no URL was found
|
|
13
|
+
* @param text first matched URL in text
|
|
14
|
+
* @returns the URL info required to generate link preview
|
|
15
|
+
*/
|
|
16
|
+
export const getUrlInfo = async (text, opts = {
|
|
17
|
+
thumbnailWidth: THUMBNAIL_WIDTH_PX,
|
|
18
|
+
fetchOpts: { timeout: 3000 }
|
|
19
|
+
}) => {
|
|
20
|
+
try {
|
|
21
|
+
// retries
|
|
22
|
+
let retries = 0;
|
|
23
|
+
const maxRetry = 5;
|
|
24
|
+
const { getLinkPreview } = await import('link-preview-js');
|
|
25
|
+
let previewLink = text;
|
|
26
|
+
if (!text.startsWith('https://') && !text.startsWith('http://')) {
|
|
27
|
+
previewLink = 'https://' + previewLink;
|
|
28
|
+
}
|
|
29
|
+
const info = await getLinkPreview(previewLink, {
|
|
30
|
+
...opts.fetchOpts,
|
|
31
|
+
followRedirects: 'follow',
|
|
32
|
+
handleRedirects: (baseURL, forwardedURL) => {
|
|
33
|
+
const urlObj = new URL(baseURL);
|
|
34
|
+
const forwardedURLObj = new URL(forwardedURL);
|
|
35
|
+
if (retries >= maxRetry) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
if (forwardedURLObj.hostname === urlObj.hostname ||
|
|
39
|
+
forwardedURLObj.hostname === 'www.' + urlObj.hostname ||
|
|
40
|
+
'www.' + forwardedURLObj.hostname === urlObj.hostname) {
|
|
41
|
+
retries += 1;
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
headers: opts.fetchOpts?.headers
|
|
49
|
+
});
|
|
50
|
+
if (info && 'title' in info && info.title) {
|
|
51
|
+
const [image] = info.images;
|
|
52
|
+
const urlInfo = {
|
|
53
|
+
'canonical-url': info.url,
|
|
54
|
+
'matched-text': text,
|
|
55
|
+
title: info.title,
|
|
56
|
+
description: info.description,
|
|
57
|
+
originalThumbnailUrl: image
|
|
58
|
+
};
|
|
59
|
+
if (opts.uploadImage) {
|
|
60
|
+
const { imageMessage } = await prepareWAMessageMedia({ image: { url: image } }, {
|
|
61
|
+
upload: opts.uploadImage,
|
|
62
|
+
mediaTypeOverride: 'thumbnail-link',
|
|
63
|
+
options: opts.fetchOpts
|
|
64
|
+
});
|
|
65
|
+
urlInfo.jpegThumbnail = imageMessage?.jpegThumbnail ? Buffer.from(imageMessage.jpegThumbnail) : undefined;
|
|
66
|
+
urlInfo.highQualityThumbnail = imageMessage || undefined;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
try {
|
|
70
|
+
urlInfo.jpegThumbnail = image ? (await getCompressedJpegThumbnail(image, opts)).buffer : undefined;
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
opts.logger?.debug({ err: error.stack, url: previewLink }, 'error in generating thumbnail');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return urlInfo;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (!error.message.includes('receive a valid')) {
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
//# sourceMappingURL=link-preview.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LTHashAntiTampering } from 'whatsapp-rust-bridge';
|
|
2
|
+
/**
|
|
3
|
+
* LT Hash is a summation based hash algorithm that maintains the integrity of a piece of data
|
|
4
|
+
* over a series of mutations. You can add/remove mutations and it'll return a hash equal to
|
|
5
|
+
* if the same series of mutations was made sequentially.
|
|
6
|
+
*/
|
|
7
|
+
export const LT_HASH_ANTI_TAMPERING = new LTHashAntiTampering();
|
|
8
|
+
//# sourceMappingURL=lt-hash.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Mutex as AsyncMutex } from 'async-mutex';
|
|
2
|
+
export const makeMutex = () => {
|
|
3
|
+
const mutex = new AsyncMutex();
|
|
4
|
+
return {
|
|
5
|
+
mutex(code) {
|
|
6
|
+
return mutex.runExclusive(code);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export const makeKeyedMutex = () => {
|
|
11
|
+
const map = new Map();
|
|
12
|
+
return {
|
|
13
|
+
async mutex(key, task) {
|
|
14
|
+
let entry = map.get(key);
|
|
15
|
+
if (!entry) {
|
|
16
|
+
entry = { mutex: new AsyncMutex(), refCount: 0 };
|
|
17
|
+
map.set(key, entry);
|
|
18
|
+
}
|
|
19
|
+
entry.refCount++;
|
|
20
|
+
try {
|
|
21
|
+
return await entry.mutex.runExclusive(task);
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
entry.refCount--;
|
|
25
|
+
// only delete it if this is still the current entry
|
|
26
|
+
if (entry.refCount === 0 && map.get(key) === entry) {
|
|
27
|
+
map.delete(key);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=make-mutex.js.map
|