@open-wa/wa-automate 4.30.13 → 4.31.0

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.
@@ -1 +1 @@
1
- [{"env":"WA_SESSION_DATA","p":"session-data","description":"The base64 encoded sessionData used to restore a session.","type":"string","key":"sessionData"},{"env":"WA_BROWSER_WS_ENDPOINT","p":"browser-ws-endpoint","type":"string","description":"ALPHA EXPERIMENTAL FEATURE! DO NOT USE IN PRODUCTION, REQUIRES TESTING.\n\nLearn more:\n\nhttps://pptr.dev/#?product=Puppeteer&version=v3.1.0&show=api-puppeteerconnectoptions\n\nhttps://medium.com/@jaredpotter1/connecting-puppeteer-to-existing-chrome-window-8a10828149e0","key":"browserWSEndpoint"},{"env":"WA_SESSION_DATA_PATH","p":"session-data-path","type":"string","description":"The path relative to the current working directory (i.e where you run the command to start your process). This will be used to store and read your `.data.json` files. defualt to ''","key":"sessionDataPath"},{"env":"WA_SKIP_UPDATE_CHECK","p":"skip-update-check","type":"boolean","description":"If set to true, `skipUpdateCheck` will bypass the latest version check. This saves some time on boot (around 150 ms).","default":"`false`","key":"skipUpdateCheck"},{"env":"WA_SESSION_ID","p":"session-id","type":"string","description":"This is the name of the session. You have to make sure that this is unique for every session.","default":"`session`","key":"sessionId"},{"env":"WA_LICENSE_KEY","p":"license-key","description":"The license key to use with the session.","type":"string","key":"licenseKey"},{"env":"WA_CUSTOM_USER_AGENT","p":"custom-user-agent","type":"string","description":"You may set a custom user agent. However, due to recent developments, this is not really neccessary any more.","key":"customUserAgent"},{"env":"WA_BLOCK_CRASH_LOGS","p":"block-crash-logs","type":"boolean","description":"Setting this to true will block any network calls to crash log servers. This should keep anything you do under the radar.","default":"`true`","key":"blockCrashLogs"},{"env":"WA_CACHE_ENABLED","p":"cache-enabled","type":"boolean","description":"Setting this to false turn off the cache. This may improve memory usage.","default":"`false`","key":"cacheEnabled"},{"env":"WA_BROWSER_REVISION","p":"browser-revision","type":"string","description":"This is the specific browser revision to be downlaoded and used. You can find browser revision strings here: http://omahaproxy.appspot.com/ Learn more about it here: https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#class-browserfetcher If you're having trouble with sending images, try '737027'. If you go too far back things will start breaking !!!!!! NOTE: THIS WILL OVERRIDE useChrome and executablePath. ONLY USE THIS IF YOU KNOW WHAT YOU ARE DOING.","key":"browserRevision"},{"env":"WA_HEADLESS","p":"headless","type":"boolean","description":"By default, all instances of @open-wa/wa-automate are headless (i.e you don't see a chrome window open), you can set this to false to show the chrome/chromium window.","default":"`true`","key":"headless"},{"env":"WA_QR_TIMEOUT","p":"qr-timeout","type":"number","description":"This determines how long the process should wait for a QR code to be scanned before killing the process entirely. To have the system wait continuously, set this to `0`.","default":60,"key":"qrTimeout"},{"env":"WA_USE_CHROME","p":"use-chrome","type":"boolean","description":"If true, the program will automatically try to detect the instance of chorme on the machine. Please note this DOES NOT override executablePath.","default":"`false`","key":"useChrome"},{"env":"WA_QR_LOG_SKIP","p":"qr-log-skip","type":"boolean","description":"If true, skips logging the QR Code to the console.","default":"`false`","key":"qrLogSkip"},{"env":"WA_DISABLE_SPINS","p":"disable-spins","type":"boolean","description":"Setting this to true will simplify logs for use within docker containers by disabling spins (will still print raw messages).","default":"`false`","key":"disableSpins"},{"env":"WA_LOG_CONSOLE","p":"log-console","type":"boolean","description":"If true, this will log any console messages from the browser.","default":"`false`","key":"logConsole"},{"env":"WA_LOG_CONSOLE_ERRORS","p":"log-console-errors","type":"boolean","description":"If true, this will log any error messages from the browser instance","default":"`false`","key":"logConsoleErrors"},{"env":"WA_AUTH_TIMEOUT","p":"auth-timeout","type":"number","description":"This determines how long the process should wait for the session authentication. If exceeded, checks if phone is out of reach (turned of or without internet connection) and throws an error. It does not relate to the amount of time spent waiting for a qr code scan (see [[qrTimeout]]). To have the system wait continuously, set this to `0`.","default":"`60`","key":"authTimeout"},{"env":"WA_SAFE_MODE","p":"safe-mode","type":"boolean","description":"If true, client will check if the page is valid before each command. If page is not valid, it will throw an error.","default":"`false`","key":"safeMode"},{"env":"WA_SKIP_SESSION_SAVE","p":"skip-session-save","type":"boolean","description":"If true, the process will not save a data.json file. This means that sessions will not be saved and you will need to pass sessionData as a config param or create the session data.json file yourself","default":"`false`","key":"skipSessionSave"},{"env":"WA_POPUP","p":"popup","type":["boolean","number"],"description":"If true, the process will open a browser window where you will see basic event logs and QR codes to authenticate the session. Usually it will open on port 3000. It can also be set to a preferred port.\n\nYou can also get the QR code png at (if localhost and port 3000):\n\n`http://localhost:3000/qr`\n\nor if you have multiple session:\n\n `http://localhost:3000/qr?sessionId=[sessionId]`","default":"`false | 3000`","key":"popup"},{"env":"WA_QR_POP_UP_ONLY","p":"qr-pop-up-only","type":"boolean","description":"This needs to be used in conjuction with `popup`, if `popup` is not true or a number (representing a desired port) then this will not work.\n\nSetting this to true will make sure that only the qr code png is served via the web server. This is useful if you do not need the whole status page.\n\nAs mentioned in [popup](#popup), the url for the qr code is `http://localhost:3000/qr` if the port is 3000.","key":"qrPopUpOnly"},{"env":"WA_BLOCK_ASSETS","p":"block-assets","type":"boolean","description":"Setting this to true will block all assets from loading onto the page. This may result in some load time improvements but also increases instability.","default":"`false`","key":"blockAssets"},{"env":"WA_KEEP_UPDATED","p":"keep-updated","type":"boolean","description":"[ALPHA FEATURE - ONLY IMPLEMENTED FOR TESTING - DO NOT USE IN PRODUCTION YET] Setting this to true will result in the library making sure it is always starting with the latest version of itself. This overrides `skipUpdateCheck`.","default":"`false`","key":"keepUpdated"},{"env":"WA_RESIZABLE","p":"resizable","type":"boolean","description":"Syncs the viewport size with the window size which is how normal browsers act. Only relevant when `headless: false` and this overrides `viewport` config.","default":"`true`","key":"resizable"},{"env":"WA_VIEWPORT","p":"viewport","type":"object","properties":{"width":{"type":"number","description":"Page width in pixels","default":"`1440`"},"height":{"type":"number","description":"Page height in pixels","default":"`900`"}},"additionalProperties":false,"description":"Set the desired viewport height and width. For CLI, use [width]x[height] format. E.g `--viewport 1920x1080`.","key":"viewport"},{"env":"WA_LEGACY","p":"legacy","type":"boolean","description":"As the library is constantly evolving, some parts will be replaced with more efficient and improved code. In some of the infinite edge cases these new changes may not work for you. Set this to true to roll back on 'late beta' features. The reason why legacy is false by default is that in order for features to be tested they have to be released and used by everyone to find the edge cases and fix them.","default":"`false`","key":"legacy"},{"env":"WA_DELETE_SESSION_DATA_ON_LOGOUT","p":"delete-session-data-on-logout","type":"boolean","description":"Deletes the session data file (if found) on logout event. This results in a quicker login when you restart the process.","default":"`false`","key":"deleteSessionDataOnLogout"},{"env":"WA_KILL_PROCESS_ON_TIMEOUT","p":"kill-process-on-timeout","type":"boolean","description":"If set to true, the system will kill the whole node process when either an [[authTimeout]] or a [[qrTimeout]] has been reached. This is useful to prevent hanging processes.","default":"`false`","key":"killProcessOnTimeout"},{"env":"WA_CORS_FIX","p":"cors-fix","type":"boolean","description":"Setting this to true will bypass web security. DO NOT DO THIS IF YOU DO NOT HAVE TO. CORS issue may arise when using a proxy.","default":"`false`","key":"corsFix"},{"env":"WA_CALL_TIMEOUT","p":"call-timeout","type":"number","description":"Amount of time (in ms) to wait for a client method (specifically methods that interact with the WA web session) to resolve. If a client method results takes longer than the timout value then it will result in a [[PageEvaluationTimeout]] error.\n\nIf you get this error, it does not automatically mean that the method failed - it just stops your program from waiting for a client method to resolve.\n\nThis is useful if you do not rely on the results of a client method (e.g the message ID).\n\nIf set to `0`, the process will wait indefinitely for a client method to resolve.","default":0,"key":"callTimeout"},{"env":"WA_SCREENSHOT_ON_INITIALIZATION_BROWSER_ERROR","p":"screenshot-on-initialization-browser-error","type":"boolean","description":"When true, this option will take a screenshot of the browser when an unexpected error occurs within the browser during `create` initialization. The path will be `[working directory]/logs/[session ID]/[start timestamp]/[timestamp].jpg`","default":"`false`","key":"screenshotOnInitializationBrowserError"},{"env":"WA_EVENT_MODE","p":"event-mode","type":"boolean","description":"Setting listeners may not be your cup of tea. With eventMode, all [[SimpleListener]] events will be registered automatically and be filed via the built in Events Listener.\n\nThis is useful because you can register/deregister the event listener as needed whereas the legacy method of setting callbacks are only be set once","default":"`true`;","key":"eventMode"},{"env":"WA_LOG_FILE","p":"log-file","type":"boolean","description":"If true, the system will automatically create a log of all processes relating to actions sent to the web session.\n\nThe location of the file will be relative to the process directory (pd)\n\n`[pd]/[sessionId]/[start timestamp].log`","default":false,"key":"logFile"},{"env":"WA_ID_CORRECTION","p":"id-correction","type":"boolean","description":"When true, the system will attempt to correct chatIds and groupChatIds. This means you can ignore `@c.us` and `@g.us` distinctions in some parameters.","default":false,"key":"idCorrection"},{"env":"WA_STICKER_SERVER_ENDPOINT","p":"sticker-server-endpoint","type":["string","boolean"],"description":"Redundant until self-hostable sticker server is available.","default":"`https://sticker-api.openwa.dev`","key":"stickerServerEndpoint"},{"env":"WA_GH_PATCH","p":"gh-patch","type":"boolean","description":"This will force the library to use the default cached raw github link for patches to shave a few hundred milliseconds from your launch time. If you use this option, you will need to wait about 5 minutes before trying out new patches.","default":"`false`","key":"ghPatch"},{"env":"WA_CACHED_PATCH","p":"cached-patch","type":"boolean","description":"Setting this to `true` will save a local copy of the patches.json file (as patches.ignore.data.json) which will be used in subsequent instantiations of the session. While the rest of the launch procedure is running, the library will fetch and save a recent version of the patches to ensure your patches don't go stale. This will be ignored if the cached patches are more than a day old.","default":"`false`","key":"cachedPatch"},{"env":"WA_LOG_DEBUG_INFO_AS_OBJECT","p":"log-debug-info-as-object","type":"boolean","description":"Setting `this` to true will replace the `console.table` with a stringified logging of the debug info object instead. This would be useful to set for smaller terminal windows. If `disableSpins` is `true` then this will also be `true`.","default":"`false`","key":"logDebugInfoAsObject"},{"env":"WA_KILL_CLIENT_ON_LOGOUT","p":"kill-client-on-logout","type":"boolean","description":"Kill the client when a logout is detected","default":"`false`","key":"killClientOnLogout"},{"env":"WA_THROW_ON_EXPIRED_SESSION_DATA","p":"throw-on-expired-session-data","type":"boolean","description":"This will make the `create` command return `false` if the detected session data is expired.\n\nThis will mean, the process will not attempt to automatically get a new QR code.","default":"`false`","key":"throwOnExpiredSessionData"},{"env":"WA_USE_NATIVE_PROXY","p":"use-native-proxy","type":"boolean","description":"Some sessions may experience issues with sending media when using proxies. Using the native proxy system instead of the recommended 3rd party library may fix these issues.","default":"`false`","key":"useNativeProxy"},{"env":"WA_RASPI","p":"raspi","type":"boolean","description":"Set this to `true` to make the library work on Raspberry Pi OS.\n\nMake sure to run the following command before running the library the first time:\n\n``` > sudo apt update -y && sudo apt install chromium-browser chromium-codecs-ffmpeg -y && sudo apt upgrade ```\n\nIf you're using the CLI, you can set this value to `true` by adding the following flag to the CLI command\n\n``` > npx @open-wa/wa-automate ... --raspi ```","default":"`false`","key":"raspi"},{"env":"WA_MULTI_DEVICE","p":"multi-device","type":"boolean","description":"Please note that multi-device is still in beta so a lot of things may not work. It is HIGHLY suggested to NOT use this in production!!!!\n\nSet this to true if you're using the multidevice beta.","default":"`false`","key":"multiDevice"},{"env":"WA_SESSION_DATA_BUCKET_AUTH","p":"session-data-bucket-auth","type":"string","description":"Base64 encoded S3 Bucket & Authentication object for session data files. The object should be in the same format as cloudUploadOptions.","key":"sessionDataBucketAuth"},{"env":"WA_AUTO_EMOJI","p":"auto-emoji","type":"string","description":"Set the automatic emoji detection character. Set this to false to disable auto emoji. Default is `:`.","default":"`:`","key":"autoEmoji"},{"env":"WA_MAX_CHATS","p":"max-chats","type":"number","description":"Set the maximum amount of chats to be present in a session.","key":"maxChats"},{"env":"WA_MAX_MESSAGES","p":"max-messages","type":"number","description":"Set the maximum amount of messages to be present in a session.","key":"maxMessages"},{"env":"WA_DISCORD","p":"discord","type":"string","description":"Your Discord ID to get onto the sticker leaderboard!","key":"discord"},{"env":"WA_IGNORE_NUKE","p":"ignore-nuke","type":"boolean","description":"Don't implicitly determine if the host logged out.","key":"ignoreNuke"},{"env":"WA_ENSURE_HEADFUL_INTEGRITY","p":"ensure-headful-integrity","type":"boolean","description":"Makes sure the headless session is usable even on first login. Headful sessions are ususally only usable on reauthentication.","key":"ensureHeadfulIntegrity"},{"env":"WA_WAIT_FOR_RIPE_SESSION","p":"wait-for-ripe-session","type":"boolean","description":"wait for a valid headful session. Not required in recent versions.","key":"waitForRipeSession"},{"env":"WA_QR_MAX","p":"qr-max","type":"number","description":"Automatically kill the process after a set amount of qr codes","key":"qrMax"},{"env":"WA_EZQR","p":"ezqr","type":"boolean","description":"Expose a URL where you can easily scan the qr code","key":"ezqr"},{"env":"WA_LOGGING","p":"logging","type":"array","items":{"$ref":"#/definitions/ConfigLogTransport"},"description":"An array of [winston](https://github.com/winstonjs/winston/blob/master/docs/transports.md#additional-transports) logging transport configurations.\n\n[Check this discussion to see how to set up logging](https://github.com/open-wa/wa-automate-nodejs/discussions/2373)","key":"logging"}]
1
+ [{"env":"WA_SESSION_DATA","p":"session-data","description":"The base64 encoded sessionData used to restore a session.","type":"string","key":"sessionData"},{"env":"WA_BROWSER_WS_ENDPOINT","p":"browser-ws-endpoint","type":"string","description":"ALPHA EXPERIMENTAL FEATURE! DO NOT USE IN PRODUCTION, REQUIRES TESTING.\n\nLearn more:\n\nhttps://pptr.dev/#?product=Puppeteer&version=v3.1.0&show=api-puppeteerconnectoptions\n\nhttps://medium.com/@jaredpotter1/connecting-puppeteer-to-existing-chrome-window-8a10828149e0","key":"browserWSEndpoint"},{"env":"WA_SESSION_DATA_PATH","p":"session-data-path","type":"string","description":"The path relative to the current working directory (i.e where you run the command to start your process). This will be used to store and read your `.data.json` files. defualt to ''","key":"sessionDataPath"},{"env":"WA_SKIP_UPDATE_CHECK","p":"skip-update-check","type":"boolean","description":"If set to true, `skipUpdateCheck` will bypass the latest version check. This saves some time on boot (around 150 ms).","default":"`false`","key":"skipUpdateCheck"},{"env":"WA_SESSION_ID","p":"session-id","type":"string","description":"This is the name of the session. You have to make sure that this is unique for every session.","default":"`session`","key":"sessionId"},{"env":"WA_LICENSE_KEY","p":"license-key","description":"The license key to use with the session.","type":"string","key":"licenseKey"},{"env":"WA_CUSTOM_USER_AGENT","p":"custom-user-agent","type":"string","description":"You may set a custom user agent. However, due to recent developments, this is not really neccessary any more.","key":"customUserAgent"},{"env":"WA_BLOCK_CRASH_LOGS","p":"block-crash-logs","type":"boolean","description":"Setting this to true will block any network calls to crash log servers. This should keep anything you do under the radar.","default":"`true`","key":"blockCrashLogs"},{"env":"WA_CACHE_ENABLED","p":"cache-enabled","type":"boolean","description":"Setting this to false turn off the cache. This may improve memory usage.","default":"`false`","key":"cacheEnabled"},{"env":"WA_BROWSER_REVISION","p":"browser-revision","type":"string","description":"This is the specific browser revision to be downlaoded and used. You can find browser revision strings here: http://omahaproxy.appspot.com/ Learn more about it here: https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#class-browserfetcher If you're having trouble with sending images, try '737027'. If you go too far back things will start breaking !!!!!! NOTE: THIS WILL OVERRIDE useChrome and executablePath. ONLY USE THIS IF YOU KNOW WHAT YOU ARE DOING.","key":"browserRevision"},{"env":"WA_HEADLESS","p":"headless","type":"boolean","description":"By default, all instances of @open-wa/wa-automate are headless (i.e you don't see a chrome window open), you can set this to false to show the chrome/chromium window.","default":"`true`","key":"headless"},{"env":"WA_QR_TIMEOUT","p":"qr-timeout","type":"number","description":"This determines how long the process should wait for a QR code to be scanned before killing the process entirely. To have the system wait continuously, set this to `0`.","default":60,"key":"qrTimeout"},{"env":"WA_USE_CHROME","p":"use-chrome","type":"boolean","description":"If true, the program will automatically try to detect the instance of chorme on the machine. Please note this DOES NOT override executablePath.","default":"`false`","key":"useChrome"},{"env":"WA_QR_LOG_SKIP","p":"qr-log-skip","type":"boolean","description":"If true, skips logging the QR Code to the console.","default":"`false`","key":"qrLogSkip"},{"env":"WA_DISABLE_SPINS","p":"disable-spins","type":"boolean","description":"Setting this to true will simplify logs for use within docker containers by disabling spins (will still print raw messages).","default":"`false`","key":"disableSpins"},{"env":"WA_LOG_CONSOLE","p":"log-console","type":"boolean","description":"If true, this will log any console messages from the browser.","default":"`false`","key":"logConsole"},{"env":"WA_LOG_CONSOLE_ERRORS","p":"log-console-errors","type":"boolean","description":"If true, this will log any error messages from the browser instance","default":"`false`","key":"logConsoleErrors"},{"env":"WA_AUTH_TIMEOUT","p":"auth-timeout","type":"number","description":"This determines how long the process should wait for the session authentication. If exceeded, checks if phone is out of reach (turned of or without internet connection) and throws an error. It does not relate to the amount of time spent waiting for a qr code scan (see [[qrTimeout]]). To have the system wait continuously, set this to `0`.","default":"`60`","key":"authTimeout"},{"env":"WA_SAFE_MODE","p":"safe-mode","type":"boolean","description":"If true, client will check if the page is valid before each command. If page is not valid, it will throw an error.","default":"`false`","key":"safeMode"},{"env":"WA_SKIP_SESSION_SAVE","p":"skip-session-save","type":"boolean","description":"If true, the process will not save a data.json file. This means that sessions will not be saved and you will need to pass sessionData as a config param or create the session data.json file yourself","default":"`false`","key":"skipSessionSave"},{"env":"WA_POPUP","p":"popup","type":["boolean","number"],"description":"If true, the process will open a browser window where you will see basic event logs and QR codes to authenticate the session. Usually it will open on port 3000. It can also be set to a preferred port.\n\nYou can also get the QR code png at (if localhost and port 3000):\n\n`http://localhost:3000/qr`\n\nor if you have multiple session:\n\n `http://localhost:3000/qr?sessionId=[sessionId]`","default":"`false | 3000`","key":"popup"},{"env":"WA_QR_POP_UP_ONLY","p":"qr-pop-up-only","type":"boolean","description":"This needs to be used in conjuction with `popup`, if `popup` is not true or a number (representing a desired port) then this will not work.\n\nSetting this to true will make sure that only the qr code png is served via the web server. This is useful if you do not need the whole status page.\n\nAs mentioned in [popup](#popup), the url for the qr code is `http://localhost:3000/qr` if the port is 3000.","key":"qrPopUpOnly"},{"env":"WA_BLOCK_ASSETS","p":"block-assets","type":"boolean","description":"Setting this to true will block all assets from loading onto the page. This may result in some load time improvements but also increases instability.","default":"`false`","key":"blockAssets"},{"env":"WA_KEEP_UPDATED","p":"keep-updated","type":"boolean","description":"[ALPHA FEATURE - ONLY IMPLEMENTED FOR TESTING - DO NOT USE IN PRODUCTION YET] Setting this to true will result in the library making sure it is always starting with the latest version of itself. This overrides `skipUpdateCheck`.","default":"`false`","key":"keepUpdated"},{"env":"WA_RESIZABLE","p":"resizable","type":"boolean","description":"Syncs the viewport size with the window size which is how normal browsers act. Only relevant when `headless: false` and this overrides `viewport` config.","default":"`true`","key":"resizable"},{"env":"WA_VIEWPORT","p":"viewport","type":"object","properties":{"width":{"type":"number","description":"Page width in pixels","default":"`1440`"},"height":{"type":"number","description":"Page height in pixels","default":"`900`"}},"additionalProperties":false,"description":"Set the desired viewport height and width. For CLI, use [width]x[height] format. E.g `--viewport 1920x1080`.","key":"viewport"},{"env":"WA_LEGACY","p":"legacy","type":"boolean","description":"As the library is constantly evolving, some parts will be replaced with more efficient and improved code. In some of the infinite edge cases these new changes may not work for you. Set this to true to roll back on 'late beta' features. The reason why legacy is false by default is that in order for features to be tested they have to be released and used by everyone to find the edge cases and fix them.","default":"`false`","key":"legacy"},{"env":"WA_DELETE_SESSION_DATA_ON_LOGOUT","p":"delete-session-data-on-logout","type":"boolean","description":"Deletes the session data file (if found) on logout event. This results in a quicker login when you restart the process.","default":"`false`","key":"deleteSessionDataOnLogout"},{"env":"WA_KILL_PROCESS_ON_TIMEOUT","p":"kill-process-on-timeout","type":"boolean","description":"If set to true, the system will kill the whole node process when either an [[authTimeout]] or a [[qrTimeout]] has been reached. This is useful to prevent hanging processes.","default":"`false`","key":"killProcessOnTimeout"},{"env":"WA_CORS_FIX","p":"cors-fix","type":"boolean","description":"Setting this to true will bypass web security. DO NOT DO THIS IF YOU DO NOT HAVE TO. CORS issue may arise when using a proxy.","default":"`false`","key":"corsFix"},{"env":"WA_CALL_TIMEOUT","p":"call-timeout","type":"number","description":"Amount of time (in ms) to wait for a client method (specifically methods that interact with the WA web session) to resolve. If a client method results takes longer than the timout value then it will result in a [[PageEvaluationTimeout]] error.\n\nIf you get this error, it does not automatically mean that the method failed - it just stops your program from waiting for a client method to resolve.\n\nThis is useful if you do not rely on the results of a client method (e.g the message ID).\n\nIf set to `0`, the process will wait indefinitely for a client method to resolve.","default":0,"key":"callTimeout"},{"env":"WA_SCREENSHOT_ON_INITIALIZATION_BROWSER_ERROR","p":"screenshot-on-initialization-browser-error","type":"boolean","description":"When true, this option will take a screenshot of the browser when an unexpected error occurs within the browser during `create` initialization. The path will be `[working directory]/logs/[session ID]/[start timestamp]/[timestamp].jpg`","default":"`false`","key":"screenshotOnInitializationBrowserError"},{"env":"WA_EVENT_MODE","p":"event-mode","type":"boolean","description":"Setting listeners may not be your cup of tea. With eventMode, all [[SimpleListener]] events will be registered automatically and be filed via the built in Events Listener.\n\nThis is useful because you can register/deregister the event listener as needed whereas the legacy method of setting callbacks are only be set once","default":"`true`;","key":"eventMode"},{"env":"WA_LOG_FILE","p":"log-file","type":"boolean","description":"If true, the system will automatically create a log of all processes relating to actions sent to the web session.\n\nThe location of the file will be relative to the process directory (pd)\n\n`[pd]/[sessionId]/[start timestamp].log`","default":false,"key":"logFile"},{"env":"WA_ID_CORRECTION","p":"id-correction","type":"boolean","description":"When true, the system will attempt to correct chatIds and groupChatIds. This means you can ignore `@c.us` and `@g.us` distinctions in some parameters.","default":false,"key":"idCorrection"},{"env":"WA_STICKER_SERVER_ENDPOINT","p":"sticker-server-endpoint","type":["string","boolean"],"description":"Redundant until self-hostable sticker server is available.","default":"`https://sticker-api.openwa.dev`","key":"stickerServerEndpoint"},{"env":"WA_GH_PATCH","p":"gh-patch","type":"boolean","description":"This will force the library to use the default cached raw github link for patches to shave a few hundred milliseconds from your launch time. If you use this option, you will need to wait about 5 minutes before trying out new patches.","default":"`false`","key":"ghPatch"},{"env":"WA_CACHED_PATCH","p":"cached-patch","type":"boolean","description":"Setting this to `true` will save a local copy of the patches.json file (as patches.ignore.data.json) which will be used in subsequent instantiations of the session. While the rest of the launch procedure is running, the library will fetch and save a recent version of the patches to ensure your patches don't go stale. This will be ignored if the cached patches are more than a day old.","default":"`false`","key":"cachedPatch"},{"env":"WA_LOG_DEBUG_INFO_AS_OBJECT","p":"log-debug-info-as-object","type":"boolean","description":"Setting `this` to true will replace the `console.table` with a stringified logging of the debug info object instead. This would be useful to set for smaller terminal windows. If `disableSpins` is `true` then this will also be `true`.","default":"`false`","key":"logDebugInfoAsObject"},{"env":"WA_KILL_CLIENT_ON_LOGOUT","p":"kill-client-on-logout","type":"boolean","description":"Kill the client when a logout is detected","default":"`false`","key":"killClientOnLogout"},{"env":"WA_THROW_ON_EXPIRED_SESSION_DATA","p":"throw-on-expired-session-data","type":"boolean","description":"This will make the `create` command return `false` if the detected session data is expired.\n\nThis will mean, the process will not attempt to automatically get a new QR code.","default":"`false`","key":"throwOnExpiredSessionData"},{"env":"WA_USE_NATIVE_PROXY","p":"use-native-proxy","type":"boolean","description":"Some sessions may experience issues with sending media when using proxies. Using the native proxy system instead of the recommended 3rd party library may fix these issues.","default":"`false`","key":"useNativeProxy"},{"env":"WA_RASPI","p":"raspi","type":"boolean","description":"Set this to `true` to make the library work on Raspberry Pi OS.\n\nMake sure to run the following command before running the library the first time:\n\n``` > sudo apt update -y && sudo apt install chromium-browser chromium-codecs-ffmpeg -y && sudo apt upgrade ```\n\nIf you're using the CLI, you can set this value to `true` by adding the following flag to the CLI command\n\n``` > npx @open-wa/wa-automate ... --raspi ```","default":"`false`","key":"raspi"},{"env":"WA_MULTI_DEVICE","p":"multi-device","type":"boolean","description":"Please note that multi-device is still in beta so a lot of things may not work. It is HIGHLY suggested to NOT use this in production!!!!\n\nSet this to true if you're using the multidevice beta.","default":"`false`\n:::danger\nSome features (e.g [[sendLinkWithAutoPreview]]) **do not** work with multi-device beta. Check [this `api`](#).\n:::","key":"multiDevice"},{"env":"WA_SESSION_DATA_BUCKET_AUTH","p":"session-data-bucket-auth","type":"string","description":"Base64 encoded S3 Bucket & Authentication object for session data files. The object should be in the same format as cloudUploadOptions.","key":"sessionDataBucketAuth"},{"env":"WA_AUTO_EMOJI","p":"auto-emoji","type":"string","description":"Set the automatic emoji detection character. Set this to false to disable auto emoji. Default is `:`.","default":"`:`","key":"autoEmoji"},{"env":"WA_MAX_CHATS","p":"max-chats","type":"number","description":"Set the maximum amount of chats to be present in a session.","key":"maxChats"},{"env":"WA_MAX_MESSAGES","p":"max-messages","type":"number","description":"Set the maximum amount of messages to be present in a session.","key":"maxMessages"},{"env":"WA_DISCORD","p":"discord","type":"string","description":"Your Discord ID to get onto the sticker leaderboard!","key":"discord"},{"env":"WA_IGNORE_NUKE","p":"ignore-nuke","type":"boolean","description":"Don't implicitly determine if the host logged out.","key":"ignoreNuke"},{"env":"WA_ENSURE_HEADFUL_INTEGRITY","p":"ensure-headful-integrity","type":"boolean","description":"Makes sure the headless session is usable even on first login. Headful sessions are ususally only usable on reauthentication.","key":"ensureHeadfulIntegrity"},{"env":"WA_WAIT_FOR_RIPE_SESSION","p":"wait-for-ripe-session","type":"boolean","description":"wait for a valid headful session. Not required in recent versions.","key":"waitForRipeSession"},{"env":"WA_QR_MAX","p":"qr-max","type":"number","description":"Automatically kill the process after a set amount of qr codes","key":"qrMax"},{"env":"WA_EZQR","p":"ezqr","type":"boolean","description":"Expose a URL where you can easily scan the qr code","key":"ezqr"},{"env":"WA_LOGGING","p":"logging","type":"array","items":{"$ref":"#/definitions/ConfigLogTransport"},"description":"An array of [winston](https://github.com/winstonjs/winston/blob/master/docs/transports.md#additional-transports) logging transport configurations.\n\n[Check this discussion to see how to set up logging](https://github.com/open-wa/wa-automate-nodejs/discussions/2373)","key":"logging"}]
@@ -74,7 +74,7 @@ export declare class Client {
74
74
  * A convinience method to download the [[DataURL]] of a file
75
75
  * @param url The url
76
76
  * @param optionsOverride You can use this to override the [axios request config](https://github.com/axios/axios#request-config)
77
- * @returns Promise<DataURL>
77
+ * @returns `Promise<DataURL>`
78
78
  */
79
79
  download(url: string, optionsOverride?: any): Promise<DataURL>;
80
80
  /**
@@ -239,7 +239,8 @@ export declare class Client {
239
239
  *
240
240
  * Here is an example of the fired object:
241
241
  *
242
- * @fires ```javascript
242
+ * @fires
243
+ * ```javascript
243
244
  * {
244
245
  * "chat": "00000000000-1111111111@g.us", //the chat in which this state is occuring
245
246
  * "user": "22222222222@c.us", //the user that is causing this state
@@ -315,7 +316,7 @@ export declare class Client {
315
316
  * @param chatId the chat from which you want to subscribes to live location updates
316
317
  * @param fn callback that takes in a LiveLocationChangedEvent
317
318
  * @returns boolean, if returns false then there were no valid live locations in the chat of chatId
318
- * @emits <LiveLocationChangedEvent> LiveLocationChangedEvent
319
+ * @emits `<LiveLocationChangedEvent>` LiveLocationChangedEvent
319
320
  */
320
321
  onLiveLocation(chatId: ChatId, fn: (liveLocationChangedEvent: LiveLocationChangedEvent) => void): Promise<boolean>;
321
322
  /**
@@ -428,7 +429,7 @@ export declare class Client {
428
429
  * A list of participants in the chat who have their live location on. If the chat does not exist, or the chat does not have any contacts actively sharing their live locations, it will return false. If it's a chat with a single contact, there will be only 1 value in the array if the contact has their livelocation on.
429
430
  * Please note. This should only be called once every 30 or so seconds. This forces the phone to grab the latest live location data for the number. This can be used in conjunction with onLiveLocation (this will trigger onLiveLocation).
430
431
  * @param chatId string Id of the chat you want to force the phone to get the livelocation data for.
431
- * @returns Promise<LiveLocationChangedEvent []> | boolean
432
+ * @returns `Promise<LiveLocationChangedEvent []>` | boolean
432
433
  */
433
434
  forceUpdateLiveLocation(chatId: ChatId): Promise<LiveLocationChangedEvent[] | boolean>;
434
435
  private link;
@@ -482,6 +483,8 @@ export declare class Client {
482
483
  */
483
484
  sendBanner(to: ChatId, base64: Base64): Promise<boolean | MessageId>;
484
485
  /**
486
+ * {@license:insiders@}
487
+ * <span theme="badge contrast license">Insiders</span>
485
488
  * [REQUIRES AN INSIDERS LICENSE-KEY](https://gum.co/open-wa?tier=Insiders%20Program)
486
489
  *
487
490
  * Send a list message. This will not work when being sent from business accounts!
@@ -511,7 +514,7 @@ export declare class Client {
511
514
  * @param groupId group chat id: `xxxxx@g.us`
512
515
  * @param content text message to add under all of the tags
513
516
  * @param hideTags Removes all tags within the message
514
- * @returns Promise<MessageId>
517
+ * @returns `Promise<MessageId>`
515
518
  */
516
519
  tagEveryone(groupId: GroupChatId, content: Content, hideTags?: boolean): Promise<boolean | MessageId>;
517
520
  /**
@@ -542,7 +545,7 @@ export declare class Client {
542
545
  /**
543
546
  * Decrypts a media message.
544
547
  * @param message This can be the serialized [[MessageId]] or the whole [[Message]] object. It is advised to just use the serialized message ID.
545
- * @returns Promise<[[DataURL]]>
548
+ * @returns `Promise<[[DataURL]]>`
546
549
  */
547
550
  decryptMedia(message: Message | MessageId): Promise<DataURL>;
548
551
  /**
@@ -553,7 +556,7 @@ export declare class Client {
553
556
  * @param caption string xxxxx
554
557
  * @param waitForKey boolean default: false set this to true if you want to wait for the id of the message. By default this is set to false as it will take a few seconds to retrieve to the key of the message and this waiting may not be desirable for the majority of users.
555
558
  * @param hideTags boolean default: false [INSIDERS] set this to try silent tag someone in the caption
556
- * @returns Promise <boolean | string> This will either return true or the id of the message. It will return true after 10 seconds even if waitForId is true
559
+ * @returns `Promise <boolean | string>` This will either return true or the id of the message. It will return true after 10 seconds even if waitForId is true
557
560
  */
558
561
  sendImage(to: ChatId, file: DataURL | FilePath, filename: string, caption: Content, quotedMsgId?: MessageId, waitForId?: boolean, ptt?: boolean, withoutPreview?: boolean, hideTags?: boolean, viewOnce?: boolean): Promise<MessageId | boolean>;
559
562
  /**
@@ -580,7 +583,7 @@ export declare class Client {
580
583
  * @param content string reply text
581
584
  * @param quotedMsgId string the msg id to reply to.
582
585
  * @param sendSeen boolean If set to true, the chat will 'blue tick' all messages before sending the reply
583
- * @returns Promise<MessageId | false> false if didn't work, otherwise returns message id.
586
+ * @returns `Promise<MessageId | false>` false if didn't work, otherwise returns message id.
584
587
  */
585
588
  reply(to: ChatId, content: Content, quotedMsgId: MessageId, sendSeen?: boolean): Promise<boolean | MessageId>;
586
589
  /**
@@ -591,7 +594,7 @@ export declare class Client {
591
594
  * This will only work if you have chats sent back and forth between you and the contact 1-1.
592
595
  *
593
596
  * @param contactId The Id of the contact with which you have an existing conversation with messages already.
594
- * @returns Promise<string | boolean> true or false or a string with an explaintaion of why it wasn't able to determine the read receipts.
597
+ * @returns `Promise<string | boolean>` true or false or a string with an explaintaion of why it wasn't able to determine the read receipts.
595
598
  *
596
599
  */
597
600
  checkReadReceipts(contactId: ContactId): Promise<string | boolean>;
@@ -612,7 +615,7 @@ export declare class Client {
612
615
  * @param ptt boolean default: false set this to true if you want to send the file as a push to talk file.
613
616
  * @param withoutPreview boolean default: false set this to true if you want to send the file without a preview (i.e as a file). This is useful for preventing auto downloads on recipient devices.
614
617
  * @param hideTags boolean default: false [INSIDERS] set this to try silent tag someone in the caption
615
- * @returns Promise <boolean | MessageId> This will either return true or the id of the message. It will return true after 10 seconds even if waitForId is true
618
+ * @returns `Promise <boolean | MessageId>` This will either return true or the id of the message. It will return true after 10 seconds even if waitForId is true
616
619
  */
617
620
  sendFile(to: ChatId, file: DataURL | FilePath, filename: string, caption: Content, quotedMsgId?: MessageId, waitForId?: boolean, ptt?: boolean, withoutPreview?: boolean, hideTags?: boolean, viewOnce?: boolean): Promise<MessageId | boolean>;
618
621
  /**
@@ -620,7 +623,7 @@ export declare class Client {
620
623
  *
621
624
  * Checks whether or not the group id provided is known to be unsafe by the contributors of the library.
622
625
  * @param groupChatId The group chat you want to deteremine is unsafe
623
- * @returns Promise <boolean | string> This will either return a boolean indiciating whether this group chat id is considered unsafe or an error message as a string
626
+ * @returns `Promise <boolean | string>` This will either return a boolean indiciating whether this group chat id is considered unsafe or an error message as a string
624
627
  */
625
628
  isGroupIdUnsafe(groupChatId: GroupChatId): Promise<string | boolean>;
626
629
  /**
@@ -628,7 +631,7 @@ export declare class Client {
628
631
  * @param to chat id `xxxxx@c.us`
629
632
  * @param file base64 data:image/xxx;base64,xxx or the path of the file you want to send.
630
633
  * @param quotedMsgId string true_0000000000@c.us_JHB2HB23HJ4B234HJB to send as a reply to a message
631
- * @returns Promise <boolean | string> This will either return true or the id of the message. It will return true after 10 seconds even if waitForId is true
634
+ * @returns `Promise <boolean | string>` This will either return true or the id of the message. It will return true after 10 seconds even if waitForId is true
632
635
  */
633
636
  sendPtt(to: ChatId, file: DataURL | FilePath, quotedMsgId: MessageId): Promise<MessageId>;
634
637
  /**
@@ -674,7 +677,7 @@ export declare class Client {
674
677
  getMe(): Promise<any>;
675
678
  /**
676
679
  * Returns a PNG DataURL screenshot of the session
677
- * @returns Promise<DataURL>
680
+ * @returns `Promise<DataURL>`
678
681
  */
679
682
  getSnapshot(): Promise<DataURL>;
680
683
  /**
@@ -793,7 +796,7 @@ export declare class Client {
793
796
  * Any potential abuse of this method will see it become paywalled.
794
797
  * @param to: Chat id to forward the message to
795
798
  * @param messageId: message id of the message to forward. Please note that if it is not loaded, this will return false - even if it exists.
796
- * @returns Promise<MessageId | boolean>
799
+ * @returns `Promise<MessageId | boolean>`
797
800
  */
798
801
  ghostForward(to: ChatId, messageId: MessageId): Promise<MessageId | boolean>;
799
802
  /**
@@ -861,7 +864,7 @@ export declare class Client {
861
864
  getAllChatIds(): Promise<ChatId[]>;
862
865
  /**
863
866
  * retrieves an array of IDs of accounts blocked by the host account.
864
- * @returns Promise<ChatId[]>
867
+ * @returns `Promise<ChatId[]>`
865
868
  */
866
869
  getBlockedIds(): Promise<ChatId[]>;
867
870
  /**
@@ -900,7 +903,7 @@ export declare class Client {
900
903
  * @param returnChatObj boolean When this is set to true and if the group was joined successfully, it will return a serialzed Chat object which includes group information and metadata. This is useful when you want to immediately do something with group metadata.
901
904
  *
902
905
  *
903
- * @returns Promise<string | boolean | number> Either false if it didn't work, or the group id.
906
+ * @returns `Promise<string | boolean | number>` Either false if it didn't work, or the group id.
904
907
  */
905
908
  joinGroupViaLink(link: string, returnChatObj?: boolean): Promise<string | boolean | number | Chat>;
906
909
  /**
@@ -1165,7 +1168,7 @@ export declare class Client {
1165
1168
  /**
1166
1169
  * Retrieves an invite link for a group chat. returns false if chat is not a group.
1167
1170
  * @param chatId
1168
- * @returns Promise<string>
1171
+ * @returns `Promise<string>`
1169
1172
  */
1170
1173
  getGroupInviteLink(chatId: ChatId): Promise<string>;
1171
1174
  /**
@@ -1177,7 +1180,7 @@ export declare class Client {
1177
1180
  /**
1178
1181
  * Revokes the current invite link for a group chat. Any previous links will stop working
1179
1182
  * @param chatId
1180
- * @returns Promise<boolean>
1183
+ * @returns `Promise<boolean>`
1181
1184
  */
1182
1185
  revokeGroupInviteLink(chatId: ChatId): Promise<boolean | string>;
1183
1186
  /**
@@ -1252,21 +1255,6 @@ export declare class Client {
1252
1255
  *
1253
1256
  * @param groupName group name: 'New group'
1254
1257
  * @param contacts: A single contact id or an array of contact ids.
1255
- * @returns Promise<GroupCreationResponse> :
1256
- * ```javascript
1257
- * {
1258
- * status: 200,
1259
- * gid: {
1260
- * server: 'g.us',
1261
- * user: '447777777777-1583678870',
1262
- * _serialized: '447777777777-1583678870@g.us'
1263
- * },
1264
- * participants: [
1265
- * { '447777777777@c.us': [Object] },
1266
- * { '447444444444@c.us': [Object] }
1267
- * ]
1268
- * }
1269
- * ```
1270
1258
  */
1271
1259
  createGroup(groupName: string, contacts: ContactId | ContactId[]): Promise<GroupChatCreationResponse>;
1272
1260
  /**
@@ -1416,7 +1404,7 @@ export declare class Client {
1416
1404
  * @param url: The url of the image
1417
1405
  * @param requestConfig {} By default the request is a get request, however you can override that and many other options by sending this parameter. You can read more about this parameter here: https://github.com/axios/axios#request-config
1418
1406
  *
1419
- * @returns Promise<MessageId | boolean>
1407
+ * @returns `Promise<MessageId | boolean>`
1420
1408
  */
1421
1409
  sendStickerfromUrl(to: ChatId, url: string, requestConfig?: AxiosRequestConfig, stickerMetadata?: StickerMetadata): Promise<string | MessageId | boolean>;
1422
1410
  /**
@@ -1428,7 +1416,7 @@ export declare class Client {
1428
1416
  * @param messageId The id of the message to reply to
1429
1417
  * @param requestConfig {} By default the request is a get request, however you can override that and many other options by sending this parameter. You can read more about this parameter here: https://github.com/axios/axios#request-config
1430
1418
  *
1431
- * @returns Promise<MessageId | boolean>
1419
+ * @returns `Promise<MessageId | boolean>`
1432
1420
  */
1433
1421
  sendStickerfromUrlAsReply(to: ChatId, url: string, messageId: MessageId, requestConfig?: AxiosRequestConfig, stickerMetadata?: StickerMetadata): Promise<MessageId | boolean>;
1434
1422
  /**
@@ -1505,7 +1493,7 @@ export declare class Client {
1505
1493
  * Turn the ephemeral setting in a chat to on or off
1506
1494
  * @param chatId The ID of the chat
1507
1495
  * @param ephemeral `true` to turn on the ephemeral setting, `false` to turn off the ephemeral setting. Please note, if the setting is already on the requested setting, this method will return `true`.
1508
- * @returns Promise<boolean> true if the setting was set, `false` if the chat does not exist
1496
+ * @returns `Promise<boolean>` true if the setting was set, `false` if the chat does not exist
1509
1497
  */
1510
1498
  setChatEphemeral(chatId: ChatId, ephemeral: boolean): Promise<boolean>;
1511
1499
  /**
@@ -1528,7 +1516,7 @@ export declare class Client {
1528
1516
  * 3: [Bryndan Write](https://www.dafontfree.net/freefonts-bryndan-write-f160189.htm)
1529
1517
  * 4: [Bebasneue Regular](https://www.dafont.com/bebas-neue.font)
1530
1518
  * 5: [Oswald Heavy](https://www.fontsquirrel.com/fonts/oswald)
1531
- * @returns Promise<string | boolean> returns status id if it worked, false if it didn't
1519
+ * @returns `Promise<string | boolean>` returns status id if it worked, false if it didn't
1532
1520
  */
1533
1521
  postTextStatus(text: Content, textRgba: string, backgroundRgba: string, font: number): Promise<MessageId | string | boolean>;
1534
1522
  /**
@@ -1537,7 +1525,7 @@ export declare class Client {
1537
1525
  * Posts an image story.
1538
1526
  * @param data data url string `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
1539
1527
  * @param caption The caption for the story
1540
- * @returns Promise<string | boolean> returns status id if it worked, false if it didn't
1528
+ * @returns `Promise<string | boolean>` returns status id if it worked, false if it didn't
1541
1529
  */
1542
1530
  postImageStatus(data: DataURL, caption: Content): Promise<MessageId | string | boolean>;
1543
1531
  /**
@@ -1546,7 +1534,7 @@ export declare class Client {
1546
1534
  * Posts a video story.
1547
1535
  * @param data data url string `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
1548
1536
  * @param caption The caption for the story
1549
- * @returns Promise<string | boolean> returns status id if it worked, false if it didn't
1537
+ * @returns `Promise<string | boolean>` returns status id if it worked, false if it didn't
1550
1538
  */
1551
1539
  postVideoStatus(data: DataURL, caption: Content): Promise<MessageId | string | boolean>;
1552
1540
  /**
@@ -1632,7 +1620,7 @@ export declare class Client {
1632
1620
  *
1633
1621
  * Sets the profile pic of the host number.
1634
1622
  * @param data string data url image string.
1635
- * @returns Promise<boolean> success if true
1623
+ * @returns `Promise<boolean>` success if true
1636
1624
  */
1637
1625
  setProfilePic(data: DataURL): Promise<boolean>;
1638
1626
  /**
@@ -303,7 +303,7 @@ class Client {
303
303
  }
304
304
  _reInjectWapi(newTab) {
305
305
  return __awaiter(this, void 0, void 0, function* () {
306
- yield (0, browser_1.injectApi)(newTab || this._page);
306
+ yield (0, browser_1.injectApi)(newTab || this._page, null, true);
307
307
  });
308
308
  }
309
309
  _reRegisterListeners() {
@@ -315,7 +315,7 @@ class Client {
315
315
  * A convinience method to download the [[DataURL]] of a file
316
316
  * @param url The url
317
317
  * @param optionsOverride You can use this to override the [axios request config](https://github.com/axios/axios#request-config)
318
- * @returns Promise<DataURL>
318
+ * @returns `Promise<DataURL>`
319
319
  */
320
320
  download(url, optionsOverride = {}) {
321
321
  return __awaiter(this, void 0, void 0, function* () {
@@ -364,7 +364,6 @@ class Client {
364
364
  /**
365
365
  * Wait for the new page to be loaded up before closing existing page
366
366
  */
367
- yield (0, patch_manager_1.earlyInjectionCheck)(newTab);
368
367
  spinner.info("Checking if fresh session is authenticated...");
369
368
  if (yield (0, auth_1.isAuthenticated)(newTab)) {
370
369
  /**
@@ -813,7 +812,8 @@ class Client {
813
812
  *
814
813
  * Here is an example of the fired object:
815
814
  *
816
- * @fires ```javascript
815
+ * @fires
816
+ * ```javascript
817
817
  * {
818
818
  * "chat": "00000000000-1111111111@g.us", //the chat in which this state is occuring
819
819
  * "user": "22222222222@c.us", //the user that is causing this state
@@ -931,7 +931,7 @@ class Client {
931
931
  * @param chatId the chat from which you want to subscribes to live location updates
932
932
  * @param fn callback that takes in a LiveLocationChangedEvent
933
933
  * @returns boolean, if returns false then there were no valid live locations in the chat of chatId
934
- * @emits <LiveLocationChangedEvent> LiveLocationChangedEvent
934
+ * @emits `<LiveLocationChangedEvent>` LiveLocationChangedEvent
935
935
  */
936
936
  onLiveLocation(chatId, fn) {
937
937
  return __awaiter(this, void 0, void 0, function* () {
@@ -1148,7 +1148,7 @@ class Client {
1148
1148
  * A list of participants in the chat who have their live location on. If the chat does not exist, or the chat does not have any contacts actively sharing their live locations, it will return false. If it's a chat with a single contact, there will be only 1 value in the array if the contact has their livelocation on.
1149
1149
  * Please note. This should only be called once every 30 or so seconds. This forces the phone to grab the latest live location data for the number. This can be used in conjunction with onLiveLocation (this will trigger onLiveLocation).
1150
1150
  * @param chatId string Id of the chat you want to force the phone to get the livelocation data for.
1151
- * @returns Promise<LiveLocationChangedEvent []> | boolean
1151
+ * @returns `Promise<LiveLocationChangedEvent []>` | boolean
1152
1152
  */
1153
1153
  forceUpdateLiveLocation(chatId) {
1154
1154
  return __awaiter(this, void 0, void 0, function* () {
@@ -1266,6 +1266,8 @@ class Client {
1266
1266
  });
1267
1267
  }
1268
1268
  /**
1269
+ * {@license:insiders@}
1270
+ * <span theme="badge contrast license">Insiders</span>
1269
1271
  * [REQUIRES AN INSIDERS LICENSE-KEY](https://gum.co/open-wa?tier=Insiders%20Program)
1270
1272
  *
1271
1273
  * Send a list message. This will not work when being sent from business accounts!
@@ -1310,7 +1312,7 @@ class Client {
1310
1312
  * @param groupId group chat id: `xxxxx@g.us`
1311
1313
  * @param content text message to add under all of the tags
1312
1314
  * @param hideTags Removes all tags within the message
1313
- * @returns Promise<MessageId>
1315
+ * @returns `Promise<MessageId>`
1314
1316
  */
1315
1317
  tagEveryone(groupId, content, hideTags) {
1316
1318
  return __awaiter(this, void 0, void 0, function* () {
@@ -1367,7 +1369,7 @@ class Client {
1367
1369
  /**
1368
1370
  * Decrypts a media message.
1369
1371
  * @param message This can be the serialized [[MessageId]] or the whole [[Message]] object. It is advised to just use the serialized message ID.
1370
- * @returns Promise<[[DataURL]]>
1372
+ * @returns `Promise<[[DataURL]]>`
1371
1373
  */
1372
1374
  decryptMedia(message) {
1373
1375
  return __awaiter(this, void 0, void 0, function* () {
@@ -1398,7 +1400,7 @@ class Client {
1398
1400
  * @param caption string xxxxx
1399
1401
  * @param waitForKey boolean default: false set this to true if you want to wait for the id of the message. By default this is set to false as it will take a few seconds to retrieve to the key of the message and this waiting may not be desirable for the majority of users.
1400
1402
  * @param hideTags boolean default: false [INSIDERS] set this to try silent tag someone in the caption
1401
- * @returns Promise <boolean | string> This will either return true or the id of the message. It will return true after 10 seconds even if waitForId is true
1403
+ * @returns `Promise <boolean | string>` This will either return true or the id of the message. It will return true after 10 seconds even if waitForId is true
1402
1404
  */
1403
1405
  sendImage(to, file, filename, caption, quotedMsgId, waitForId, ptt, withoutPreview, hideTags, viewOnce) {
1404
1406
  return __awaiter(this, void 0, void 0, function* () {
@@ -1462,7 +1464,7 @@ class Client {
1462
1464
  * @param content string reply text
1463
1465
  * @param quotedMsgId string the msg id to reply to.
1464
1466
  * @param sendSeen boolean If set to true, the chat will 'blue tick' all messages before sending the reply
1465
- * @returns Promise<MessageId | false> false if didn't work, otherwise returns message id.
1467
+ * @returns `Promise<MessageId | false>` false if didn't work, otherwise returns message id.
1466
1468
  */
1467
1469
  reply(to, content, quotedMsgId, sendSeen) {
1468
1470
  return __awaiter(this, void 0, void 0, function* () {
@@ -1479,7 +1481,7 @@ class Client {
1479
1481
  * This will only work if you have chats sent back and forth between you and the contact 1-1.
1480
1482
  *
1481
1483
  * @param contactId The Id of the contact with which you have an existing conversation with messages already.
1482
- * @returns Promise<string | boolean> true or false or a string with an explaintaion of why it wasn't able to determine the read receipts.
1484
+ * @returns `Promise<string | boolean>` true or false or a string with an explaintaion of why it wasn't able to determine the read receipts.
1483
1485
  *
1484
1486
  */
1485
1487
  checkReadReceipts(contactId) {
@@ -1504,7 +1506,7 @@ class Client {
1504
1506
  * @param ptt boolean default: false set this to true if you want to send the file as a push to talk file.
1505
1507
  * @param withoutPreview boolean default: false set this to true if you want to send the file without a preview (i.e as a file). This is useful for preventing auto downloads on recipient devices.
1506
1508
  * @param hideTags boolean default: false [INSIDERS] set this to try silent tag someone in the caption
1507
- * @returns Promise <boolean | MessageId> This will either return true or the id of the message. It will return true after 10 seconds even if waitForId is true
1509
+ * @returns `Promise <boolean | MessageId>` This will either return true or the id of the message. It will return true after 10 seconds even if waitForId is true
1508
1510
  */
1509
1511
  sendFile(to, file, filename, caption, quotedMsgId, waitForId, ptt, withoutPreview, hideTags, viewOnce) {
1510
1512
  return __awaiter(this, void 0, void 0, function* () {
@@ -1516,7 +1518,7 @@ class Client {
1516
1518
  *
1517
1519
  * Checks whether or not the group id provided is known to be unsafe by the contributors of the library.
1518
1520
  * @param groupChatId The group chat you want to deteremine is unsafe
1519
- * @returns Promise <boolean | string> This will either return a boolean indiciating whether this group chat id is considered unsafe or an error message as a string
1521
+ * @returns `Promise <boolean | string>` This will either return a boolean indiciating whether this group chat id is considered unsafe or an error message as a string
1520
1522
  */
1521
1523
  isGroupIdUnsafe(groupChatId) {
1522
1524
  return __awaiter(this, void 0, void 0, function* () {
@@ -1535,7 +1537,7 @@ class Client {
1535
1537
  * @param to chat id `xxxxx@c.us`
1536
1538
  * @param file base64 data:image/xxx;base64,xxx or the path of the file you want to send.
1537
1539
  * @param quotedMsgId string true_0000000000@c.us_JHB2HB23HJ4B234HJB to send as a reply to a message
1538
- * @returns Promise <boolean | string> This will either return true or the id of the message. It will return true after 10 seconds even if waitForId is true
1540
+ * @returns `Promise <boolean | string>` This will either return true or the id of the message. It will return true after 10 seconds even if waitForId is true
1539
1541
  */
1540
1542
  sendPtt(to, file, quotedMsgId) {
1541
1543
  return __awaiter(this, void 0, void 0, function* () {
@@ -1635,7 +1637,7 @@ class Client {
1635
1637
  }
1636
1638
  /**
1637
1639
  * Returns a PNG DataURL screenshot of the session
1638
- * @returns Promise<DataURL>
1640
+ * @returns `Promise<DataURL>`
1639
1641
  */
1640
1642
  getSnapshot() {
1641
1643
  return __awaiter(this, void 0, void 0, function* () {
@@ -1825,7 +1827,7 @@ class Client {
1825
1827
  * Any potential abuse of this method will see it become paywalled.
1826
1828
  * @param to: Chat id to forward the message to
1827
1829
  * @param messageId: message id of the message to forward. Please note that if it is not loaded, this will return false - even if it exists.
1828
- * @returns Promise<MessageId | boolean>
1830
+ * @returns `Promise<MessageId | boolean>`
1829
1831
  */
1830
1832
  ghostForward(to, messageId) {
1831
1833
  return __awaiter(this, void 0, void 0, function* () {
@@ -1944,7 +1946,7 @@ class Client {
1944
1946
  }
1945
1947
  /**
1946
1948
  * retrieves an array of IDs of accounts blocked by the host account.
1947
- * @returns Promise<ChatId[]>
1949
+ * @returns `Promise<ChatId[]>`
1948
1950
  */
1949
1951
  getBlockedIds() {
1950
1952
  return __awaiter(this, void 0, void 0, function* () {
@@ -2011,7 +2013,7 @@ class Client {
2011
2013
  * @param returnChatObj boolean When this is set to true and if the group was joined successfully, it will return a serialzed Chat object which includes group information and metadata. This is useful when you want to immediately do something with group metadata.
2012
2014
  *
2013
2015
  *
2014
- * @returns Promise<string | boolean | number> Either false if it didn't work, or the group id.
2016
+ * @returns `Promise<string | boolean | number>` Either false if it didn't work, or the group id.
2015
2017
  */
2016
2018
  joinGroupViaLink(link, returnChatObj) {
2017
2019
  return __awaiter(this, void 0, void 0, function* () {
@@ -2407,7 +2409,7 @@ class Client {
2407
2409
  /**
2408
2410
  * Retrieves an invite link for a group chat. returns false if chat is not a group.
2409
2411
  * @param chatId
2410
- * @returns Promise<string>
2412
+ * @returns `Promise<string>`
2411
2413
  */
2412
2414
  getGroupInviteLink(chatId) {
2413
2415
  return __awaiter(this, void 0, void 0, function* () {
@@ -2427,7 +2429,7 @@ class Client {
2427
2429
  /**
2428
2430
  * Revokes the current invite link for a group chat. Any previous links will stop working
2429
2431
  * @param chatId
2430
- * @returns Promise<boolean>
2432
+ * @returns `Promise<boolean>`
2431
2433
  */
2432
2434
  revokeGroupInviteLink(chatId) {
2433
2435
  return __awaiter(this, void 0, void 0, function* () {
@@ -2542,21 +2544,6 @@ class Client {
2542
2544
  *
2543
2545
  * @param groupName group name: 'New group'
2544
2546
  * @param contacts: A single contact id or an array of contact ids.
2545
- * @returns Promise<GroupCreationResponse> :
2546
- * ```javascript
2547
- * {
2548
- * status: 200,
2549
- * gid: {
2550
- * server: 'g.us',
2551
- * user: '447777777777-1583678870',
2552
- * _serialized: '447777777777-1583678870@g.us'
2553
- * },
2554
- * participants: [
2555
- * { '447777777777@c.us': [Object] },
2556
- * { '447444444444@c.us': [Object] }
2557
- * ]
2558
- * }
2559
- * ```
2560
2547
  */
2561
2548
  createGroup(groupName, contacts) {
2562
2549
  return __awaiter(this, void 0, void 0, function* () {
@@ -2791,7 +2778,7 @@ class Client {
2791
2778
  * @param url: The url of the image
2792
2779
  * @param requestConfig {} By default the request is a get request, however you can override that and many other options by sending this parameter. You can read more about this parameter here: https://github.com/axios/axios#request-config
2793
2780
  *
2794
- * @returns Promise<MessageId | boolean>
2781
+ * @returns `Promise<MessageId | boolean>`
2795
2782
  */
2796
2783
  sendStickerfromUrl(to, url, requestConfig = {}, stickerMetadata) {
2797
2784
  return __awaiter(this, void 0, void 0, function* () {
@@ -2808,7 +2795,7 @@ class Client {
2808
2795
  * @param messageId The id of the message to reply to
2809
2796
  * @param requestConfig {} By default the request is a get request, however you can override that and many other options by sending this parameter. You can read more about this parameter here: https://github.com/axios/axios#request-config
2810
2797
  *
2811
- * @returns Promise<MessageId | boolean>
2798
+ * @returns `Promise<MessageId | boolean>`
2812
2799
  */
2813
2800
  sendStickerfromUrlAsReply(to, url, messageId, requestConfig = {}, stickerMetadata) {
2814
2801
  return __awaiter(this, void 0, void 0, function* () {
@@ -3096,7 +3083,7 @@ class Client {
3096
3083
  * Turn the ephemeral setting in a chat to on or off
3097
3084
  * @param chatId The ID of the chat
3098
3085
  * @param ephemeral `true` to turn on the ephemeral setting, `false` to turn off the ephemeral setting. Please note, if the setting is already on the requested setting, this method will return `true`.
3099
- * @returns Promise<boolean> true if the setting was set, `false` if the chat does not exist
3086
+ * @returns `Promise<boolean>` true if the setting was set, `false` if the chat does not exist
3100
3087
  */
3101
3088
  setChatEphemeral(chatId, ephemeral) {
3102
3089
  return __awaiter(this, void 0, void 0, function* () {
@@ -3127,7 +3114,7 @@ class Client {
3127
3114
  * 3: [Bryndan Write](https://www.dafontfree.net/freefonts-bryndan-write-f160189.htm)
3128
3115
  * 4: [Bebasneue Regular](https://www.dafont.com/bebas-neue.font)
3129
3116
  * 5: [Oswald Heavy](https://www.fontsquirrel.com/fonts/oswald)
3130
- * @returns Promise<string | boolean> returns status id if it worked, false if it didn't
3117
+ * @returns `Promise<string | boolean>` returns status id if it worked, false if it didn't
3131
3118
  */
3132
3119
  postTextStatus(text, textRgba, backgroundRgba, font) {
3133
3120
  return __awaiter(this, void 0, void 0, function* () {
@@ -3140,7 +3127,7 @@ class Client {
3140
3127
  * Posts an image story.
3141
3128
  * @param data data url string `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
3142
3129
  * @param caption The caption for the story
3143
- * @returns Promise<string | boolean> returns status id if it worked, false if it didn't
3130
+ * @returns `Promise<string | boolean>` returns status id if it worked, false if it didn't
3144
3131
  */
3145
3132
  postImageStatus(data, caption) {
3146
3133
  return __awaiter(this, void 0, void 0, function* () {
@@ -3153,7 +3140,7 @@ class Client {
3153
3140
  * Posts a video story.
3154
3141
  * @param data data url string `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
3155
3142
  * @param caption The caption for the story
3156
- * @returns Promise<string | boolean> returns status id if it worked, false if it didn't
3143
+ * @returns `Promise<string | boolean>` returns status id if it worked, false if it didn't
3157
3144
  */
3158
3145
  postVideoStatus(data, caption) {
3159
3146
  return __awaiter(this, void 0, void 0, function* () {
@@ -3276,7 +3263,7 @@ class Client {
3276
3263
  *
3277
3264
  * Sets the profile pic of the host number.
3278
3265
  * @param data string data url image string.
3279
- * @returns Promise<boolean> success if true
3266
+ * @returns `Promise<boolean>` success if true
3280
3267
  */
3281
3268
  setProfilePic(data) {
3282
3269
  return __awaiter(this, void 0, void 0, function* () {
@@ -1,3 +1,6 @@
1
+ declare type Brand<K, T> = K & {
2
+ __brand?: T;
3
+ };
1
4
  /**
2
5
  * The suffix used to identify a non-group chat id
3
6
  */
@@ -33,7 +36,7 @@ export declare type GroupChatId = `${AccountNumber}-${number}@${GroupChatServer}
33
36
  *
34
37
  * `"447123456789@c.us"`
35
38
  */
36
- export declare type ContactId = `${AccountNumber}@${ChatServer}`;
39
+ export declare type ContactId = Brand<`${AccountNumber}@${ChatServer}`, "ContactId">;
37
40
  /**
38
41
  * A chat id ends with `@c.us` or `@g.us` for group chats.
39
42
  *
@@ -51,7 +54,7 @@ export declare type ChatId = ContactId | GroupChatId;
51
54
  *
52
55
  * `"false_447123456789@c.us_9C4D0965EA5C09D591334AB6BDB07FEB"`
53
56
  */
54
- export declare type MessageId = `${boolean}_${ChatId}_${string}`;
57
+ export declare type MessageId = Brand<`${boolean}_${ChatId}_${string}`, "MessageId">;
55
58
  /**
56
59
  * This is a generic type alias for the content of a message
57
60
  *
@@ -59,7 +62,7 @@ export declare type MessageId = `${boolean}_${ChatId}_${string}`;
59
62
  *
60
63
  * `"hello!"`
61
64
  */
62
- export declare type Content = string;
65
+ export declare type Content = Brand<string, "Content">;
63
66
  export declare type NonSerializedId = {
64
67
  server: WaServers;
65
68
  user: AccountNumber;
@@ -77,7 +80,7 @@ export declare type NonSerializedId = {
77
80
  *
78
81
  * Learn more here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
79
82
  */
80
- export declare type DataURL = string;
83
+ export declare type DataURL = Brand<`data:${string};base64,${Base64}`, "DataURL">;
81
84
  /**
82
85
  * Base64 is basically a file encoded as a string.
83
86
  *
@@ -85,10 +88,11 @@ export declare type DataURL = string;
85
88
  *
86
89
  * Learn more here: https://developer.mozilla.org/en-US/docs/Glossary/Base64
87
90
  */
88
- export declare type Base64 = string;
91
+ export declare type Base64 = Brand<string, "Base64">;
89
92
  /**
90
93
  * The relative or absolute path of a file
91
94
  *
92
95
  * Learn more here: https://www.w3schools.com/html/html_filepaths.asp
93
96
  */
94
- export declare type FilePath = string;
97
+ export declare type FilePath = Brand<string, "FilePath">;
98
+ export {};
@@ -1,2 +1,3 @@
1
1
  "use strict";
2
+ // declare const tag: unique symbol
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -687,7 +687,7 @@ export interface ConfigObject {
687
687
  /**
688
688
  * What to do when an error is detected on a client method.
689
689
  *
690
- * @default `NOTHING`
690
+ * @default `OnError.NOTHING`
691
691
  */
692
692
  onError?: OnError;
693
693
  /**
@@ -697,6 +697,9 @@ export interface ConfigObject {
697
697
  * Set this to true if you're using the multidevice beta.
698
698
  *
699
699
  * @default `false`
700
+ * :::danger
701
+ * Some features (e.g [[sendLinkWithAutoPreview]]) **do not** work with multi-device beta. Check [this `api`](#).
702
+ * :::
700
703
  */
701
704
  multiDevice?: boolean;
702
705
  /**
@@ -3,6 +3,7 @@ export * from './contact';
3
3
  export * from './message';
4
4
  export * from './errors';
5
5
  export * from './events';
6
+ export * from './product';
6
7
  /**
7
8
  * Client status
8
9
  * @readonly
@@ -16,6 +16,7 @@ __exportStar(require("./contact"), exports);
16
16
  __exportStar(require("./message"), exports);
17
17
  __exportStar(require("./errors"), exports);
18
18
  __exportStar(require("./events"), exports);
19
+ __exportStar(require("./product"), exports);
19
20
  /**
20
21
  * Client status
21
22
  * @readonly
@@ -75,7 +75,7 @@ export interface Product {
75
75
  description?: string;
76
76
  /**
77
77
  * The availiable quantity of this product.
78
- * @default `"unknown"``
78
+ * @default "unknown"`
79
79
  */
80
80
  availability?: number | "unknown";
81
81
  /**
@@ -3,13 +3,13 @@ import { Spin } from './events';
3
3
  import { ConfigObject } from '../api/model';
4
4
  import { Page } from 'puppeteer';
5
5
  /**
6
+ * isAuthenticated
6
7
  * Validates if client is authenticated
7
8
  * @returns true if is authenticated, false otherwise
8
9
  * @param waPage
9
10
  */
10
11
  export declare const isAuthenticated: (waPage: Page) => Promise<unknown>;
11
12
  export declare const needsToScan: (waPage: Page) => Observable<unknown>;
12
- export declare const isInsideChat: (waPage: Page) => Observable<boolean>;
13
13
  export declare const waitForRipeSession: (waPage: Page) => Promise<boolean>;
14
14
  export declare const sessionDataInvalid: (waPage: Page) => Promise<string>;
15
15
  export declare const phoneIsOutOfReach: (waPage: Page) => Promise<boolean>;
@@ -27,6 +27,10 @@ export declare class QRManager {
27
27
  grabAndEmit(qrData: any, waPage: Page, config: ConfigObject, spinner: Spin): Promise<void>;
28
28
  smartQr(waPage: Page, config?: ConfigObject, spinner?: Spin): Promise<boolean | void | string>;
29
29
  emitFirst(waPage: Page, config?: ConfigObject, spinner?: Spin): Promise<void>;
30
+ /**
31
+ * Wait 10 seconds for the qr element to show.
32
+ * If it doesn't show up within 10 seconds then assume the session is authed already or blocked therefore ignore and return promise
33
+ */
30
34
  waitFirstQr(waPage: Page, config?: ConfigObject, spinner?: Spin): Promise<void>;
31
35
  }
32
36
  export declare const qrManager: QRManager;
@@ -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.qrManager = exports.QRManager = exports.phoneIsOutOfReach = exports.sessionDataInvalid = exports.waitForRipeSession = exports.isInsideChat = exports.needsToScan = exports.isAuthenticated = void 0;
34
+ exports.qrManager = exports.QRManager = exports.phoneIsOutOfReach = exports.sessionDataInvalid = exports.waitForRipeSession = exports.needsToScan = exports.isAuthenticated = void 0;
35
35
  const qrcode = __importStar(require("qrcode-terminal"));
36
36
  const rxjs_1 = require("rxjs");
37
37
  const events_1 = require("./events");
@@ -41,11 +41,12 @@ const browser_1 = require("./browser");
41
41
  const axios_1 = __importDefault(require("axios"));
42
42
  const logging_1 = require("../logging/logging");
43
43
  /**
44
+ * isAuthenticated
44
45
  * Validates if client is authenticated
45
46
  * @returns true if is authenticated, false otherwise
46
47
  * @param waPage
47
48
  */
48
- const isAuthenticated = (waPage) => (0, rxjs_1.race)((0, exports.needsToScan)(waPage), (0, exports.isInsideChat)(waPage), (0, exports.sessionDataInvalid)(waPage)).toPromise();
49
+ const isAuthenticated = (waPage) => (0, rxjs_1.race)((0, exports.needsToScan)(waPage), isInsideChat(waPage), (0, exports.sessionDataInvalid)(waPage)).toPromise();
49
50
  exports.isAuthenticated = isAuthenticated;
50
51
  const needsToScan = (waPage) => {
51
52
  return (0, rxjs_1.from)(new Promise((resolve) => __awaiter(void 0, void 0, void 0, function* () {
@@ -72,7 +73,11 @@ const isInsideChat = (waPage) => {
72
73
  .waitForFunction("!!window.WA_AUTHENTICATED || (document.getElementsByClassName('app')[0] && document.getElementsByClassName('app')[0].attributes && !!document.getElementsByClassName('app')[0].attributes.tabindex) || (document.getElementsByClassName('two')[0] && document.getElementsByClassName('two')[0].attributes && !!document.getElementsByClassName('two')[0].attributes.tabindex)", { timeout: 0 })
73
74
  .then(() => true));
74
75
  };
75
- exports.isInsideChat = isInsideChat;
76
+ const isTosBlocked = (waPage) => {
77
+ return (0, rxjs_1.from)(waPage
78
+ .waitForFunction(`document.getElementsByTagName("html")[0].classList[0] === 'no-js'`, { timeout: 0 })
79
+ .then(() => false));
80
+ };
76
81
  const waitForRipeSession = (waPage) => __awaiter(void 0, void 0, void 0, function* () {
77
82
  try {
78
83
  yield waPage.waitForFunction(`window.isRipeSession()`, { timeout: 0, polling: 'mutation' });
@@ -84,11 +89,17 @@ const waitForRipeSession = (waPage) => __awaiter(void 0, void 0, void 0, functio
84
89
  });
85
90
  exports.waitForRipeSession = waitForRipeSession;
86
91
  const sessionDataInvalid = (waPage) => __awaiter(void 0, void 0, void 0, function* () {
92
+ const check = `Object.keys(localStorage).includes("old-logout-cred")`;
87
93
  yield waPage
88
- .waitForFunction('!window.getQrPng', { timeout: 0, polling: 'mutation' });
89
- yield (0, browser_1.injectApi)(waPage);
90
- yield waPage
91
- .waitForFunction('!window.getQrPng', { timeout: 0, polling: 'mutation' });
94
+ .waitForFunction(check, { timeout: 0, polling: 'mutation' });
95
+ // await injectApi(waPage, null, true);
96
+ // await waPage
97
+ // .waitForFunction(
98
+ // '!window.getQrPng',
99
+ // { timeout: 0, polling: 'mutation' }
100
+ // )
101
+ // await timeout(1000000)
102
+ //NEED A DIFFERENT WAY TO DETERMINE IF THE SESSION WAS LOGGED OUT!!!!
92
103
  //if the code reaches here it means the browser was refreshed. Nuke the session data and restart `create`
93
104
  return 'NUKE';
94
105
  });
@@ -212,7 +223,7 @@ class QRManager {
212
223
  if (!gotResult && (qrData === 'QR_CODE_SUCCESS' || qrData === md)) {
213
224
  gotResult = true;
214
225
  spinner === null || spinner === void 0 ? void 0 : spinner.succeed(qrData === md ? "Multi device support for this project is EXPERIMENTAL. Some things may not work...." : "QR code scanned. Loading session...");
215
- return resolve(yield (0, exports.isInsideChat)(waPage).toPromise());
226
+ return resolve(yield isInsideChat(waPage).toPromise());
216
227
  }
217
228
  if (!gotResult)
218
229
  this.grabAndEmit(qrData, waPage, config, spinner);
@@ -240,13 +251,17 @@ class QRManager {
240
251
  yield this.grabAndEmit(firstQr, waPage, config, spinner);
241
252
  });
242
253
  }
254
+ /**
255
+ * Wait 10 seconds for the qr element to show.
256
+ * If it doesn't show up within 10 seconds then assume the session is authed already or blocked therefore ignore and return promise
257
+ */
243
258
  waitFirstQr(waPage, config, spinner) {
244
259
  return __awaiter(this, void 0, void 0, function* () {
245
260
  const fqr = yield waPage.waitForFunction(`!!(${this.qrCheck})`, {
246
261
  polling: 500,
247
262
  timeout: 10000
248
263
  })
249
- .catch(e => false);
264
+ .catch(() => false);
250
265
  if (fqr)
251
266
  yield this.emitFirst(waPage, config, spinner);
252
267
  return;
@@ -45,12 +45,15 @@ const promise_1 = __importDefault(require("terminate/promise"));
45
45
  const logging_1 = require("../logging/logging");
46
46
  const tools_1 = require("../utils/tools");
47
47
  const auth_1 = require("./auth");
48
- let browser, wapiInjected = false, wapiAttempts = 1;
48
+ const script_preloader_1 = require("./script_preloader");
49
+ const patch_manager_1 = require("./patch_manager");
50
+ let browser, wapiInjected = false, dumbCache = undefined, wapiAttempts = 1;
49
51
  exports.BROWSER_START_TS = 0;
50
52
  function initPage(sessionId, config, customUserAgent, spinner, _page, skipAuth) {
51
53
  var _a, _b, _c, _d, _e;
52
54
  return __awaiter(this, void 0, void 0, function* () {
53
55
  const setupPromises = [];
56
+ script_preloader_1.scriptLoader.loadScripts();
54
57
  if ((config === null || config === void 0 ? void 0 : config.resizable) === undefined || !(config === null || config === void 0 ? void 0 : config.resizable) == false)
55
58
  config.defaultViewport = null;
56
59
  if (config === null || config === void 0 ? void 0 : config.useStealth) {
@@ -65,7 +68,28 @@ function initPage(sessionId, config, customUserAgent, spinner, _page, skipAuth)
65
68
  spinner === null || spinner === void 0 ? void 0 : spinner.info(`Browser launched: ${((0, tools_1.now)() - startBrowser).toFixed(0)}ms`);
66
69
  waPage = yield getWAPage(browser);
67
70
  }
71
+ //@ts-ignore
72
+ waPage._client.send('Network.setBypassServiceWorker', { bypass: true });
68
73
  const postBrowserLaunchTs = (0, tools_1.now)();
74
+ waPage.on("framenavigated", (frame) => __awaiter(this, void 0, void 0, function* () {
75
+ try {
76
+ const frameNavPromises = [];
77
+ const content = yield frame.content();
78
+ const webpPackKey = (((content.match(/self.(?:.*)=self.*\|\|\[\]/g) || [])[0] || "").match(/self.*\w?=/g) || [""])[0].replace("=", "").replace("self.", "") || false;
79
+ logging_1.log.info(`FRAME NAV, ${frame.url()}, ${webpPackKey}`);
80
+ if (webpPackKey) {
81
+ frameNavPromises.push(injectApi(waPage, spinner, true));
82
+ frameNavPromises.push(auth_1.qrManager.waitFirstQr(waPage, config, spinner));
83
+ }
84
+ if (frame.url().includes('post_logout=1')) {
85
+ console.log("Session most likely logged out");
86
+ }
87
+ yield Promise.all(frameNavPromises);
88
+ }
89
+ catch (error) {
90
+ logging_1.log.error('framenaverr', error);
91
+ }
92
+ }));
69
93
  spinner === null || spinner === void 0 ? void 0 : spinner.info('Setting Up Page');
70
94
  if (config === null || config === void 0 ? void 0 : config.proxyServerCredentials) {
71
95
  yield waPage.authenticate(config.proxyServerCredentials);
@@ -105,10 +129,29 @@ function initPage(sessionId, config, customUserAgent, spinner, _page, skipAuth)
105
129
  if (proxyAddr) {
106
130
  proxy = (yield Promise.resolve().then(() => __importStar(require('puppeteer-page-proxy')))).default;
107
131
  }
108
- if (interceptAuthentication || proxyAddr || blockCrashLogs) {
132
+ if (interceptAuthentication || proxyAddr || blockCrashLogs || true) {
109
133
  yield waPage.setRequestInterception(true);
134
+ waPage.on('response', (response) => __awaiter(this, void 0, void 0, function* () {
135
+ if (response.request().url() == "https://web.whatsapp.com/") {
136
+ const t = yield response.text();
137
+ if (t.includes(`class="no-js"`) && t.includes(`self.`) && !dumbCache) {
138
+ //this is a valid response, save it for later
139
+ dumbCache = t;
140
+ logging_1.log.info("saving valid page to dumb cache");
141
+ }
142
+ }
143
+ }));
110
144
  const authCompleteEv = new events_1.EvEmitter(sessionId, 'AUTH');
111
145
  waPage.on('request', (request) => __awaiter(this, void 0, void 0, function* () {
146
+ //local refresh cache:
147
+ if (request.url() === "https://web.whatsapp.com/" && dumbCache) {
148
+ //if the dumbCache isn't set and this response includes
149
+ logging_1.log.info("reviving page from dumb cache");
150
+ return yield request.respond({
151
+ status: 200,
152
+ body: dumbCache
153
+ });
154
+ }
112
155
  if (interceptAuthentication &&
113
156
  request.url().includes('_priority_components') &&
114
157
  !quickAuthed) {
@@ -184,7 +227,6 @@ function initPage(sessionId, config, customUserAgent, spinner, _page, skipAuth)
184
227
  //try twice
185
228
  const WEB_START_TS = new Date().getTime();
186
229
  const webRes = yield waPage.goto(puppeteer_config_1.puppeteerConfig.WAUrl);
187
- Promise.all([injectApi(waPage, spinner), auth_1.qrManager.waitFirstQr(waPage, config, spinner)]);
188
230
  const WEB_END_TS = new Date().getTime();
189
231
  if (webRes == null) {
190
232
  spinner === null || spinner === void 0 ? void 0 : spinner.info(`Page loaded but something may have gone wrong: ${WEB_END_TS - WEB_START_TS}ms`);
@@ -262,12 +304,15 @@ const getSessionDataFilePath = (sessionId, config) => {
262
304
  return false;
263
305
  };
264
306
  exports.getSessionDataFilePath = getSessionDataFilePath;
265
- const addScript = (page, js) => page.addScriptTag({
266
- path: require.resolve(path.join(__dirname, '../lib', js))
267
- });
307
+ const addScript = (page, js) => __awaiter(void 0, void 0, void 0, function* () { return page.evaluate(yield script_preloader_1.scriptLoader.getScript(js)); });
268
308
  exports.addScript = addScript;
309
+ // (page: Page, js : string) : Promise<unknown> => page.addScriptTag({
310
+ // path: require.resolve(path.join(__dirname, '../lib', js))
311
+ // })
269
312
  function injectPreApiScripts(page, spinner) {
270
313
  return __awaiter(this, void 0, void 0, function* () {
314
+ if (yield page.evaluate("!['jsSHA','axios', 'QRCode', 'Base64', 'objectHash'].find(x=>!window[x])"))
315
+ return;
271
316
  const t1 = yield (0, tools_1.timePromise)(() => Promise.all([
272
317
  'axios.min.js',
273
318
  'jsSha.min.js',
@@ -282,17 +327,33 @@ function injectPreApiScripts(page, spinner) {
282
327
  exports.injectPreApiScripts = injectPreApiScripts;
283
328
  function injectWapi(page, spinner, force = false) {
284
329
  return __awaiter(this, void 0, void 0, function* () {
330
+ const bruteInjectionAttempts = 1;
331
+ yield (0, patch_manager_1.earlyInjectionCheck)(page);
332
+ const check = `window.WAPI && window.Store ? true : false`;
333
+ const initCheck = yield page.evaluate(check);
334
+ if (initCheck)
335
+ return;
336
+ logging_1.log.info(`WAPI CHECK: ${initCheck}`);
337
+ if (!check)
338
+ force = true;
285
339
  if (wapiInjected && !force)
286
340
  return page;
287
- const check = `window.WAPI && window.Store ? true : false`;
288
- const wapi = yield (0, tools_1.timePromise)(() => (0, exports.addScript)(page, 'wapi.js'));
289
- spinner === null || spinner === void 0 ? void 0 : spinner.info(`WAPI inject: ${wapi}ms`);
341
+ const multiScriptInjectPromiseArr = Array(bruteInjectionAttempts).fill("wapi.js").map((_s) => (0, exports.addScript)(page, _s));
342
+ try {
343
+ const wapi = yield (0, tools_1.timePromise)(() => Promise.all(multiScriptInjectPromiseArr));
344
+ spinner === null || spinner === void 0 ? void 0 : spinner.info(`WAPI inject: ${wapi}ms`);
345
+ }
346
+ catch (error) {
347
+ logging_1.log.error("injectWapi ~ error", error.message);
348
+ //one of the injection attempts failed.
349
+ return yield injectWapi(page, spinner, force);
350
+ }
290
351
  spinner === null || spinner === void 0 ? void 0 : spinner.info("Checking session integrity");
291
352
  wapiAttempts++;
292
- wapiInjected = !!(yield page.waitForFunction(check, { timeout: 3000, polling: 200 }).catch(e => false));
353
+ wapiInjected = !!(yield page.waitForFunction(check, { timeout: 3000, polling: 50 }).catch(e => false));
293
354
  if (!wapiInjected) {
294
355
  spinner === null || spinner === void 0 ? void 0 : spinner.info(`Session integrity check failed, trying again... ${wapiAttempts}`);
295
- return yield injectWapi(page, spinner);
356
+ return yield injectWapi(page, spinner, true);
296
357
  }
297
358
  spinner === null || spinner === void 0 ? void 0 : spinner.info("Session integrity check passed");
298
359
  return page;
@@ -164,6 +164,8 @@ function getLicense(config, me, debugInfo, spinner) {
164
164
  exports.getLicense = getLicense;
165
165
  function earlyInjectionCheck(page) {
166
166
  return __awaiter(this, void 0, void 0, function* () {
167
+ //@ts-ignore
168
+ yield page.waitForFunction(() => Object.entries(window).filter(([, o]) => o && o.push && (o.push != [].push))[0] ? true : false, { timeout: 10, polling: 500 }).catch(() => { });
167
169
  //@ts-ignore
168
170
  return yield page.evaluate(() => { if (window.webpackChunkwhatsapp_web_client) {
169
171
  window.webpackChunkbuild = window.webpackChunkwhatsapp_web_client;
@@ -172,7 +174,7 @@ function earlyInjectionCheck(page) {
172
174
  (function () { const f = Object.entries(window).filter(([, o]) => o && o.push && (o.push != [].push)); if (f[0]) {
173
175
  window.webpackChunkbuild = window[f[0][0]];
174
176
  } })();
175
- } return (typeof webpackChunkbuild !== "undefined"); });
177
+ } return (typeof window.webpackChunkbuild !== "undefined"); });
176
178
  });
177
179
  }
178
180
  exports.earlyInjectionCheck = earlyInjectionCheck;
@@ -0,0 +1,17 @@
1
+ export declare class ScriptLoader {
2
+ scripts: string[];
3
+ contentRegistry: {
4
+ [key: string]: string;
5
+ };
6
+ constructor();
7
+ loadScripts(): Promise<{
8
+ [key: string]: string;
9
+ }>;
10
+ getScript(scriptName: string): Promise<string>;
11
+ flush(): void;
12
+ getScripts(): {
13
+ [key: string]: string;
14
+ };
15
+ }
16
+ declare const scriptLoader: ScriptLoader;
17
+ export { scriptLoader };
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.scriptLoader = exports.ScriptLoader = void 0;
32
+ const path = __importStar(require("path"));
33
+ const fs = __importStar(require("fs"));
34
+ const logging_1 = require("../logging/logging");
35
+ const read = (_path) => new Promise((resolve, reject) => {
36
+ fs.readFile(require.resolve(path.join(__dirname, '../lib', _path)), 'utf8', (err, file) => {
37
+ if (err)
38
+ reject(err);
39
+ resolve(file);
40
+ });
41
+ });
42
+ class ScriptLoader {
43
+ constructor() {
44
+ this.scripts = [
45
+ // stage 1
46
+ 'axios.min.js',
47
+ 'jsSha.min.js',
48
+ 'qr.min.js',
49
+ 'base64.js',
50
+ 'hash.js',
51
+ //stage 2
52
+ 'wapi.js',
53
+ //stage 3,
54
+ 'launch.js'
55
+ ];
56
+ this.contentRegistry = {};
57
+ this.contentRegistry = {};
58
+ }
59
+ loadScripts() {
60
+ return __awaiter(this, void 0, void 0, function* () {
61
+ yield Promise.all(this.scripts.map(this.getScript.bind(this)));
62
+ return this.contentRegistry;
63
+ });
64
+ }
65
+ getScript(scriptName) {
66
+ return __awaiter(this, void 0, void 0, function* () {
67
+ if (!this.contentRegistry[scriptName]) {
68
+ this.contentRegistry[scriptName] = yield read(scriptName);
69
+ logging_1.log.info("SCRIPT READY: " + scriptName);
70
+ }
71
+ return this.contentRegistry[scriptName];
72
+ });
73
+ }
74
+ flush() {
75
+ this.contentRegistry = {};
76
+ }
77
+ getScripts() {
78
+ return this.contentRegistry;
79
+ }
80
+ }
81
+ exports.ScriptLoader = ScriptLoader;
82
+ const scriptLoader = new ScriptLoader();
83
+ exports.scriptLoader = scriptLoader;
package/dist/lib/wapi.js CHANGED
@@ -82,7 +82,7 @@ if (!window.Store||!window.Store.Msg) {
82
82
  window.Store[needObj.id] = needObj.foundedModule;
83
83
  }
84
84
  });
85
- window.Store.Chat.modelClass.prototype.sendMessage = function (e) {
85
+ if(window.Store.Chat) window.Store.Chat.modelClass.prototype.sendMessage = function (e) {
86
86
  window.Store.SendTextMsgToChat(this, ...arguments);
87
87
  }
88
88
  return window.Store;
@@ -833,7 +833,7 @@ window.WAPI.markAsUnread = async function (id) {
833
833
  return false;
834
834
  };
835
835
 
836
- function isChatMessage(message) {
836
+ window.isChatMessage = function (message) {
837
837
  if (message.isSentByMe) {
838
838
  return false;
839
839
  }
@@ -1314,7 +1314,7 @@ window.WAPI.onParticipantsChanged = function (groupId, callback) {
1314
1314
  * @param callback - function - Callback function to be called when a message acknowledgement changes. The callback returns 3 variables
1315
1315
  * @returns {boolean}
1316
1316
  */
1317
- var groupParticpiantsEvents = {};
1317
+ window.groupParticpiantsEvents = {};
1318
1318
  window.WAPI._onParticipantsChanged = function (groupId, callback) {
1319
1319
  const subtypeEvents = [
1320
1320
  "invite" ,
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@open-wa/wa-automate",
3
- "version": "4.30.13",
4
- "licenseCheckUrl": "https://openwa.dev/license-check",
5
- "brokenMethodReportUrl": "https://openwa.dev/report-bm",
3
+ "version": "4.31.0",
4
+ "licenseCheckUrl": "https://funcs.openwa.dev/license-check",
5
+ "brokenMethodReportUrl": "https://funcs.openwa.dev/report-bm",
6
6
  "patches": "https://cdn.openwa.dev/patches.json",
7
7
  "stickerUrl": "https://sticker-api.openwa.dev",
8
8
  "description": " 💬 🤖 The most reliable NodeJS whatsapp library for chatbots with advanced features.",