@open-wa/wa-automate 4.28.6 → 4.28.10

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.
@@ -794,6 +794,10 @@ export declare class Client {
794
794
  */
795
795
  getAllContacts(): Promise<Contact[]>;
796
796
  getWAVersion(): Promise<string>;
797
+ /**
798
+ * Generate a pre-filled github issue link to easily report a bug
799
+ */
800
+ getIssueLink(): Promise<string>;
797
801
  /**
798
802
  * Retrieves if the phone is online. Please note that this may not be real time.
799
803
  * @returns Boolean
@@ -427,9 +427,9 @@ class Client {
427
427
  return rest;
428
428
  }
429
429
  pup(pageFunction, ...args) {
430
- var _a, _b;
430
+ var _a, _b, _c, _d, _e;
431
431
  return __awaiter(this, void 0, void 0, function* () {
432
- const { safeMode, callTimeout, idChecking, logFile, logging } = this._createConfig;
432
+ const { safeMode, callTimeout, idCorrection, logging } = this._createConfig;
433
433
  let _t;
434
434
  if (safeMode) {
435
435
  if (!this._page || this._page.isClosed())
@@ -438,19 +438,34 @@ class Client {
438
438
  if (state !== model_1.STATE.CONNECTED)
439
439
  throw new errors_1.CustomError(errors_1.ERROR_NAME.STATE_ERROR, `state: ${state}`);
440
440
  }
441
- if (idChecking && args[0]) {
442
- Object.entries(args[0]).map(([k, v]) => {
443
- if (["to", "chatId", "groupChatId", "groupId", "contactId"].includes(k) && typeof v == "string" && v) {
444
- args[0][k] = (v === null || v === void 0 ? void 0 : v.includes('-')) ?
445
- //it is a group chat, make sure it has a @g.us at the end
446
- `${v === null || v === void 0 ? void 0 : v.replace(/@(c|g).us/g, '')}@g.us` :
447
- //it is a normal chat, make sure it has a @c.us at the end
448
- `${v === null || v === void 0 ? void 0 : v.replace(/@(c|g).us/g, '')}@c.us`;
449
- }
450
- });
441
+ if (idCorrection && args[0]) {
442
+ const fixId = (id) => {
443
+ var _a;
444
+ let isGroup = false;
445
+ let scrubbedId = (_a = id === null || id === void 0 ? void 0 : id.match(/\d|-/g)) === null || _a === void 0 ? void 0 : _a.join('');
446
+ scrubbedId = scrubbedId.match(/-/g) && scrubbedId.match(/-/g).length == 1 && scrubbedId.split('-')[1].length === 10 ? scrubbedId : scrubbedId.replace(/-/g, '');
447
+ if (scrubbedId.includes('-') || scrubbedId.length === 18)
448
+ isGroup = true;
449
+ const fixed = isGroup ?
450
+ `${scrubbedId === null || scrubbedId === void 0 ? void 0 : scrubbedId.replace(/@(c|g).us/g, '')}@g.us` :
451
+ `${scrubbedId === null || scrubbedId === void 0 ? void 0 : scrubbedId.replace(/@(c|g).us/g, '')}@c.us`;
452
+ logging_1.log.info('Fixed ID', { id, fixed });
453
+ return fixed;
454
+ };
455
+ if (typeof args[0] === 'string' && args[0] && !(args[0].includes("@g.us") || args[0].includes("@c.us")) && ((_c = (_b = (((_a = pageFunction === null || pageFunction === void 0 ? void 0 : pageFunction.toString()) === null || _a === void 0 ? void 0 : _a.match(/[^(]*\(([^)]*)\)/)[1]) || "")) === null || _b === void 0 ? void 0 : _b.replace(/\s/g, '')) === null || _c === void 0 ? void 0 : _c.split(','))) {
456
+ const p = ((pageFunction === null || pageFunction === void 0 ? void 0 : pageFunction.toString().match(/[^(]*\(([^)]*)\)/)[1]) || "").replace(/\s/g, '').split(',');
457
+ if (["to", "chatId", "groupChatId", "groupId", "contactId"].includes(p[0]))
458
+ args[0] = fixId(args[0]);
459
+ }
460
+ else if (typeof args[0] === 'object')
461
+ Object.entries(args[0]).map(([k, v]) => {
462
+ if (["to", "chatId", "groupChatId", "groupId", "contactId"].includes(k) && typeof v == "string" && v && !(v.includes("@g.us") || v.includes("@c.us"))) {
463
+ args[0][k] = fixId(v);
464
+ }
465
+ });
451
466
  }
452
467
  if (logging) {
453
- const wapis = (_b = (((_a = pageFunction === null || pageFunction === void 0 ? void 0 : pageFunction.toString()) === null || _a === void 0 ? void 0 : _a.match(/WAPI\.(\w*)\(/g)) || [])) === null || _b === void 0 ? void 0 : _b.map(s => s.replace(/WAPI|\.|\(/g, ''));
468
+ const wapis = (_e = (((_d = pageFunction === null || pageFunction === void 0 ? void 0 : pageFunction.toString()) === null || _d === void 0 ? void 0 : _d.match(/WAPI\.(\w*)\(/g)) || [])) === null || _e === void 0 ? void 0 : _e.map(s => s.replace(/WAPI|\.|\(/g, ''));
454
469
  _t = Date.now();
455
470
  logging_1.log.info(`Request ${_t}`, Object.assign({ _method: (wapis === null || wapis === void 0 ? void 0 : wapis.length) === 1 ? wapis[0] : wapis }, args[0]));
456
471
  }
@@ -1801,6 +1816,14 @@ class Client {
1801
1816
  return yield this.pup(() => WAPI.getWAVersion());
1802
1817
  });
1803
1818
  }
1819
+ /**
1820
+ * Generate a pre-filled github issue link to easily report a bug
1821
+ */
1822
+ getIssueLink() {
1823
+ return __awaiter(this, void 0, void 0, function* () {
1824
+ return (0, tools_1.generateGHIssueLink)(this.getConfig(), this.getSessionInfo());
1825
+ });
1826
+ }
1804
1827
  /**
1805
1828
  * Retrieves if the phone is online. Please note that this may not be real time.
1806
1829
  * @returns Boolean
@@ -12,6 +12,9 @@ export interface SessionInfo {
12
12
  NUM_HASH?: string;
13
13
  OW_KEY?: string;
14
14
  INSTANCE_ID?: string;
15
+ LATEST_VERSION?: boolean;
16
+ CLI?: boolean;
17
+ ACC_TYPE?: 'PERSONAL' | 'BUSINESS';
15
18
  }
16
19
  export interface HealthCheck {
17
20
  /**
package/dist/cli/index.js CHANGED
@@ -39,6 +39,7 @@ const ready = (config) => __awaiter(void 0, void 0, void 0, function* () {
39
39
  function start() {
40
40
  return __awaiter(this, void 0, void 0, function* () {
41
41
  const { cliConfig, createConfig, PORT, spinner } = (0, setup_1.cli)();
42
+ process.env.OWA_CLI = "true";
42
43
  spinner.start("Launching EASY API");
43
44
  (0, server_1.setUpExpressApp)();
44
45
  if (cliConfig.cors)
@@ -115,6 +115,8 @@ function smartQr(waPage, config, spinner) {
115
115
  return true;
116
116
  let hash = 'START';
117
117
  const grabAndEmit = (qrData) => __awaiter(this, void 0, void 0, function* () {
118
+ if (!qrNum && browser_1.BROWSER_START_TS)
119
+ spinner.info(`First QR: ${Date.now() - browser_1.BROWSER_START_TS} ms`);
118
120
  if (qrData) {
119
121
  if (!config.qrLogSkip)
120
122
  qrcode.generate(qrData, { small: true });
@@ -1,6 +1,7 @@
1
1
  import { Browser, Page } from 'puppeteer';
2
2
  import { Spin } from './events';
3
3
  import { ConfigObject } from '../api/model';
4
+ export declare let BROWSER_START_TS: number;
4
5
  export declare function initPage(sessionId?: string, config?: ConfigObject, customUserAgent?: string, spinner?: Spin, _page?: Page, skipAuth?: boolean): Promise<Page>;
5
6
  export declare const deleteSessionData: (config: ConfigObject) => boolean;
6
7
  export declare const getSessionDataFilePath: (sessionId: string, config: ConfigObject) => string | boolean;
@@ -31,7 +31,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
31
31
  return (mod && mod.__esModule) ? mod : { "default": mod };
32
32
  };
33
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
- exports.kill = exports.injectApi = exports.addScript = exports.getSessionDataFilePath = exports.deleteSessionData = exports.initPage = void 0;
34
+ exports.kill = exports.injectApi = exports.addScript = exports.getSessionDataFilePath = exports.deleteSessionData = exports.initPage = exports.BROWSER_START_TS = void 0;
35
35
  const path = __importStar(require("path"));
36
36
  const fs = __importStar(require("fs"));
37
37
  const death_1 = __importDefault(require("death"));
@@ -45,6 +45,7 @@ const tree_kill_1 = __importDefault(require("tree-kill"));
45
45
  const logging_1 = require("../logging/logging");
46
46
  const tools_1 = require("../utils/tools");
47
47
  let browser;
48
+ exports.BROWSER_START_TS = 0;
48
49
  function initPage(sessionId, config, customUserAgent, spinner, _page, skipAuth) {
49
50
  var _a, _b, _c, _d, _e;
50
51
  return __awaiter(this, void 0, void 0, function* () {
@@ -58,7 +59,7 @@ function initPage(sessionId, config, customUserAgent, spinner, _page, skipAuth)
58
59
  let waPage = _page;
59
60
  if (!waPage) {
60
61
  spinner === null || spinner === void 0 ? void 0 : spinner.info('Launching Browser');
61
- browser = yield initBrowser(sessionId, config);
62
+ browser = yield initBrowser(sessionId, config, spinner);
62
63
  waPage = yield getWAPage(browser);
63
64
  }
64
65
  spinner === null || spinner === void 0 ? void 0 : spinner.info('Setting Up Page');
@@ -281,7 +282,7 @@ function injectApi(page) {
281
282
  });
282
283
  }
283
284
  exports.injectApi = injectApi;
284
- function initBrowser(sessionId, config = {}) {
285
+ function initBrowser(sessionId, config = {}, spinner) {
285
286
  var _a, _b, _c;
286
287
  return __awaiter(this, void 0, void 0, function* () {
287
288
  if (config === null || config === void 0 ? void 0 : config.raspi) {
@@ -327,13 +328,17 @@ function initBrowser(sessionId, config = {}) {
327
328
  if (config === null || config === void 0 ? void 0 : config.multiDevice) {
328
329
  args = args.filter(x => x != '--incognito');
329
330
  config["userDataDir"] = config["userDataDir"] || `${(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'}`;
331
+ spinner === null || spinner === void 0 ? void 0 : spinner.info('MD Enabled, turning off incognito mode.');
332
+ spinner === null || spinner === void 0 ? void 0 : spinner.info(`Data dir: ${config["userDataDir"]}`);
330
333
  }
331
334
  if (config === null || config === void 0 ? void 0 : config.corsFix)
332
335
  args.push('--disable-web-security');
333
336
  if (config["userDataDir"] && !fs.existsSync(config["userDataDir"])) {
337
+ spinner === null || spinner === void 0 ? void 0 : spinner.info(`Data dir doesnt exist, creating...: ${config["userDataDir"]}`);
334
338
  fs.mkdirSync(config["userDataDir"], { recursive: true });
335
339
  }
336
340
  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: true, args }, config), { devtools: false }));
341
+ exports.BROWSER_START_TS = Date.now();
337
342
  //devtools
338
343
  if (config === null || config === void 0 ? void 0 : config.devtools) {
339
344
  const _dt = yield Promise.resolve().then(() => __importStar(require('puppeteer-extra-plugin-devtools')));
@@ -351,12 +356,11 @@ function initBrowser(sessionId, config = {}) {
351
356
  try {
352
357
  // const tunnel = await devtools.createTunnel(browser);
353
358
  const tunnel = config.devtools == 'local' ? devtools.getLocalDevToolsUrl(browser) : (yield devtools.createTunnel(browser)).url;
354
- const l = `\ndevtools URL: ${typeof config.devtools == 'object' ? Object.assign(Object.assign({}, config.devtools), { tunnel }) : tunnel}`;
355
- console.log(l);
356
- logging_1.log.info(l);
359
+ const l = `\ndevtools URL: ${typeof config.devtools == 'object' ? JSON.stringify(Object.assign(Object.assign({}, config.devtools), { tunnel }), null, 2) : tunnel}`;
360
+ spinner.info(l);
357
361
  }
358
362
  catch (error) {
359
- console.error("initBrowser -> error", error);
363
+ spinner.fail(error);
360
364
  logging_1.log.error("initBrowser -> error", error);
361
365
  }
362
366
  }
@@ -27,17 +27,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
27
27
  step((generator = generator.apply(thisArg, _arguments || [])).next());
28
28
  });
29
29
  };
30
- var __rest = (this && this.__rest) || function (s, e) {
31
- var t = {};
32
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
33
- t[p] = s[p];
34
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
35
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
36
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
37
- t[p[i]] = s[p[i]];
38
- }
39
- return t;
40
- };
41
30
  var __importDefault = (this && this.__importDefault) || function (mod) {
42
31
  return (mod && mod.__esModule) ? mod : { "default": mod };
43
32
  };
@@ -171,7 +160,7 @@ function create(config = {}) {
171
160
  config.multiDevice = true;
172
161
  }
173
162
  if ((config === null || config === void 0 ? void 0 : config.multiDevice) && (config === null || config === void 0 ? void 0 : config.chromiumArgs))
174
- spinner.info(`Using custom chromium args with multi device will cause issues! Please remove themm`);
163
+ spinner.info(`Using custom chromium args with multi device will cause issues! Please remove them: ${config === null || config === void 0 ? void 0 : config.chromiumArgs}`);
175
164
  if ((config === null || config === void 0 ? void 0 : config.multiDevice) && !(config === null || config === void 0 ? void 0 : config.useChrome))
176
165
  spinner.info(`It is recommended to set useChrome: true or use the --use-chrome flag if you are experiencing issues with Multi device support`);
177
166
  waPage = yield (0, browser_1.initPage)(sessionId, config, customUserAgent, spinner);
@@ -218,11 +207,10 @@ function create(config = {}) {
218
207
  console.table(debugInfo);
219
208
  logging_1.log.info('Debug info:', debugInfo);
220
209
  }
210
+ debugInfo.LATEST_VERSION = !((notifier === null || notifier === void 0 ? void 0 : notifier.update) && ((notifier === null || notifier === void 0 ? void 0 : notifier.update.latest) !== exports.pkg.version));
211
+ debugInfo.CLI = process.env.OWA_CLI && true || false;
221
212
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
222
- spinner.succeed('Use this easy pre-filled link to report an issue: ' + `https://github.com/open-wa/wa-automate-nodejs/issues/new?template=bug_report.yaml&debug_info=${encodeURI(JSON.stringify(((_a) => {
223
- var { OS, PAGE_UA } = _a, o = __rest(_a, ["OS", "PAGE_UA"]);
224
- return o;
225
- })(debugInfo), null, 2))}&environment=${`-%20OS:%20${encodeURI(debugInfo.OS)}%0A-%20Node:%20${encodeURI(process.versions.node)}%0A-%20npm:%20%0A`}`);
213
+ spinner.succeed('Use this easy pre-filled link to report an issue: ' + (0, tools_1.generateGHIssueLink)(config, debugInfo));
226
214
  if (canInjectEarly) {
227
215
  if (attemptingReauth)
228
216
  yield waPage.evaluate(`window.Store = {"Msg": true}`);
@@ -1,5 +1,6 @@
1
- import { DataURL } from '../api/model';
1
+ import { ConfigObject, DataURL } from '../api/model';
2
2
  import { AxiosRequestConfig } from 'axios';
3
+ import { SessionInfo } from '../api/model/sessionInfo';
3
4
  export declare const timeout: (ms: any) => Promise<unknown>;
4
5
  /**
5
6
  * Use this to generate a more likely valid user agent. It makes sure it has the WA part and replaces any windows or linux os info with mac.
@@ -27,3 +28,4 @@ export declare const getDUrl: (url: string, optionsOverride?: AxiosRequestConfig
27
28
  export declare const base64MimeType: (dUrl: DataURL) => string;
28
29
  export declare const processSend: (message: string) => void;
29
30
  export declare const processSendData: (data?: any) => void;
31
+ export declare const generateGHIssueLink: (config: ConfigObject, sessionInfo: SessionInfo, extras?: any) => string;
@@ -23,8 +23,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
23
23
  return (mod && mod.__esModule) ? mod : { "default": mod };
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.processSendData = exports.processSend = exports.base64MimeType = exports.getDUrl = exports.isDataURL = exports.isBase64 = exports.camelize = exports.without = exports.getConfigFromProcessEnv = exports.smartUserAgent = exports.timeout = void 0;
26
+ exports.generateGHIssueLink = exports.processSendData = exports.processSend = exports.base64MimeType = exports.getDUrl = exports.isDataURL = exports.isBase64 = exports.camelize = exports.without = exports.getConfigFromProcessEnv = exports.smartUserAgent = exports.timeout = void 0;
27
27
  const axios_1 = __importDefault(require("axios"));
28
+ const node_child_process_1 = require("node:child_process");
28
29
  //@ts-ignore
29
30
  process.send = process.send || function () { };
30
31
  const timeout = ms => new Promise(resolve => setTimeout(resolve, ms, 'timeout'));
@@ -145,3 +146,24 @@ const processSendData = (data = {}) => {
145
146
  return;
146
147
  };
147
148
  exports.processSendData = processSendData;
149
+ const generateGHIssueLink = (config, sessionInfo, extras = {}) => {
150
+ const npm_ver = (0, node_child_process_1.execSync)('npm -v');
151
+ const labels = [];
152
+ if (sessionInfo.CLI)
153
+ labels.push('CLI');
154
+ if (!sessionInfo.LATEST_VERSION)
155
+ labels.push('NCV');
156
+ labels.push(config.multiDevice ? 'MD' : 'Legacy');
157
+ if (sessionInfo.ACC_TYPE === 'BUSINESS')
158
+ labels.push('BHA');
159
+ if (sessionInfo.ACC_TYPE === 'PERSONAL')
160
+ labels.push('PHA');
161
+ const qp = Object.assign({ "template": "bug_report.yaml",
162
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
163
+ "d_info": `${encodeURI(JSON.stringify(((_a) => {
164
+ var { OS, PAGE_UA } = _a, o = __rest(_a, ["OS", "PAGE_UA"]);
165
+ return o;
166
+ })(sessionInfo), null, 2))}`, "enviro": `${`-%20OS:%20${encodeURI(sessionInfo.OS)}%0A-%20Node:%20${encodeURI(process.versions.node)}%0A-%20npm:%20${(String(npm_ver)).replace(/\s/g, '')}`}`, "labels": labels.join(',') }, extras);
167
+ return `https://github.com/open-wa/wa-automate-nodejs/issues/new?${Object.keys(qp).map(k => `${k}=${qp[k]}`).join('&')}`;
168
+ };
169
+ exports.generateGHIssueLink = generateGHIssueLink;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-wa/wa-automate",
3
- "version": "4.28.6",
3
+ "version": "4.28.10",
4
4
  "licenseCheckUrl": "https://openwa.dev/license-check",
5
5
  "brokenMethodReportUrl": "https://openwa.dev/report-bm",
6
6
  "patches": "https://cdn.openwa.dev/patches.json",