@open-wa/wa-automate 4.76.0 → 5.0.0-alpha.2

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.
Files changed (125) hide show
  1. package/README.md +14 -165
  2. package/dist/cli-runtime-B7_3MM0c.cjs +798 -0
  3. package/dist/cli-runtime-B7_3MM0c.cjs.map +1 -0
  4. package/dist/cli-runtime-CmpYxFCk.d.cts +31 -0
  5. package/dist/cli-runtime-CmpYxFCk.d.cts.map +1 -0
  6. package/dist/cli.cjs +17 -0
  7. package/dist/cli.cjs.map +1 -0
  8. package/dist/cli.d.cts +2 -0
  9. package/dist/index.cjs +224 -0
  10. package/dist/index.cjs.map +1 -0
  11. package/dist/index.d.cts +81 -0
  12. package/dist/index.d.cts.map +1 -0
  13. package/package.json +34 -177
  14. package/CNAME +0 -1
  15. package/_tsconfig.docs.json +0 -140
  16. package/bin/config-schema.json +0 -1
  17. package/bin/oas-type-schemas.json +0 -1
  18. package/bin/server.js +0 -45
  19. package/build/build-config-json-for-bin.ts +0 -56
  20. package/build/generate-oas-types.ts +0 -31
  21. package/dist/api/Client.d.ts +0 -2255
  22. package/dist/api/Client.js +0 -4358
  23. package/dist/api/functions/exposed.enum.d.ts +0 -7
  24. package/dist/api/functions/exposed.enum.js +0 -11
  25. package/dist/api/model/aliases.d.ts +0 -110
  26. package/dist/api/model/aliases.js +0 -3
  27. package/dist/api/model/button.d.ts +0 -24
  28. package/dist/api/model/button.js +0 -2
  29. package/dist/api/model/call.d.ts +0 -51
  30. package/dist/api/model/call.js +0 -18
  31. package/dist/api/model/chat.d.ts +0 -221
  32. package/dist/api/model/chat.js +0 -52
  33. package/dist/api/model/config.d.ts +0 -836
  34. package/dist/api/model/config.js +0 -111
  35. package/dist/api/model/contact.d.ts +0 -143
  36. package/dist/api/model/contact.js +0 -2
  37. package/dist/api/model/errors.d.ts +0 -90
  38. package/dist/api/model/errors.js +0 -117
  39. package/dist/api/model/events.d.ts +0 -120
  40. package/dist/api/model/events.js +0 -127
  41. package/dist/api/model/group-metadata.d.ts +0 -124
  42. package/dist/api/model/group-metadata.js +0 -25
  43. package/dist/api/model/id.d.ts +0 -5
  44. package/dist/api/model/id.js +0 -2
  45. package/dist/api/model/index.d.ts +0 -110
  46. package/dist/api/model/index.js +0 -128
  47. package/dist/api/model/label.d.ts +0 -24
  48. package/dist/api/model/label.js +0 -2
  49. package/dist/api/model/media.d.ts +0 -93
  50. package/dist/api/model/media.js +0 -12
  51. package/dist/api/model/message.d.ts +0 -422
  52. package/dist/api/model/message.js +0 -40
  53. package/dist/api/model/product.d.ts +0 -141
  54. package/dist/api/model/product.js +0 -2
  55. package/dist/api/model/reactions.d.ts +0 -76
  56. package/dist/api/model/reactions.js +0 -2
  57. package/dist/api/model/sessionInfo.d.ts +0 -77
  58. package/dist/api/model/sessionInfo.js +0 -2
  59. package/dist/build/build-postman.d.ts +0 -1
  60. package/dist/build/build-postman.js +0 -262
  61. package/dist/cli/cli-options.d.ts +0 -9
  62. package/dist/cli/cli-options.js +0 -289
  63. package/dist/cli/collections.d.ts +0 -2
  64. package/dist/cli/collections.js +0 -251
  65. package/dist/cli/file-utils.d.ts +0 -1
  66. package/dist/cli/file-utils.js +0 -71
  67. package/dist/cli/index.d.ts +0 -1
  68. package/dist/cli/index.js +0 -231
  69. package/dist/cli/integrations/chatwoot.d.ts +0 -49
  70. package/dist/cli/integrations/chatwoot.js +0 -672
  71. package/dist/cli/integrations/cloudflare.d.ts +0 -6
  72. package/dist/cli/integrations/cloudflare.js +0 -76
  73. package/dist/cli/logo.d.ts +0 -1
  74. package/dist/cli/logo.js +0 -49
  75. package/dist/cli/server.d.ts +0 -24
  76. package/dist/cli/server.js +0 -540
  77. package/dist/cli/setup.d.ts +0 -30
  78. package/dist/cli/setup.js +0 -308
  79. package/dist/config/puppeteer.config.d.ts +0 -11
  80. package/dist/config/puppeteer.config.js +0 -65
  81. package/dist/controllers/auth.d.ts +0 -36
  82. package/dist/controllers/auth.js +0 -322
  83. package/dist/controllers/browser.d.ts +0 -17
  84. package/dist/controllers/browser.js +0 -603
  85. package/dist/controllers/events.d.ts +0 -82
  86. package/dist/controllers/events.js +0 -173
  87. package/dist/controllers/init_patch.d.ts +0 -13
  88. package/dist/controllers/init_patch.js +0 -42
  89. package/dist/controllers/initializer.d.ts +0 -22
  90. package/dist/controllers/initializer.js +0 -511
  91. package/dist/controllers/launch_checks.d.ts +0 -8
  92. package/dist/controllers/launch_checks.js +0 -130
  93. package/dist/controllers/patch_manager.d.ts +0 -37
  94. package/dist/controllers/patch_manager.js +0 -231
  95. package/dist/controllers/popup/index.d.ts +0 -3
  96. package/dist/controllers/popup/index.html +0 -168
  97. package/dist/controllers/popup/index.js +0 -148
  98. package/dist/controllers/script_preloader.d.ts +0 -17
  99. package/dist/controllers/script_preloader.js +0 -88
  100. package/dist/index.d.ts +0 -13
  101. package/dist/index.js +0 -36
  102. package/dist/lib/README.md +0 -5
  103. package/dist/lib/base64.js +0 -1
  104. package/dist/lib/hash.js +0 -1
  105. package/dist/lib/jsSha.min.js +0 -1
  106. package/dist/lib/launch.js +0 -1
  107. package/dist/lib/qr.min.js +0 -1
  108. package/dist/lib/wapi.js +0 -2163
  109. package/dist/logging/custom_transport.d.ts +0 -9
  110. package/dist/logging/custom_transport.js +0 -35
  111. package/dist/logging/logging.d.ts +0 -50
  112. package/dist/logging/logging.js +0 -196
  113. package/dist/structures/Collector.d.ts +0 -202
  114. package/dist/structures/Collector.js +0 -391
  115. package/dist/structures/Dialog.d.ts +0 -55
  116. package/dist/structures/Dialog.js +0 -21
  117. package/dist/structures/MessageCollector.d.ts +0 -78
  118. package/dist/structures/MessageCollector.js +0 -145
  119. package/dist/structures/preProcessors.d.ts +0 -58
  120. package/dist/structures/preProcessors.js +0 -181
  121. package/dist/utils/pid_utils.d.ts +0 -1
  122. package/dist/utils/pid_utils.js +0 -26
  123. package/dist/utils/tools.d.ts +0 -152
  124. package/dist/utils/tools.js +0 -494
  125. package/tos.md +0 -77
@@ -1,603 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
- return new (P || (P = Promise))(function (resolve, reject) {
28
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
- step((generator = generator.apply(thisArg, _arguments || [])).next());
32
- });
33
- };
34
- var __importDefault = (this && this.__importDefault) || function (mod) {
35
- return (mod && mod.__esModule) ? mod : { "default": mod };
36
- };
37
- Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.kill = exports.injectApi = exports.injectWapi = exports.injectPreApiScripts = exports.addScript = exports.getSessionDataFilePath = exports.invalidateSesssionData = exports.deleteSessionData = exports.initPage = exports.BROWSER_START_TS = void 0;
39
- const path = __importStar(require("path"));
40
- const fs = __importStar(require("fs/promises"));
41
- const readline = __importStar(require("readline"));
42
- const death_1 = __importDefault(require("death"));
43
- // import puppeteer from 'puppeteer-extra';
44
- const puppeteer_config_1 = require("../config/puppeteer.config");
45
- const puppeteer_1 = require("puppeteer");
46
- const events_1 = require("./events");
47
- const pico_s3_1 = require("pico-s3");
48
- // eslint-disable-next-line @typescript-eslint/no-var-requires
49
- const puppeteer = require('puppeteer-extra');
50
- const promise_1 = __importDefault(require("terminate/promise"));
51
- const logging_1 = require("../logging/logging");
52
- const tools_1 = require("../utils/tools");
53
- const script_preloader_1 = require("./script_preloader");
54
- const patch_manager_1 = require("./patch_manager");
55
- const init_patch_1 = require("./init_patch");
56
- let browser, wapiInjected = false, pageCache = undefined, wapiAttempts = 1;
57
- exports.BROWSER_START_TS = 0;
58
- function initPage(sessionId, config, qrManager, customUserAgent, spinner, _page, skipAuth) {
59
- var _a, _b, _c, _d, _e;
60
- return __awaiter(this, void 0, void 0, function* () {
61
- const setupPromises = [];
62
- yield script_preloader_1.scriptLoader.loadScripts();
63
- if ((config === null || config === void 0 ? void 0 : config.resizable) === undefined || !(config === null || config === void 0 ? void 0 : config.resizable) == false)
64
- config.defaultViewport = null;
65
- if (config === null || config === void 0 ? void 0 : config.useStealth) {
66
- const { default: stealth } = yield Promise.resolve().then(() => __importStar(require('puppeteer-extra-plugin-stealth')));
67
- puppeteer.use(stealth());
68
- }
69
- let waPage = _page;
70
- if (!waPage) {
71
- spinner === null || spinner === void 0 ? void 0 : spinner.info('Launching Browser');
72
- const startBrowser = (0, tools_1.now)();
73
- browser = yield initBrowser(sessionId, config, spinner);
74
- spinner === null || spinner === void 0 ? void 0 : spinner.info(`Browser launched: ${((0, tools_1.now)() - startBrowser).toFixed(0)}ms`);
75
- waPage = yield getWAPage(browser);
76
- if (process.stdin.setRawMode && typeof process.stdin.setRawMode == "function") {
77
- readline.emitKeypressEvents(process.stdin);
78
- process.stdin.setRawMode(true);
79
- console.log('Press "s" to take a screenshot. Press "Ctrl+C" to quit.');
80
- process.stdin.on('keypress', (str, key) => __awaiter(this, void 0, void 0, function* () {
81
- if (key.name === 's') {
82
- const path = `./screenshot_${config.sessionId || "session"}_${Date.now()}.png`;
83
- console.log(`Taking screenshot: ${path} ...`);
84
- yield waPage.screenshot({ path });
85
- }
86
- if (key.ctrl && key.name === 'c') {
87
- process.exit();
88
- }
89
- }));
90
- }
91
- else
92
- console.log("Unable to set raw mode on stdin. Keypress events will not be emitted. You cannot take a screenshot by pressing 's' during launch.");
93
- }
94
- //@ts-ignore
95
- yield (typeof waPage._client === 'function' && waPage._client() || waPage._client).send('Network.setBypassServiceWorker', { bypass: true });
96
- const postBrowserLaunchTs = (0, tools_1.now)();
97
- waPage.on("framenavigated", (frame) => __awaiter(this, void 0, void 0, function* () {
98
- try {
99
- const frameNavPromises = [];
100
- // const content = await frame.content() //not using content right now so save some ms by commenting out
101
- logging_1.log.info(`FRAME NAV DETECTED, ${frame.url()}, Reinjecting APIs...`);
102
- // there's no more webpack so reinject anyways
103
- const hasWapi = yield waPage.evaluate("window.WAPI ? true : false");
104
- if (!hasWapi) {
105
- logging_1.log.info("FN: WAPI missing. Reinjecting APIs...");
106
- frameNavPromises.push(injectApi(waPage, spinner, true));
107
- frameNavPromises.push(qrManager.waitFirstQr(waPage, config, spinner));
108
- }
109
- else
110
- logging_1.log.info("FN: WAPI intact. Skipping reinjection...");
111
- if (frame.url().includes('post_logout=1')) {
112
- console.log("Session most likely logged out");
113
- }
114
- yield Promise.all(frameNavPromises);
115
- }
116
- catch (error) {
117
- logging_1.log.error('framenaverr', error);
118
- }
119
- }));
120
- spinner === null || spinner === void 0 ? void 0 : spinner.info('Setting Up Page');
121
- if (config === null || config === void 0 ? void 0 : config.proxyServerCredentials) {
122
- yield waPage.authenticate(config.proxyServerCredentials);
123
- }
124
- setupPromises.push(waPage.setUserAgent(customUserAgent || puppeteer_config_1.useragent));
125
- if ((config === null || config === void 0 ? void 0 : config.defaultViewport) !== null)
126
- setupPromises.push(waPage.setViewport({
127
- width: ((_a = config === null || config === void 0 ? void 0 : config.viewport) === null || _a === void 0 ? void 0 : _a.width) || puppeteer_config_1.width,
128
- height: ((_b = config === null || config === void 0 ? void 0 : config.viewport) === null || _b === void 0 ? void 0 : _b.height) || puppeteer_config_1.height,
129
- deviceScaleFactor: 1
130
- }));
131
- const cacheEnabled = (config === null || config === void 0 ? void 0 : config.cacheEnabled) === false ? false : true;
132
- const blockCrashLogs = (config === null || config === void 0 ? void 0 : config.blockCrashLogs) === false ? false : true;
133
- setupPromises.push(waPage.setBypassCSP((config === null || config === void 0 ? void 0 : config.bypassCSP) || false));
134
- setupPromises.push(waPage.setCacheEnabled(cacheEnabled));
135
- const blockAssets = !(config === null || config === void 0 ? void 0 : config.headless) ? false : (config === null || config === void 0 ? void 0 : config.blockAssets) || false;
136
- if (blockAssets) {
137
- const { default: block } = yield Promise.resolve().then(() => __importStar(require('puppeteer-extra-plugin-block-resources')));
138
- puppeteer.use(block({
139
- blockedTypes: new Set(['image', 'stylesheet', 'font'])
140
- }));
141
- }
142
- const interceptAuthentication = !(config === null || config === void 0 ? void 0 : config.safeMode);
143
- const proxyAddr = (config === null || config === void 0 ? void 0 : config.proxyServerCredentials) ? `${((_c = config.proxyServerCredentials) === null || _c === void 0 ? void 0 : _c.username) && ((_d = config.proxyServerCredentials) === null || _d === void 0 ? void 0 : _d.password) ? `${config.proxyServerCredentials.protocol ||
144
- config.proxyServerCredentials.address.includes('https') ? 'https' :
145
- config.proxyServerCredentials.address.includes('http') ? 'http' :
146
- config.proxyServerCredentials.address.includes('socks5') ? 'socks5' :
147
- config.proxyServerCredentials.address.includes('socks4') ? 'socks4' : 'http'}://${config.proxyServerCredentials.username}:${config.proxyServerCredentials.password}@${config.proxyServerCredentials.address
148
- .replace('https', '')
149
- .replace('http', '')
150
- .replace('socks5', '')
151
- .replace('socks4', '')
152
- .replace('://', '')}` : config.proxyServerCredentials.address}` : false;
153
- let quickAuthed = false;
154
- let proxy;
155
- if (proxyAddr) {
156
- proxy = (yield Promise.resolve().then(() => __importStar(require('smashah-puppeteer-page-proxy')))).default;
157
- }
158
- /**
159
- * Detect a locally cached page
160
- */
161
- if (process.env.WA_LOCAL_PAGE_CACHE) {
162
- const localPageCacheExists = yield (0, tools_1.pathExists)(process.env.WA_LOCAL_PAGE_CACHE, true);
163
- logging_1.log.info(`Local page cache env var set: ${process.env.WA_LOCAL_PAGE_CACHE} ${localPageCacheExists}`);
164
- if (localPageCacheExists) {
165
- logging_1.log.info(`Local page cache file exists. Loading...`);
166
- pageCache = yield fs.readFile(process.env.WA_LOCAL_PAGE_CACHE, "utf8");
167
- }
168
- }
169
- if (interceptAuthentication || proxyAddr || blockCrashLogs || true) {
170
- yield waPage.setRequestInterception(true);
171
- waPage.on('response', (response) => __awaiter(this, void 0, void 0, function* () {
172
- try {
173
- if (response.request().url() == "https://web.whatsapp.com/") {
174
- const t = yield response.text();
175
- if (t.includes(`class="no-js"`) && t.includes(`self.`) && !pageCache) {
176
- //this is a valid response, save it for later
177
- pageCache = t;
178
- logging_1.log.info("saving valid page to dumb cache");
179
- /**
180
- * Save locally
181
- */
182
- if (process.env.WA_LOCAL_PAGE_CACHE) {
183
- logging_1.log.info(`Writing page cache to local file: ${process.env.WA_LOCAL_PAGE_CACHE}`);
184
- yield fs.writeFile(process.env.WA_LOCAL_PAGE_CACHE, pageCache);
185
- }
186
- }
187
- }
188
- }
189
- catch (error) {
190
- logging_1.log.error("page cache error", error);
191
- }
192
- }));
193
- const authCompleteEv = new events_1.EvEmitter(sessionId, 'AUTH');
194
- waPage.on('request', (request) => __awaiter(this, void 0, void 0, function* () {
195
- //local refresh cache:
196
- if (request.url() === "https://web.whatsapp.com/" && pageCache) {
197
- //if the pageCache isn't set and this response includes
198
- logging_1.log.info("reviving page from page cache");
199
- return yield request.respond({
200
- status: 200,
201
- body: pageCache
202
- });
203
- }
204
- if (interceptAuthentication &&
205
- request.url().includes('_priority_components') &&
206
- !quickAuthed) {
207
- authCompleteEv.emit(true);
208
- yield waPage.evaluate('window.WA_AUTHENTICATED=true;');
209
- quickAuthed = true;
210
- }
211
- if (["https://dit.whatsapp.net/deidentified_telemetry", "https://crashlogs.whatsapp.net/"].find(u => request.url().includes(u)) && blockCrashLogs) {
212
- request.abort();
213
- }
214
- else if (proxyAddr && !(config === null || config === void 0 ? void 0 : config.useNativeProxy)) {
215
- proxy(request, proxyAddr);
216
- }
217
- else
218
- request.continue();
219
- }));
220
- }
221
- if (skipAuth) {
222
- spinner.info("Skipping Authentication");
223
- }
224
- else {
225
- /**
226
- * AUTH
227
- */
228
- spinner === null || spinner === void 0 ? void 0 : spinner.info('Loading session data');
229
- let sessionjson = yield getSessionDataFromFile(sessionId, config, spinner);
230
- if (!sessionjson && sessionjson !== "" && config.sessionDataBucketAuth) {
231
- try {
232
- spinner === null || spinner === void 0 ? void 0 : spinner.info('Unable to find session data file locally, attempting to find session data in cloud storage..');
233
- sessionjson = JSON.parse(Buffer.from(yield (0, pico_s3_1.getTextFile)(Object.assign(Object.assign({ directory: '_sessionData' }, JSON.parse(Buffer.from(config.sessionDataBucketAuth, 'base64').toString('ascii'))), { filename: `${config.sessionId || 'session'}.data.json` })), 'base64').toString('ascii'));
234
- spinner === null || spinner === void 0 ? void 0 : spinner.succeed('Successfully downloaded session data file from cloud storage!');
235
- }
236
- catch (error) {
237
- spinner === null || spinner === void 0 ? void 0 : spinner.fail(`${error instanceof pico_s3_1.FileNotFoundError ? 'The session data file was not found in the cloud storage bucket' : 'Something went wrong while fetching session data from cloud storage bucket'}. Continuing...`);
238
- }
239
- }
240
- if (sessionjson && Object.keys(sessionjson).length) {
241
- spinner === null || spinner === void 0 ? void 0 : spinner.info(config.multiDevice ? "multi-device enabled. Session data skipped..." : 'Existing session data detected. Injecting...');
242
- if (!(config === null || config === void 0 ? void 0 : config.multiDevice))
243
- yield waPage.evaluateOnNewDocument(session => {
244
- localStorage.clear();
245
- Object.keys(session).forEach(key => localStorage.setItem(key, session[key]));
246
- }, sessionjson);
247
- spinner === null || spinner === void 0 ? void 0 : spinner.succeed('Existing session data injected');
248
- }
249
- else {
250
- if (config === null || config === void 0 ? void 0 : config.multiDevice) {
251
- spinner === null || spinner === void 0 ? void 0 : spinner.info("No session data detected. Opting in for MD.");
252
- spinner === null || spinner === void 0 ? void 0 : spinner.info("Make sure to keep the session alive for at least 5 minutes after scanning the QR code before trying to restart a session!!");
253
- if (config === null || config === void 0 ? void 0 : config.legacy)
254
- yield waPage.evaluateOnNewDocument(session => {
255
- localStorage.clear();
256
- Object.keys(session).forEach(key => localStorage.setItem(key, session[key]));
257
- }, {
258
- "md-opted-in": "true",
259
- "MdUpgradeWamFlag": "true",
260
- "remember-me": "true"
261
- });
262
- }
263
- }
264
- /**
265
- * END AUTH
266
- */
267
- }
268
- if ((config === null || config === void 0 ? void 0 : config.proxyServerCredentials) && !(config === null || config === void 0 ? void 0 : config.useNativeProxy)) {
269
- yield proxy(waPage, proxyAddr);
270
- }
271
- if ((_e = config === null || config === void 0 ? void 0 : config.proxyServerCredentials) === null || _e === void 0 ? void 0 : _e.address)
272
- spinner.succeed(`Active proxy: ${config.proxyServerCredentials.address}`);
273
- yield Promise.all(setupPromises);
274
- spinner === null || spinner === void 0 ? void 0 : spinner.info(`Pre page launch setup complete: ${((0, tools_1.now)() - postBrowserLaunchTs).toFixed(0)}ms`);
275
- spinner === null || spinner === void 0 ? void 0 : spinner.info('Navigating to WA');
276
- try {
277
- //try twice
278
- const WEB_START_TS = new Date().getTime();
279
- const webRes = yield waPage.goto(puppeteer_config_1.puppeteerConfig.WAUrl);
280
- const WEB_END_TS = new Date().getTime();
281
- yield waPage.exposeFunction("ProgressBarEvent", ({ value, text }) => {
282
- spinner === null || spinner === void 0 ? void 0 : spinner.info(`${(value || value === 0) && `${value}%:\t`} ${text}`);
283
- spinner === null || spinner === void 0 ? void 0 : spinner.emit({ value, text }, "internal_launch_progress");
284
- });
285
- yield waPage.exposeFunction("CriticalInternalMessage", ({ value, text }) => __awaiter(this, void 0, void 0, function* () {
286
- spinner === null || spinner === void 0 ? void 0 : spinner.info(`${text}`);
287
- spinner === null || spinner === void 0 ? void 0 : spinner.emit({ value, text }, "critical_internal_message");
288
- if (value === "TEMP_BAN" && !(config.killProcessOnBan === false))
289
- yield (0, exports.kill)(waPage, undefined, true, undefined, "TEMP_BAN");
290
- }));
291
- yield (0, init_patch_1.injectProgObserver)(waPage);
292
- if (webRes == null) {
293
- spinner === null || spinner === void 0 ? void 0 : spinner.info(`Page loaded but something may have gone wrong: ${WEB_END_TS - WEB_START_TS}ms`);
294
- }
295
- else {
296
- spinner === null || spinner === void 0 ? void 0 : spinner.info(`Page loaded in ${WEB_END_TS - WEB_START_TS}ms: ${webRes.status()}${webRes.ok() ? '' : ', ' + webRes.statusText()}`);
297
- if (!webRes.ok())
298
- spinner === null || spinner === void 0 ? void 0 : spinner.info(`Headers Info: ${JSON.stringify(webRes.headers(), null, 2)}`);
299
- }
300
- }
301
- catch (error) {
302
- spinner === null || spinner === void 0 ? void 0 : spinner.fail(error);
303
- throw error;
304
- }
305
- return waPage;
306
- });
307
- }
308
- exports.initPage = initPage;
309
- const getSessionDataFromFile = (sessionId, config, spinner) => __awaiter(void 0, void 0, void 0, function* () {
310
- if ((config === null || config === void 0 ? void 0 : config.sessionData) == "NUKE")
311
- return '';
312
- //check if [session].json exists in __dirname
313
- const sessionjsonpath = yield (0, exports.getSessionDataFilePath)(sessionId, config);
314
- let sessionjson = '';
315
- const sd = process.env[`${sessionId.toUpperCase()}_DATA_JSON`] ? JSON.parse(process.env[`${sessionId.toUpperCase()}_DATA_JSON`]) : config === null || config === void 0 ? void 0 : config.sessionData;
316
- sessionjson = (typeof sd === 'string' && sd !== "") ? JSON.parse(Buffer.from(sd, 'base64').toString('ascii')) : sd;
317
- if (sessionjsonpath && typeof sessionjsonpath == 'string' && (yield (0, tools_1.pathExists)(sessionjsonpath))) {
318
- spinner.succeed(`Found session data file: ${sessionjsonpath}`);
319
- const s = yield fs.readFile(sessionjsonpath, "utf8");
320
- try {
321
- sessionjson = JSON.parse(s);
322
- }
323
- catch (error) {
324
- try {
325
- sessionjson = JSON.parse(Buffer.from(s, 'base64').toString('ascii'));
326
- }
327
- catch (error) {
328
- const msg = `${s == "LOGGED OUT" ? "The session was logged out" : "Session data json file is corrupted"}. Please re-scan the QR code.`;
329
- if (spinner) {
330
- spinner.fail(msg);
331
- }
332
- else
333
- console.error(msg);
334
- return false;
335
- }
336
- }
337
- }
338
- else {
339
- spinner.succeed(`No session data file found for session : ${sessionId}`);
340
- }
341
- return sessionjson;
342
- });
343
- const deleteSessionData = (config) => __awaiter(void 0, void 0, void 0, function* () {
344
- const sessionjsonpath = yield (0, exports.getSessionDataFilePath)((config === null || config === void 0 ? void 0 : config.sessionId) || 'session', config);
345
- if (typeof sessionjsonpath == 'string' && (yield (0, tools_1.pathExists)(sessionjsonpath))) {
346
- const l = `logout detected, deleting session data file: ${sessionjsonpath}`;
347
- console.log(l);
348
- logging_1.log.info(l);
349
- yield fs.unlink(sessionjsonpath);
350
- }
351
- const mdDir = yield (0, tools_1.pathExists)(config['userDataDir']);
352
- if (config['userDataDir'] && mdDir) {
353
- logging_1.log.info(`Deleting MD session directory: ${mdDir}`);
354
- yield fs.rm(mdDir, { force: true, recursive: true });
355
- logging_1.log.info(`MD directory ${mdDir} deleted: ${!(yield (0, tools_1.pathExists)(mdDir, true))}`);
356
- }
357
- return true;
358
- });
359
- exports.deleteSessionData = deleteSessionData;
360
- const invalidateSesssionData = (config) => __awaiter(void 0, void 0, void 0, function* () {
361
- const sessionjsonpath = yield (0, exports.getSessionDataFilePath)((config === null || config === void 0 ? void 0 : config.sessionId) || 'session', config);
362
- if (typeof sessionjsonpath == 'string' && (yield (0, tools_1.pathExists)(sessionjsonpath))) {
363
- const l = `logout detected, invalidating session data file: ${sessionjsonpath}`;
364
- console.log(l);
365
- logging_1.log.info(l);
366
- fs.writeFile(sessionjsonpath, "LOGGED OUT");
367
- }
368
- return true;
369
- });
370
- exports.invalidateSesssionData = invalidateSesssionData;
371
- const getSessionDataFilePath = (sessionId, config) => __awaiter(void 0, void 0, void 0, function* () {
372
- var _a, _b;
373
- const p = ((_a = require === null || require === void 0 ? void 0 : require.main) === null || _a === void 0 ? void 0 : _a.path) || ((_b = process === null || process === void 0 ? void 0 : process.mainModule) === null || _b === void 0 ? void 0 : _b.path);
374
- const sessionjsonpath = ((config === null || config === void 0 ? void 0 : config.sessionDataPath) && (config === null || config === void 0 ? void 0 : config.sessionDataPath.includes('.data.json'))) ? path.join(path.resolve(process.cwd(), (config === null || config === void 0 ? void 0 : config.sessionDataPath) || '')) : path.join(path.resolve(process.cwd(), (config === null || config === void 0 ? void 0 : config.sessionDataPath) || ''), `${sessionId || 'session'}.data.json`);
375
- const altSessionJsonPath = p ? ((config === null || config === void 0 ? void 0 : config.sessionDataPath) && (config === null || config === void 0 ? void 0 : config.sessionDataPath.includes('.data.json'))) ? path.join(path.resolve(p, (config === null || config === void 0 ? void 0 : config.sessionDataPath) || '')) : path.join(path.resolve(p, (config === null || config === void 0 ? void 0 : config.sessionDataPath) || ''), `${sessionId || 'session'}.data.json`) : false;
376
- if ((0, tools_1.pathExists)(sessionjsonpath)) {
377
- return sessionjsonpath;
378
- }
379
- else if (p && altSessionJsonPath && (yield (0, tools_1.pathExists)(altSessionJsonPath))) {
380
- return altSessionJsonPath;
381
- }
382
- return false;
383
- });
384
- exports.getSessionDataFilePath = getSessionDataFilePath;
385
- const addScript = (page, js, asScriptTag) => __awaiter(void 0, void 0, void 0, function* () {
386
- const content = yield script_preloader_1.scriptLoader.getScript(js);
387
- const injectResult = yield (asScriptTag ? page.addScriptTag({ content, type: 'text/javascript' }) : page.evaluate(content).catch(e => logging_1.log.error(`Injection error: ${js}`, e)));
388
- logging_1.log.info(`Injection Result of ${js}: ${injectResult}`);
389
- return injectResult;
390
- });
391
- exports.addScript = addScript;
392
- // (page: Page, js : string) : Promise<unknown> => page.addScriptTag({
393
- // path: require.resolve(path.join(__dirname, '../lib', js))
394
- // })
395
- function injectPreApiScripts(page, spinner) {
396
- return __awaiter(this, void 0, void 0, function* () {
397
- if (yield page.evaluate("!['jsSHA','axios', 'QRCode', 'Base64', 'objectHash'].find(x=>!window[x])"))
398
- return;
399
- const t1 = yield (0, tools_1.timePromise)(() => Promise.all([
400
- // 'jsSha.min.js', //only needed in getFileHash which is not used anymore
401
- 'qr.min.js',
402
- // 'base64.js', //only needed in base64ImageToFile and atob is a fallback
403
- 'hash.js'
404
- ].map(js => (0, exports.addScript)(page, js))));
405
- spinner === null || spinner === void 0 ? void 0 : spinner.info(`Base inject: ${t1}ms`);
406
- return page;
407
- });
408
- }
409
- exports.injectPreApiScripts = injectPreApiScripts;
410
- function injectWapi(page, spinner, force = false) {
411
- return __awaiter(this, void 0, void 0, function* () {
412
- console.log(`Waiting for require...`);
413
- const tR = yield (0, tools_1.timePromise)(() => page.waitForFunction('window.require || false', { timeout: 5000, polling: 50 }).catch(() => { console.log("No require found in frame"); }));
414
- console.log(`Found require: ${tR}ms`);
415
- const bruteInjectionAttempts = 1;
416
- yield (0, patch_manager_1.earlyInjectionCheck)(page);
417
- const check = `window.WAPI && window.Store ? true : false`;
418
- const initCheck = yield page.evaluate(check);
419
- if (initCheck)
420
- return;
421
- logging_1.log.info(`WAPI CHECK: ${initCheck}`);
422
- if (!initCheck)
423
- force = true;
424
- if (wapiInjected && !force)
425
- return page;
426
- const multiScriptInjectPromiseArr = Array(bruteInjectionAttempts).fill("wapi.js").map((_s) => (0, exports.addScript)(page, _s));
427
- try {
428
- const wapi = yield (0, tools_1.timePromise)(() => Promise.all(multiScriptInjectPromiseArr));
429
- spinner === null || spinner === void 0 ? void 0 : spinner.info(`WAPI inject: ${wapi}ms`);
430
- }
431
- catch (error) {
432
- logging_1.log.error("injectWapi ~ error", error.message);
433
- //one of the injection attempts failed.
434
- return yield injectWapi(page, spinner, force);
435
- }
436
- spinner === null || spinner === void 0 ? void 0 : spinner.info("Checking session integrity");
437
- wapiAttempts++;
438
- wapiInjected = !!(yield page.waitForFunction(check, { timeout: 3000, polling: 50 }).catch(e => false));
439
- if (!wapiInjected) {
440
- spinner === null || spinner === void 0 ? void 0 : spinner.info(`Session integrity check failed, trying again... ${wapiAttempts}`);
441
- return yield injectWapi(page, spinner, true);
442
- }
443
- spinner === null || spinner === void 0 ? void 0 : spinner.info("Session integrity check passed");
444
- return page;
445
- });
446
- }
447
- exports.injectWapi = injectWapi;
448
- function injectApi(page, spinner, force = false) {
449
- return __awaiter(this, void 0, void 0, function* () {
450
- spinner === null || spinner === void 0 ? void 0 : spinner.info("Injecting scripts");
451
- yield injectPreApiScripts(page, spinner);
452
- yield injectWapi(page, spinner, force);
453
- const launch = yield (0, tools_1.timePromise)(() => (0, exports.addScript)(page, 'launch.js'));
454
- spinner === null || spinner === void 0 ? void 0 : spinner.succeed(`Launch inject: ${launch}ms`);
455
- return page;
456
- });
457
- }
458
- exports.injectApi = injectApi;
459
- function initBrowser(sessionId, config = {}, spinner) {
460
- var _a, _b, _c;
461
- return __awaiter(this, void 0, void 0, function* () {
462
- if (config === null || config === void 0 ? void 0 : config.raspi) {
463
- config.executablePath = "/usr/bin/chromium-browser";
464
- }
465
- if ((config === null || config === void 0 ? void 0 : config.useChrome) && !(config === null || config === void 0 ? void 0 : config.executablePath)) {
466
- const { default: storage } = yield Promise.resolve().then(() => __importStar(require('node-persist')));
467
- yield storage.init();
468
- const _savedPath = yield storage.getItem('executablePath');
469
- if (!_savedPath) {
470
- const chromeLauncher = yield Promise.resolve().then(() => __importStar(require('chrome-launcher')));
471
- config.executablePath = chromeLauncher.Launcher.getInstallations()[0];
472
- if (!config.executablePath)
473
- delete config.executablePath;
474
- yield storage.setItem('executablePath', config.executablePath);
475
- }
476
- else
477
- config.executablePath = _savedPath;
478
- }
479
- if (config === null || config === void 0 ? void 0 : config.browserRevision) {
480
- const browserFetcher = puppeteer.createBrowserFetcher();
481
- const browserDownloadSpinner = new events_1.Spin(sessionId + '_browser', 'Browser', false, false);
482
- try {
483
- browserDownloadSpinner.start('Downloading browser revision: ' + config.browserRevision);
484
- const revisionInfo = yield browserFetcher.download(config.browserRevision, function (downloadedBytes, totalBytes) {
485
- browserDownloadSpinner.info(`Downloading Browser: ${Math.round(downloadedBytes / 1000000)}/${Math.round(totalBytes / 1000000)}`);
486
- });
487
- if (revisionInfo.executablePath) {
488
- config.executablePath = revisionInfo.executablePath;
489
- // config.pipe = true;
490
- }
491
- browserDownloadSpinner.succeed('Browser downloaded successfully');
492
- }
493
- catch (error) {
494
- browserDownloadSpinner.succeed('Something went wrong while downloading the browser');
495
- }
496
- }
497
- /**
498
- * Explicit fallback due to pptr 19
499
- */
500
- if (!config.executablePath)
501
- config.executablePath = (0, puppeteer_1.executablePath)();
502
- if (((_a = config === null || config === void 0 ? void 0 : config.proxyServerCredentials) === null || _a === void 0 ? void 0 : _a.address) && (config === null || config === void 0 ? void 0 : config.useNativeProxy))
503
- puppeteer_config_1.puppeteerConfig.chromiumArgs.push(`--proxy-server=${config.proxyServerCredentials.address}`);
504
- if (config === null || config === void 0 ? void 0 : config.browserWsEndpoint)
505
- config.browserWSEndpoint = config.browserWsEndpoint;
506
- let args = [...puppeteer_config_1.puppeteerConfig.chromiumArgs, ...((config === null || config === void 0 ? void 0 : config.chromiumArgs) || [])];
507
- if (config === null || config === void 0 ? void 0 : config.multiDevice) {
508
- args = args.filter(x => x != '--incognito');
509
- config["userDataDir"] = config["userDataDir"] || `${(config === null || config === void 0 ? void 0 : config.sessionDataPath) || ((config === null || config === void 0 ? void 0 : config.inDocker) ? '/sessions' : (config === null || config === void 0 ? void 0 : config.sessionDataPath) || '.')}/_IGNORE_${(config === null || config === void 0 ? void 0 : config.sessionId) || 'session'}`;
510
- spinner === null || spinner === void 0 ? void 0 : spinner.info('MD Enabled, turning off incognito mode.');
511
- spinner === null || spinner === void 0 ? void 0 : spinner.info(`Data dir: ${config["userDataDir"]}`);
512
- }
513
- if (config === null || config === void 0 ? void 0 : config.corsFix)
514
- args.push('--disable-web-security');
515
- if (config["userDataDir"] && !(yield (0, tools_1.pathExists)(config["userDataDir"]))) {
516
- spinner === null || spinner === void 0 ? void 0 : spinner.info(`Data dir doesnt exist, creating...: ${config["userDataDir"]}`);
517
- fs.mkdir(config["userDataDir"], { recursive: true });
518
- }
519
- const browser = (config === null || config === void 0 ? void 0 : config.browserWSEndpoint) ? yield puppeteer.connect(Object.assign({}, config)) : yield puppeteer.launch(Object.assign(Object.assign({ headless: "new", args }, config), { devtools: false })).catch(e => {
520
- spinner === null || spinner === void 0 ? void 0 : spinner.fail('Error launching browser');
521
- console.error(e);
522
- if (e.message.includes("ENOENT")) {
523
- config.executablePath = (0, puppeteer_1.executablePath)();
524
- console.log("Falling back to chromium:", config.executablePath);
525
- return puppeteer.launch(Object.assign(Object.assign({ headless: "new", args }, config), { devtools: false }));
526
- }
527
- spinner === null || spinner === void 0 ? void 0 : spinner.fail(e.message);
528
- throw e;
529
- });
530
- exports.BROWSER_START_TS = Date.now();
531
- //devtools
532
- if (config === null || config === void 0 ? void 0 : config.devtools) {
533
- const _dt = yield Promise.resolve().then(() => __importStar(require('puppeteer-extra-plugin-devtools')));
534
- const devtools = _dt.default();
535
- if (config.devtools !== 'local' && !((_b = config === null || config === void 0 ? void 0 : config.devtools) === null || _b === void 0 ? void 0 : _b.user) && !((_c = config === null || config === void 0 ? void 0 : config.devtools) === null || _c === void 0 ? void 0 : _c.pass)) {
536
- config.devtools = {};
537
- config.devtools.user = 'dev';
538
- const uuid = (yield Promise.resolve().then(() => __importStar(require('uuid-apikey')))).default;
539
- config.devtools.pass = uuid.create().apiKey;
540
- }
541
- if (config.devtools.user && config.devtools.pass) {
542
- devtools.setAuthCredentials(config.devtools.user, config.devtools.pass);
543
- }
544
- puppeteer.use(devtools);
545
- try {
546
- // const tunnel = await devtools.createTunnel(browser);
547
- const tunnel = config.devtools == 'local' ? devtools.getLocalDevToolsUrl(browser) : (yield devtools.createTunnel(browser)).url;
548
- const l = `\ndevtools URL: ${typeof config.devtools == 'object' ? JSON.stringify(Object.assign(Object.assign({}, config.devtools), { tunnel }), null, 2) : tunnel}`;
549
- spinner.info(l);
550
- }
551
- catch (error) {
552
- spinner.fail(error);
553
- logging_1.log.error("initBrowser -> error", error);
554
- }
555
- }
556
- return browser;
557
- });
558
- }
559
- function getWAPage(browser) {
560
- return __awaiter(this, void 0, void 0, function* () {
561
- const pages = yield browser.pages();
562
- console.assert(pages.length > 0);
563
- return pages[0];
564
- });
565
- }
566
- (0, death_1.default)(() => __awaiter(void 0, void 0, void 0, function* () {
567
- //clean up code here
568
- if (browser)
569
- yield (0, exports.kill)(browser);
570
- }));
571
- /**
572
- * @internal
573
- */
574
- const kill = (p, b, exit, pid, reason = "LAUNCH_KILL") => __awaiter(void 0, void 0, void 0, function* () {
575
- (0, tools_1.processSendData)({
576
- reason
577
- });
578
- (0, tools_1.timeout)(3000);
579
- const killBrowser = (browser) => __awaiter(void 0, void 0, void 0, function* () {
580
- if (!browser)
581
- return;
582
- pid = (browser === null || browser === void 0 ? void 0 : browser.process()) ? browser === null || browser === void 0 ? void 0 : browser.process().pid : null;
583
- if (!pid)
584
- return;
585
- if (!(p === null || p === void 0 ? void 0 : p.isClosed()))
586
- yield (p === null || p === void 0 ? void 0 : p.close());
587
- if (browser)
588
- yield (browser === null || browser === void 0 ? void 0 : browser.close().catch(() => { }));
589
- });
590
- if (p) {
591
- const browser = (p === null || p === void 0 ? void 0 : p.browser) && typeof (p === null || p === void 0 ? void 0 : p.browser) === 'function' && (p === null || p === void 0 ? void 0 : p.browser());
592
- yield killBrowser(browser);
593
- }
594
- else if (b) {
595
- yield killBrowser(b);
596
- }
597
- if (pid)
598
- yield (0, promise_1.default)(pid, 'SIGKILL').catch(e => console.error('Error while terminating browser PID. You can just ignore this, as the process has most likely been terminated successfully already:', e.message));
599
- if (exit)
600
- process.exit();
601
- return;
602
- });
603
- exports.kill = kill;