{"_id":"webmaxsocket","_rev":"16-899f6705119937d5b6671195eb0001de","name":"webmaxsocket","dist-tags":{"latest":"1.2.7"},"versions":{"1.0.0":{"name":"webmaxsocket","version":"1.0.0","keywords":["max","messenger","max-messenger","oneme","api","userbot","selfbot","websocket","qr-code","qr-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.0.0","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"b74a81648d4c052e1f1acdde7d36ac9655c1fe0e","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.0.0.tgz","fileCount":13,"integrity":"sha512-YDoJX0GX7w8s1sP1QjKr8CUOM5jKxsKZr9vwjq5sJ8B8NPlBjXLfvAMVLmNSU9/DCuPyU+2VqEBPkPkdUku5dQ==","signatures":[{"sig":"MEYCIQCojYZvK5smEhKGKKAPQJt4QUkftfqPdeGb0HIieOLKxAIhAPzu9IS39RtycC/KbgOajlT5xdWZ1Ld7N9APYUZClJgV","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":58420},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"9e5c53d7685de47b0b1bae726b70fcc3000df845","scripts":{"start":"node example.js","example":"node example.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger with QR code authentication","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","uuid":"^9.0.0","qrcode-terminal":"^0.12.0"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.0.0_1769867123835_0.10877409931386506","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"webmaxsocket","version":"1.1.0","keywords":["max","messenger","max-messenger","oneme","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.1.0","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"3e398a7462603605cc26e5df8f1ec3fe294d640e","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.1.0.tgz","fileCount":18,"integrity":"sha512-qbDsruZk9p0qgf0YmWW3j0SA7k89/IFbByaiJzmsSJu0br0XIVCrQ0sCJJ/nrXVeDOf4GNnaw1e2OjE9MmutQw==","signatures":[{"sig":"MEUCIE8b2g6Ktq2dCtRzIy7ztvDuRqSVvpMUPIfgMyIxiG1eAiEAqs+JdlW4guhXem0RWe305G/hG3+dJH63nRRu9sf9nls=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":106479},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"cbb4f1ce379ffd3d119c7cbd9eed93938ff216ac","scripts":{"start":"node example.js","example":"node example.js","example:ios":"node example-ios.js","example:sms":"node example-sms.js","example:token":"node example-token.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger with QR code and token authentication","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","lz4":"^0.6.5","uuid":"^9.0.0","qrcode-terminal":"^0.12.0","@msgpack/msgpack":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{},"optionalDependencies":{"lz4":"^0.6.5"},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.1.0_1774513838349_0.48915861568029917","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"webmaxsocket","version":"1.1.1","keywords":["max","messenger","max-messenger","oneme","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.1.1","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"dd6edc6966e518a65f32dd4a9a3e680069a3198f","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.1.1.tgz","fileCount":18,"integrity":"sha512-GgLZl6Ce8ELzr3nDXP/wwkFdzJV/Q1ZTekLVeWMpUzbD+Myb4qa1rNvuv/17bxnnLp6c0iztU4tP+AwTwX85Ww==","signatures":[{"sig":"MEYCIQDs+h3wGp3F1tf1eVR5Eo42J9/emXxBHuXvzPBsuyb65gIhAJjgz4JNRYqEDwF5gXAyhldnZCUG0XdRQPCbDXvxDXd3","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":118720},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"0f052f4a433737d8977f7ab7230d1190ebe6a863","scripts":{"start":"node example.js","example":"node example.js","example:ios":"node example-ios.js","example:sms":"node example-sms.js","example:token":"node example-token.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger with QR code and token authentication","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","lz4":"^0.6.5","uuid":"^9.0.0","qrcode-terminal":"^0.12.0","@msgpack/msgpack":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{},"optionalDependencies":{"lz4":"^0.6.5"},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.1.1_1774515381150_0.5873311499005551","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"webmaxsocket","version":"1.1.2","keywords":["max","messenger","max-messenger","oneme","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.1.2","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"c355e3fb156423faaaa10643f53dd88ab88fa223","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.1.2.tgz","fileCount":20,"integrity":"sha512-br3bjJOlKp1uyoMtZ8LW6HaCDYaa/Ov871y9GxO5ZxVy59UwJcvXNLlDnvQeePzhE0LCAXnztS12qTLm2bIaZQ==","signatures":[{"sig":"MEYCIQCtLxf+X7UoorCvwRFPAGsVVZZQQO2zd5c9YysqkftWAgIhALvDQpUic/BpmjOK2V0+aLmgUFwkp+6hxPfL1CjZgIxa","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":135845},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"0ce6f9bd978681ad6c857a7e20272d03d0665507","scripts":{"start":"node example.js","example":"node example.js","example:ios":"node example-ios.js","example:sms":"node example-sms.js","example:token":"node example-token.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger with QR code and token authentication","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","lz4":"^0.6.5","uuid":"^9.0.0","qrcode-terminal":"^0.12.0","@msgpack/msgpack":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{},"optionalDependencies":{"lz4":"^0.6.5"},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.1.2_1774517068320_0.8204817933146393","host":"s3://npm-registry-packages-npm-production"}},"1.1.3":{"name":"webmaxsocket","version":"1.1.3","keywords":["max","messenger","max-messenger","oneme","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.1.3","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"d9994d73c6b0e5ff99455b91b636bae1953665fa","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.1.3.tgz","fileCount":20,"integrity":"sha512-qbSUkWUd45F+mukL1OCa1moT7NLKRe6y/v07wSnZqLUsOE49U/lKRFbZKFzAPqpUNXLNt8SD6MYOPlT067wKww==","signatures":[{"sig":"MEYCIQDyTS49EPqCt1RqBX2C/hocURX2tnm24dHzJSPJ6lnVIgIhAKknFRaEvbKWFyX65Rg0nU6ZLoLMwAqaPkK7SoeFbiuH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":137250},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"5308e2fe5c0a0854b3fbaa34fc0b5102aee5150f","scripts":{"start":"node example.js","example":"node example.js","example:ios":"node example-ios.js","example:sms":"node example-sms.js","example:token":"node example-token.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger with QR code and token authentication","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","lz4":"^0.6.5","uuid":"^9.0.0","qrcode-terminal":"^0.12.0","@msgpack/msgpack":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{},"optionalDependencies":{"lz4":"^0.6.5"},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.1.3_1774518790443_0.15277486732639556","host":"s3://npm-registry-packages-npm-production"}},"1.1.4":{"name":"webmaxsocket","version":"1.1.4","keywords":["max","messenger","max-messenger","oneme","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.1.4","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"da060cc2bbd885f2ace237be08076ac93177d4a4","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.1.4.tgz","fileCount":21,"integrity":"sha512-Ps1syviBdEUYq47jUORtfeqkdw9BjOy01fN9i1lqr5hO8635a1IahP3lHVFHErAiNajGVVEEayi/gSe1FxFt5Q==","signatures":[{"sig":"MEYCIQCUdMyTpqV3LBoCuizvsGDoT+SGd+afAp70jNcHwRQ5pAIhALQMM3uDPpuCy0RKA1i8EMQpPVISaSM4hn/L1J/KCpNa","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":170199},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"0a3d5015e5cdf2d688935288016fd880f02ecaa9","scripts":{"start":"node example.js","example":"node example.js","example:ios":"node example-ios.js","example:sms":"node example-sms.js","example:token":"node example-token.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger with QR code and token authentication","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","lz4":"^0.6.5","uuid":"^9.0.0","qrcode-terminal":"^0.12.0","@msgpack/msgpack":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{},"optionalDependencies":{"lz4":"^0.6.5"},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.1.4_1774525577063_0.9827824138393992","host":"s3://npm-registry-packages-npm-production"}},"1.1.5":{"name":"webmaxsocket","version":"1.1.5","keywords":["max","messenger","max-messenger","oneme","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.1.5","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"a074d69f148c0106aa2e54fc3e5d680d6c8604c6","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.1.5.tgz","fileCount":22,"integrity":"sha512-xdolI+zwaGrf7PvQU6lYQvhMWBsJsoV+wfxO6+3LBnXdXl0nV78OfsrfTG3cfGyLYnPd7y8zPK7CzS1Qqzcmlw==","signatures":[{"sig":"MEUCIDKHxqQfa4ys2dskmgX2ms34CoX6r0dEzaQe0hmLD4BEAiEAwftbiyMaIW+IwEIua6vfB1XC3mtM/R9Ii1NFsiITeQk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":191786},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"9008a694fd43aff12bcb189fcac937d9b9570367","scripts":{"start":"node example.js","example":"node example.js","example:ios":"node example-ios.js","example:sms":"node example-sms.js","example:token":"node example-token.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger with QR code and token authentication","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","lz4":"^0.6.5","uuid":"^9.0.0","qrcode-terminal":"^0.12.0","@msgpack/msgpack":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{},"optionalDependencies":{"lz4":"^0.6.5"},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.1.5_1775110534045_0.5883305412297419","host":"s3://npm-registry-packages-npm-production"}},"1.1.6":{"name":"webmaxsocket","version":"1.1.6","keywords":["max","messenger","max-messenger","oneme","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.1.6","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"ab2c05173eb281d7740ec40069de869976b0bc4a","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.1.6.tgz","fileCount":22,"integrity":"sha512-IXAFow7e+rqwVkOWryS7jXBWI5qPbauyH02BxZqfEC/lt8qlhCH90Bih6Aj/1Z49tts9huhJffSJHz/z4Is/Mw==","signatures":[{"sig":"MEUCIQCgABjUJQya2uPUmqfcaCj1SwrvDvIpcmsjGXZnzLiPBwIgW5seflr6J4GcfJDlcGA/Zn2QS2zVSIewXOkROaeNv3k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":198820},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"ecb75690854445d9b49e1b1805c81a5a9fd2be0e","scripts":{"start":"node example.js","example":"node example.js","example:ios":"node example-ios.js","example:sms":"node example-sms.js","example:token":"node example-token.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger with QR code and token authentication","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","uuid":"^9.0.0","lz4js":"^0.2.0","qrcode-terminal":"^0.12.0","@msgpack/msgpack":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{},"optionalDependencies":{"lz4":"^0.6.5"},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.1.6_1775390431825_0.8673945848805522","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"webmaxsocket","version":"1.2.0","keywords":["max","messenger","max-messenger","oneme","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.2.0","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"7468fbab87cb0c43f925f7a56cd77543ceb77253","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.2.0.tgz","fileCount":22,"integrity":"sha512-Z2NeRb+CpbUlTwW6E2zFzYdG2LRfcjd9RpvNL7nTUBt/go8EzC0FT0Gj/vzom+exgdtgQZ8Whr/1GvyAOLCeIw==","signatures":[{"sig":"MEUCIQDU5shf4WUceK58KAyU4nhlAP3CLvHMWL+40iKz2ZeajgIgA1IhjSNuOjnjxahW5Feem5UmM4AZK999vrrk1rEucEA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":208119},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"eda39b947e54957d1a0a1794c90a6bb6e62e63d9","scripts":{"start":"node example.js","example":"node example.js","example:ios":"node example-ios.js","example:sms":"node example-sms.js","example:token":"node example-token.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger: QR, token, SMS auth and optional 2FA password (TCP)","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","uuid":"^9.0.0","lz4js":"^0.2.0","qrcode-terminal":"^0.12.0","@msgpack/msgpack":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{},"optionalDependencies":{"lz4":"^0.6.5"},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.2.0_1775468697724_0.9679515847509967","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"webmaxsocket","version":"1.2.1","keywords":["max","messenger","max-messenger","oneme","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.2.1","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"8eaca7e6d0b158f6e9ba2204c269bf737a1ec5dd","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.2.1.tgz","fileCount":23,"integrity":"sha512-ux5N8cryD9xUfNjUvoKXhWNEDgoD/exb2sColk2BM2CFjSCeuk28jnje0fMPuVrBzzu2upxY/QUW4ePKVXRkrw==","signatures":[{"sig":"MEUCIBvdB8OJGN1xmu1eoD9CtCcGZu+ubxdcNizvYA1yZyQiAiEA4IBM6kwr37v/8mN8pFl/6awm97b6wqSJLHvj+DbKebo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":216543},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"f13e192ac1af4240ef7c0f8fe35027d181676cfc","scripts":{"start":"node example.js","example":"node example.js","example:ios":"node example-ios.js","example:sms":"node example-sms.js","example:token":"node example-token.js","example:sessions-2fa":"node example-sessions-2fa.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger: QR, token, SMS auth, 2FA, device sessions (TCP)","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","uuid":"^9.0.0","lz4js":"^0.2.0","qrcode-terminal":"^0.12.0","@msgpack/msgpack":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{},"optionalDependencies":{"lz4":"^0.6.5"},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.2.1_1775469258234_0.5893493008579962","host":"s3://npm-registry-packages-npm-production"}},"1.2.2":{"name":"webmaxsocket","version":"1.2.2","keywords":["max","messenger","max-messenger","oneme","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.2.2","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"2bb8c7186a6163ff7d1d6c6e923c6469aea66f89","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.2.2.tgz","fileCount":23,"integrity":"sha512-P062x6+TtSKYmnOrjLwtIho69XgWIx85FNUrFbZuli71DRduNw1inX/VAxMiSzqensv82YhAkkttOHFIM7PtkA==","signatures":[{"sig":"MEUCICdFpUY7bpEEvv0gEuw6DnjiYXdQBp1niFQYZiVK4rl/AiEAw1c+cufD7RpiMTejDBAWNOoG1o/lth0/ntu+vcEJFZY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":223025},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"53b918ec4e59980f6af3e62e171f54fdded7d6e6","scripts":{"start":"node example.js","example":"node example.js","example:ios":"node example-ios.js","example:sms":"node example-sms.js","example:token":"node example-token.js","example:sessions-2fa":"node example-sessions-2fa.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger: QR, token, SMS auth, 2FA, device sessions (TCP)","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","uuid":"^9.0.0","lz4js":"^0.2.0","qrcode-terminal":"^0.12.0","@msgpack/msgpack":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{},"optionalDependencies":{"lz4":"^0.6.5"},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.2.2_1775592590156_0.6462778205717372","host":"s3://npm-registry-packages-npm-production"}},"1.2.3":{"name":"webmaxsocket","version":"1.2.3","keywords":["max","messenger","max-messenger","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.2.3","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"52608c434b970a6dac8a04d12b256a224a7dbda5","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.2.3.tgz","fileCount":23,"integrity":"sha512-Vw0q4nwjaWPbNcUgJywfhEGjB0EAqRo5PDBitXlhVNRyncAkix8nnqITlrp2hkhGScYYPdhl8Mtno/FFZ9lMoA==","signatures":[{"sig":"MEUCIHWSw+fJH6GNTaNjxOZqZIg5toafi0KzkVKDSustJfIhAiEA6v6FfqyfFtg9bd7lcpEFeKfVDiq3Sc3IQnwkrV4PL1I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":239610},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"c254465093ad811b2fc71af781c1246471df5679","scripts":{"start":"node example.js","example":"node example.js","example:ios":"node example-ios.js","example:sms":"node example-sms.js","example:token":"node example-token.js","example:sessions-2fa":"node example-sessions-2fa.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger: QR, token, SMS auth, 2FA, device sessions (TCP)","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","uuid":"^9.0.0","lz4js":"^0.2.0","qrcode-terminal":"^0.12.0","@msgpack/msgpack":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{},"optionalDependencies":{"lz4":"^0.6.5"},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.2.3_1775853204922_0.18532218110480358","host":"s3://npm-registry-packages-npm-production"}},"1.2.4":{"name":"webmaxsocket","version":"1.2.4","keywords":["max","messenger","max-messenger","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.2.4","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"fe126c1ffe7cb288393c83b86868609f04fd69ae","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.2.4.tgz","fileCount":22,"integrity":"sha512-zUj8YYgW+i2Rwmhe4w8C0dp9OemBgnL/h1blLKdlQJtDx7N3WB9qSdLWZMy+lUHd3O2Oa0I/f7EpXRwGZag1ig==","signatures":[{"sig":"MEQCIHM4OLyfxiDxXADM8mZHtQuLny1EFjId8ayAaxqDSwNjAiBhtB786EW6xitlt9bfS6CHJ3FtsFZ/LimO+rDAqY83oQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":231381},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"347f7ba0c460168c0a98116fb85a1b4d5bba7c19","scripts":{"start":"node example.js","example":"node example.js","example:sms":"node example-sms.js","example:token":"node example-token.js","example:sessions-2fa":"node example-sessions-2fa.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger: QR, token, SMS auth, 2FA, device sessions (TCP)","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","uuid":"^9.0.0","lz4js":"^0.2.0","qrcode-terminal":"^0.12.0","@msgpack/msgpack":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{},"optionalDependencies":{"lz4":"^0.6.5"},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.2.4_1777401277076_0.0003955159908666239","host":"s3://npm-registry-packages-npm-production"}},"1.2.5":{"name":"webmaxsocket","version":"1.2.5","keywords":["max","messenger","max-messenger","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.2.5","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"debd04567068e3881a60cf62ecedf60e1a17118d","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.2.5.tgz","fileCount":23,"integrity":"sha512-nDsLUEKYxa3+O5T2IqyczjN6/m2lE5pwFoPUyT1XHfTbHjcS5h05Gq02CX0AfBjwFJ5RDOP9wvUqnW0yOWDMeQ==","signatures":[{"sig":"MEUCIFiHOkj7TpQPaA6BZAM0MTh++8RyfUF1vZTs+d4st6CzAiEAqWtOh+oFLL7kBeleUjkXSotXLmSt2oLaF4eVfxusX4E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":245618},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"18be28763e67838b0fb61ae4483a73c423225c2f","scripts":{"start":"node example.js","example":"node example.js","example:sms":"node example-sms.js","example:token":"node example-token.js","example:sessions-2fa":"node example-sessions-2fa.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger: QR, token, SMS auth, 2FA, device sessions (TCP)","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","uuid":"^9.0.0","lz4js":"^0.2.0","qrcode-terminal":"^0.12.0","@msgpack/msgpack":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{},"optionalDependencies":{"lz4":"^0.6.5"},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.2.5_1778135923200_0.6081191680928026","host":"s3://npm-registry-packages-npm-production"}},"1.2.6":{"name":"webmaxsocket","version":"1.2.6","keywords":["max","messenger","max-messenger","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","_id":"webmaxsocket@1.2.6","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"homepage":"https://github.com/Tellarion/webmaxsocket#readme","bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"dist":{"shasum":"a07f8cc25b9900baf49b31426491d44ed43e793f","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.2.6.tgz","fileCount":24,"integrity":"sha512-K0blhTS+xf/BeSKc9iPfCcAgjmEpWqWmMps8tLh3cibw/YKARfl6FThgOFWD4RKsqT5uly3HCpMLNAyfUt7k+A==","signatures":[{"sig":"MEUCIDv30aHWRuCdihuTC1ykdqSpuXyFOBMSuiaePWa5z5jhAiEAv84f0iJnjoe2LPtGzPfg6/+HTZ50zZIiWwFz1eBaY+0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":258720},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"8c1608a1a3687ff9de1ad0d71004cbaeecc71685","scripts":{"start":"node example.js","example":"node example.js","example:sms":"node example-sms.js","example:token":"node example-token.js","example:download":"node example-download-files.js","example:sessions-2fa":"node example-sessions-2fa.js"},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"repository":{"url":"git+https://github.com/Tellarion/webmaxsocket.git","type":"git"},"_npmVersion":"11.6.2","description":"Node.js client for Max Messenger: QR, token, SMS auth, 2FA, device sessions (TCP)","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.0","uuid":"^9.0.0","lz4js":"^0.2.0","qrcode-terminal":"^0.12.0","@msgpack/msgpack":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{},"optionalDependencies":{"lz4":"^0.6.5"},"_npmOperationalInternal":{"tmp":"tmp/webmaxsocket_1.2.6_1778787605406_0.3889933306344697","host":"s3://npm-registry-packages-npm-production"}},"1.2.7":{"name":"webmaxsocket","version":"1.2.7","description":"Node.js client for Max Messenger: QR, token, SMS auth, 2FA, device sessions (TCP)","main":"index.js","scripts":{"start":"node example.js","example":"node example.js","example:token":"node example-token.js","example:sms":"node example-sms.js","example:sessions-2fa":"node example-sessions-2fa.js","example:download":"node example-download-files.js"},"keywords":["max","messenger","max-messenger","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"author":{"name":"Tellarion"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/Tellarion/webmaxsocket.git"},"bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"homepage":"https://github.com/Tellarion/webmaxsocket#readme","dependencies":{"@msgpack/msgpack":"^3.1.3","lz4js":"^0.2.0","qrcode-terminal":"^0.12.0","uuid":"^9.0.0","ws":"^8.18.0"},"optionalDependencies":{"lz4":"^0.6.5"},"devDependencies":{},"engines":{"node":">=14.0.0"},"gitHead":"f060f50aad6db5ea2483a185f3451768ed6742ad","_id":"webmaxsocket@1.2.7","_nodeVersion":"24.16.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-HCQbpdkRlfMMVHHS6hWvHR66pb/wCgOjcqu4Vww7XlXwcrSbKiCFlyF53RmRJdrWefOBLTvB1YCVfOV7M1Amnw==","shasum":"a6d174bd1a505c00847d70a0fcbfc64cfef29b82","tarball":"https://registry.npmjs.org/webmaxsocket/-/webmaxsocket-1.2.7.tgz","fileCount":24,"unpackedSize":264597,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAgF4JtUERd+TiWNtZ4xw7X/kSMzw2MT9jKIYUbAk8VXAiEAzwj+UH85P/Srf6V8+XLMIBB6L5PQiNus1TJsEN8QsnY="}]},"_npmUser":{"name":"tellarion","email":"im@tellarion.dev"},"directories":{},"maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/webmaxsocket_1.2.7_1785915566683_0.3666033021914661"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-31T13:45:23.834Z","modified":"2026-08-05T07:39:27.081Z","1.0.0":"2026-01-31T13:45:23.981Z","1.1.0":"2026-03-26T08:30:38.486Z","1.1.1":"2026-03-26T08:56:21.279Z","1.1.2":"2026-03-26T09:24:28.462Z","1.1.3":"2026-03-26T09:53:10.599Z","1.1.4":"2026-03-26T11:46:17.240Z","1.1.5":"2026-04-02T06:15:34.204Z","1.1.6":"2026-04-05T12:00:31.997Z","1.2.0":"2026-04-06T09:44:57.880Z","1.2.1":"2026-04-06T09:54:18.389Z","1.2.2":"2026-04-07T20:09:50.313Z","1.2.3":"2026-04-10T20:33:25.060Z","1.2.4":"2026-04-28T18:34:37.216Z","1.2.5":"2026-05-07T06:38:43.345Z","1.2.6":"2026-05-14T19:40:05.569Z","1.2.7":"2026-08-05T07:39:26.890Z"},"bugs":{"url":"https://github.com/Tellarion/webmaxsocket/issues"},"author":{"name":"Tellarion"},"license":"MIT","homepage":"https://github.com/Tellarion/webmaxsocket#readme","keywords":["max","messenger","max-messenger","api","userbot","selfbot","websocket","qr-code","qr-auth","token-auth","bot","nodejs","commonjs"],"repository":{"type":"git","url":"git+https://github.com/Tellarion/webmaxsocket.git"},"description":"Node.js client for Max Messenger: QR, token, SMS auth, 2FA, device sessions (TCP)","maintainers":[{"name":"tellarion","email":"im@tellarion.dev"}],"readme":"# WebMaxSocket - Node.js Client for Max Messenger\r\n\r\n## 📖 Описание / Description\r\n\r\n**WebMaxSocket** — async Node.js библиотека для работы с внутренним API мессенджера Max. Поддерживает **QR-код авторизацию**, **Token авторизацию**, **SMS-вход** с опциональным **2FA-паролем** (как в приложении Max), и работу через **WebSocket** (WEB) или **TCP Socket** (ANDROID).\r\n\r\n**Текущая версия пакета: 1.2.7**\r\n\r\nСводка всех методов: **[api.package.md](./api.package.md)**.\r\n\r\n### Журнал изменений (выдержка)\r\n\r\n#### 1.2.7\r\n\r\n- **Fingerprint 26.19.2 (6733):** актуальные `APP_VERSION` / `BUILD_NUMBER` (фикс «Приложение устарело» на SMS).\r\n- **`getUserByPhone` / `getUserIdByPhone`:** поиск пользователя по номеру (`CONTACT_INFO_BY_PHONE`).\r\n\r\n#### 1.2.6\r\n\r\n- **`client.lastSyncPayload`** — сохраняется последний успешный ответ **`LOGIN`/`sync()`** (в т.ч. массив `chats`). На **TCP** список **`getChats()`** иногда пустой, тогда чаты брать из **`lastSyncPayload.chats`**.\r\n- **Скачивание документов `FILE` без `baseUrl` в истории:** **`requestFileDownloadUrl({ chatId, messageId, fileId, fileName?, … })`** — сервер возвращает временный HTTPS-**`url`** для скачивания.\r\n- **`message.downloadAttachment()`** — для **`_type: FILE`** без URL сам вызывает **`requestFileDownloadUrl`** (нужны корректный **`chatId`** сообщения и **`messageId`**).\r\n- **`getHistory`**: в каждое сообщение подмешивается **`chatId`** из аргумента запроса (в сырых сообщениях его часто нет).\r\n- **`Message`**: корректно обрабатывается **`chatId === 0`** (например «Избранное к себе»).\r\n- **TCP + msgpack:** при наличии **`BigInt`** в исходящем payload включается **`useBigInt64`** при кодировании; входящие пакеты декодируются с **`useBigInt64`**, чтобы **`message.id`** и другие int64 не терялись (выше **`Number.MAX_SAFE_INTEGER`**).\r\n- **`downloadMedia`:** расширена карта MIME → расширение (`text/plain`, `application/pdf`, …).\r\n- Новый пример: **`example-download-files.js`** (история чата → папка `downloads/`).\r\n\r\n## ✨ Особенности / Features\r\n\r\n- ✅ **QR-код авторизация** / QR code authentication  \r\n- ✅ **QR для привязки устройства** (`showLinkDeviceQR`) после входа по SMS/TCP — тот же сценарий, что «Профиль → Устройства → Подключить устройство» в приложении\r\n- ✅ **Token авторизация** / Token authentication\r\n- ✅ **SMS + 2FA по паролю** (ANDROID): после кода из SMS при необходимости второй шаг `AUTH_LOGIN_CHECK_PASSWORD` (opcode `0x73`); сохранение пароля в сессии опционально (`saveTwofaPassword`)\r\n- ✅ **Два транспорта:** WebSocket (WEB) и TCP Socket (ANDROID)\r\n- ✅ **Автоматическое сохранение сессий** / Automatic session storage\r\n- ✅ **Ротация токена после `sync()`:** если сервер возвращает новый `token` в ответе `LOGIN`, он сохраняется в `sessions/*.json` (как при SMS/QR)\r\n- ✅ **Периодический `sync()`** (`sessionRefreshIntervalMs` / `autoSyncIntervalMs`) для продления сессии: на **TCP** после первого `LOGIN` каждый следующий `sync()` — **новое TLS и снова `LOGIN` (19)** (на сокете нельзя второй `LOGIN` подряд; **`SYNC` (21)** с TCP сервер не принимает — см. «Сессии»)\r\n- ✅ **Автовыбор транспорта** после QR-авторизации (переход на TCP)\r\n- ✅ **Отправка и получение сообщений** / Send and receive messages\r\n- ✅ **Загрузка медиа с диска:** `uploadPhoto`, `uploadVideo`, `uploadFile`, `uploadAudio` → `attachments` в `sendMessage` / `sendMessageChannel` / `reply`\r\n- ✅ **Скачивание вложений:** по **`baseUrl`/`url`** — `downloadUrlToTempFile`, `message.downloadAttachment()`; документы **`FILE`** без URL в истории — **`requestFileDownloadUrl()`**\r\n- ✅ **Группы и каналы:** создание, инвайты, админы, участники, ссылки, mute, подписка — см. раздел API\r\n- ✅ **Реакции, пины, настройки профиля и приватности, контакты / блокировка**\r\n- ✅ **Список устройств (сессий)** и **завершение других сеансов** (`getSessionsInfo`, `closeAllSessionsExceptCurrent`) — как «Профиль → Устройства» в Max\r\n- ✅ **Сведения о 2FA и установка пароля по trackId** (`getTwoFADetails`, `setTwoFAPassword`)\r\n- ✅ **Редактирование и удаление сообщений** / Edit and delete messages\r\n- ✅ **Event-driven архитектура** / Event-driven architecture\r\n- ✅ **Входящие звонки (TCP):** опкод **`NOTIF_INCOMING_CALL` (137)**, событие **`incoming_call`** / **`onIncomingCall`**, хелперы **`summarizeIncomingCall`** и др.\r\n- ✅ **Итог звонка в чате:** в **`NOTIF_MESSAGE`** приходит вложение `_type: \"CALL\"` (`hangupType`, `duration`, `conversationId`) — событие **`call_log`** / **`onCallLog`**, утилиты **`extractCallAttachesFromNotifPayload`**, **`formatCallLogLine`**\r\n- ✅ **Встроенный лог входящих** (`logIncoming`, `WEBMAX_DEBUG`, `WEBMAX_SILENT`) — JSON в консоль без ручных обработчиков\r\n- ✅ **TypeScript-ready** структура / TypeScript-ready structure\r\n\r\n## 📦 Установка / Installation\r\n\r\n```bash\r\nnpm install webmaxsocket\r\n```\r\n\r\n### Зависимости для Socket транспорта (ANDROID) / Socket transport dependencies\r\n\r\nОтветы сервера по TCP содержат полезную нагрузку в **LZ4**-блоках (поверх **msgpack**). Для распаковки используется **`lz4js`** — чистый JavaScript, **без node-gyp** и нативной сборки, в том числе на Windows без Visual Studio C++. Он входит в зависимости `webmaxsocket` и ставится вместе с пакетом. При необходимости можно доустановить вручную:\r\n\r\n```bash\r\nnpm install lz4js\r\n```\r\n\r\nДополнительно можно установить нативный модуль **`lz4`**, если в окружении доступна сборка C++:\r\n\r\n```bash\r\nnpm install lz4\r\n```\r\n\r\n**Примечание:** Для обычной QR-авторизации (WEB) дополнительные зависимости не нужны. Socket транспорт используется только после сохранения сессии или при явном указании `deviceType: 'ANDROID'`.\r\n\r\n## 📞 Входящие звонки (TCP / ANDROID)\r\n\r\nПри входящем вызове сервер шлёт **`NOTIF_INCOMING_CALL`** (**opcode 137**): `callerId`, `conversationId`, `type` (`AUDIO` / `VIDEO`), `vcp` (параметры медиа — не логируйте публично).\r\n\r\nПосле ответа / отбоя в том же диалоге часто приходит обычное **`NOTIF_MESSAGE`** с пустым текстом и вложением **`_type: \"CALL\"`**:\r\n\r\n| `hangupType` | `duration` | Наблюдаемый смысл |\r\n|--------------|------------|-------------------|\r\n| `REJECTED` | `0` | Дозвон не завершился разговором (отклонение, сброс до ответа и т.п.) |\r\n| `HUNGUP` | `> 0` | Был разговор, затем положили трубку (мс) |\r\n\r\nСвязать события одного звонка удобно по **`conversationId`**.\r\n\r\n**События `EventEmitter`:** `incoming_call` (payload как с сервера), `call_log` (`{ chatId, message, callAttaches, summaries }`).\r\n\r\n**Парные методы (как `onMessage`):** `onIncomingCall(handler)`, `onCallLog(handler)`.\r\n\r\n**Отклонение входящего:** экспериментальные методы **`rejectIncomingCall(payload)`** и **`hangupCall(conversationIdOrPayload, { reason? })`** вызывают OK API **`vchat.hangupConversation`** (`conversationId`, `reason`, `anonymToken?`). Для входящего дозвона используйте `reason: 'REJECTED'` (по умолчанию в `rejectIncomingCall`).\r\n\r\n**Утилиты:** `summarizeIncomingCall`, `extractCallAttachesFromNotifPayload`, `summarizeCallAttach`, `formatCallLogLine`, `isCallAttach`.\r\n\r\n```javascript\r\nconst {\r\n  WebMaxClient,\r\n  summarizeIncomingCall,\r\n  formatCallLogLine,\r\n} = require('webmaxsocket');\r\n\r\nasync function main() {\r\n  const client = new WebMaxClient({ name: 'sms_session', deviceType: 'ANDROID' });\r\n\r\n  client.onIncomingCall(async (payload) => {\r\n    console.log('Звонок:', summarizeIncomingCall(payload));\r\n\r\n    // Экспериментально: сбросить входящий вызов.\r\n    // Если OK API вернёт ошибку авторизации, передайте okApiSessionKey/okApiSessionSecret\r\n    // в конструктор или в options метода.\r\n    await client.rejectIncomingCall(payload);\r\n  });\r\n\r\n  client.onCallLog(({ summaries }) => {\r\n    summaries.forEach((s) => console.log(formatCallLogLine(s)));\r\n  });\r\n\r\n  await client.start();\r\n}\r\n\r\nmain().catch(console.error);\r\n```\r\n\r\n## 🚀 Быстрый старт / Quick Start\r\n\r\n### Базовый пример / Basic Example\r\n\r\n```javascript\r\nconst { WebMaxClient } = require('webmaxsocket');\r\n\r\nasync function main() {\r\n  // Инициализация клиента / Initialize client\r\n  const client = new WebMaxClient({\r\n    name: 'my_session'  // Имя сессии / Session name\r\n  });\r\n\r\n  // Обработчик запуска / Start handler\r\n  client.onStart(async () => {\r\n    console.log('✅ Бот запущен!');\r\n    console.log(`👤 Вы вошли как: ${client.me.fullname}`);\r\n  });\r\n\r\n  // Обработчик сообщений / Message handler\r\n  client.onMessage(async (message) => {\r\n    // Не отвечаем на свои сообщения / Don't reply to own messages\r\n    if (message.senderId === client.me.id) return;\r\n    \r\n    console.log(`💬 ${message.getSenderName()}: ${message.text}`);\r\n    \r\n    // Автоответ / Auto-reply\r\n    await message.reply({\r\n      text: `Привет! Я получил: \"${message.text}\"`\r\n    });\r\n  });\r\n\r\n  // Запуск / Start\r\n  await client.start();\r\n}\r\n\r\nmain().catch(console.error);\r\n```\r\n\r\n### Авторизация / Authentication\r\n\r\n#### Способ 1: QR-код (рекомендуется для первого запуска)\r\n\r\nПри первом запуске вы увидите QR-код в консоли:\r\n\r\n```\r\n🔐 АВТОРИЗАЦИЯ ЧЕРЕЗ QR-КОД\r\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n\r\n📱 На телефоне: Профиль → Устройства / Безопасность → Подключить устройство\r\n📸 Отсканируйте QR-код\r\n\r\n█████████████████████████████\r\n...\r\n```\r\n\r\nПосле сканирования:\r\n- Токен и clientSessionId сохраняются автоматически\r\n- При следующем запуске клиент **автоматически переключится на TCP Socket** для стабильности\r\n- Повторная авторизация не требуется\r\n\r\n#### Способ 2: SMS авторизация (ANDROID)\r\n\r\nАвторизация по номеру телефона с кодом из SMS. Если на аккаунте включена **двухфакторная защита паролем**, после верного SMS-кода сервер возвращает **`passwordChallenge`**; тогда нужен второй шаг — **`sendPassword`** (протокол `AUTH_LOGIN_CHECK_PASSWORD`, как в официальном клиенте).\r\n\r\n```javascript\r\nconst client = new WebMaxClient({\r\n  name: 'my_session',\r\n  deviceType: 'ANDROID', // Обязательно для SMS\r\n  // saveTwofaPassword: true  // по умолчанию: сохранить пароль 2FA в sessions/*.json\r\n});\r\n\r\nawait client.connect();\r\n\r\nconst authSession = await client.authorizeBySMS('+79001234567');\r\nconst code = '123456'; // код из SMS\r\n\r\nconst result = await authSession.sendCode(code);\r\n\r\nif (result && typeof result === 'object' && result.needsPassword) {\r\n  // Подсказка/почта могут быть в result.passwordChallenge\r\n  await result.sendPassword('ваш_пароль_2FA');\r\n  // после успеха в сессии появится token; при saveTwofaPassword !== false — поле twofaPassword\r\n} else {\r\n  // Обычный вход без пароля: result — строка-токен (уже выполнен sync внутри sendCode)\r\n}\r\n\r\nawait client.triggerHandlers(client.handlers.START);\r\n```\r\n\r\n**Сессия:** для повторных запусков достаточно **токена** в `sessions/<имя>.json` — SMS и пароль 2FA не нужны, пока токен действителен. Поле **`twofaPassword`** (если включено сохранение) используется при **полном** повторном входе (истёк токен): можно подставить пароль без ручного ввода (в примерах учитываются переменные **`TWOFA_PASSWORD`**, **`ASK_TWOFA=1`** для принудительного запроса в консоль).\r\n\r\nИли запустите готовый пример:\r\n\r\n```bash\r\nnode example-sms.js\r\nnode example-sms.js +79001234567  # с номером в аргументе\r\n```\r\n\r\n#### QR после входа: привязка второго устройства (ANDROID)\r\n\r\nКогда вы уже авторизованы по **TCP** (SMS и сохранённая сессия), запрос **`GET_QR` на том же соединении недоступен** (ответ сервера: недопустимое состояние сессии). Для сценария как в приложении — **показать QR, телефон сканирует** — используйте метод **`showLinkDeviceQR()`**: библиотека открывает **отдельное краткоживущее WebSocket-подключение** (как у [web.max.ru](https://web.max.ru)), запрашивает QR, печатает его в консоль и при необходимости ждёт сканирования.\r\n\r\nТребования: активное соединение и **`isAuthorized`** (обычно после `await client.start()`).\r\n\r\n```javascript\r\nawait client.start();\r\n\r\n// Показать QR и ждать, пока отсканируют в приложении Max на телефоне\r\nawait client.showLinkDeviceQR();\r\n\r\n// Только показать QR и вернуть данные (без ожидания скана)\r\nconst data = await client.showLinkDeviceQR({ waitForScan: false });\r\n// data: { qrLink, trackId, pollingInterval, expiresAt }\r\n```\r\n\r\nОпции: `waitForScan` (по умолчанию `true`), `small` — компактный QR в терминале.\r\n\r\n**Версия клиента:** для выдачи QR сервер ожидает актуальный **`appVersion`** в User-Agent (не ниже **25.12.13**). В конструкторе по умолчанию используется **26.19.2** (`buildNumber: 6733`).\r\n\r\nЕсли сервер отвечает **`qr_login.disabled`**, проверьте версию приложения в опциях, откройте [web.max.ru](https://web.max.ru) в браузере или войдите на втором устройстве по номеру телефона.\r\n\r\n#### Устройства (сессии) и 2FA в аккаунте\r\n\r\nПосле **`start()`** (или `connect` + `sync`) доступны:\r\n\r\n- **`getSessionsInfo()`** — payload со списком сессий (часто поле **`sessions`**). Удобный разбор: **`WebMaxClient.normalizeSessionsList(payload)`** → массив `{ time, client, info, location, current, raw }`.\r\n- **`closeAllSessionsExceptCurrent()`** — завершить все сессии, кроме текущей (аналог «Завершить другие сеансы»). Отправляется только **явный список `times` (и варианты `sessionTimes` / `ids`) чужих устройств** из `getSessionsInfo`. Флаги вида `allExceptCurrent` **не используются** — на стороне Max они приводили к инвалидации **текущего** токена. Текущая сессия определяется по полю **`current`** и по совпадению **`deviceId`** с клиентом (см. `normalizeSessionsList`).\r\n- **`closeSessions(payload)`** — низкоуровневый вызов `SESSIONS_CLOSE` с произвольным телом.\r\n- **`getTwoFADetails()`** — состояние и параметры 2FA.\r\n- **`setTwoFAPassword({ trackId, password, hint?, email? })`** — включение или смена пароля по **`trackId`** из сценария приложения; до получения **`trackId`** может понадобиться навигация в официальном клиенте.\r\n\r\nПример:\r\n\r\n```javascript\r\nawait client.start();\r\n\r\nconst info = await client.getSessionsInfo();\r\nconst devices = WebMaxClient.normalizeSessionsList(info);\r\nconsole.log(devices);\r\n\r\n// по желанию — завершить все, кроме этой сессии\r\n// await client.closeAllSessionsExceptCurrent();\r\n\r\nconst twoFA = await client.getTwoFADetails();\r\n// await client.setTwoFAPassword({ trackId: '...', password: '...', hint: '...' });\r\n```\r\n\r\nГотовый скрипт: **`node example-sessions-2fa.js`** (с флагом **`--close-others`** — с подтверждением завершит другие сеансы).\r\n\r\n#### Способ 3: Token авторизация\r\n\r\nЕсли у вас уже есть токен (от другого сервиса/приложения):\r\n\r\n```javascript\r\nconst client = new WebMaxClient({\r\n  name: 'my_session',\r\n  token: 'An_Sx6HQ9HDiftNkVBNf6Q5PG5D8Oyj...',  // Ваш токен\r\n  configPath: 'config/myconfig.json',  // Или из файла\r\n  saveToken: true\r\n});\r\n\r\nawait client.start();\r\n```\r\n\r\nФормат конфига (`config/default.json`):\r\n```json\r\n{\r\n  \"token\": \"An_Sx6HQ9HDiftNk...\",\r\n  \"ua\": \"Mozilla/5.0 (Linux; Android 14) ...\",\r\n  \"device_type\": 3,\r\n  \"deviceType\": \"ANDROID\",\r\n  \"appVersion\": \"26.19.2\",\r\n  \"buildNumber\": 6733\r\n}\r\n```\r\n\r\n#### Транспорты\r\n\r\n- **WEB** (`deviceType: 'WEB'` или `device_type: 1`) → WebSocket (ws-api.oneme.ru)\r\n- **ANDROID** (`deviceType: 'ANDROID'` или `device_type: 2/3`) → TCP Socket (api.oneme.ru)\r\n\r\nКлиент **автоматически выбирает** правильный транспорт на основе сохраненного deviceType.\r\n\r\n## API\r\n\r\n### WebMaxClient\r\n\r\nОсновной класс для работы с API Max.\r\n\r\n#### Конструктор\r\n\r\n```javascript\r\nconst client = new WebMaxClient({\r\n  name: 'session',        // Имя сессии (для сохранения авторизации)\r\n  token: 'An_Sx6H...',    // Токен авторизации (опционально)\r\n  configPath: 'myconfig', // Путь к config файлу (опционально)\r\n  deviceType: 'WEB',      // Тип устройства: 'WEB' или 'ANDROID' (опционально)\r\n  saveToken: true,        // Сохранять токен в сессию (по умолчанию true)\r\n  debug: false,           // TCP/WebSocket: краткий лог opcode; также учитывается WEBMAX_DEBUG=1, DEBUG=1\r\n  // Лог входящих (JSON в консоль), см. ниже:\r\n  logIncoming: undefined, // false | 'messages' | 'verbose' — по умолчанию см. таблицу\r\n  logIncomingVerbose: false, // явно включить verbose (как logIncoming: 'verbose')\r\n  apiUrl: 'wss://...',    // URL WebSocket API (опционально)\r\n  maxReconnectAttempts: 5,// Максимальное количество попыток переподключения\r\n  reconnectDelay: 3000,   // Задержка между попытками переподключения (мс)\r\n  // Сессия и токен (см. раздел «Сессии»):\r\n  sessionRefreshIntervalMs: 0, // Периодический sync (мс), минимум 10_000; 0 — выключено. Алиас: autoSyncIntervalMs\r\n  clearSessionOnFailedSync: false, // connectWithSession: при ошибке sync вызвать session.clear() перед authorize() (по умолчанию false)\r\n  // User-Agent / клиент (важно для GET_QR, см. showLinkDeviceQR):\r\n  appVersion: '26.19.2',  // Актуальная версия Android-клиента\r\n  ua: 'Mozilla/5.0 ...', // или headerUserAgent\r\n  osVersion: '14',\r\n  screen: '360x780 3.0x',\r\n  timezone: 'Europe/Moscow',\r\n  locale: 'ru',\r\n  buildNumber: 6733,      // опционально\r\n  clientSessionId: 1      // опционально\r\n});\r\n```\r\n\r\n**Лог входящих (`logIncoming`):** печать блоков `📥 [incoming:…]` с JSON.\r\n\r\n| Значение / условие | Поведение |\r\n|--------------------|-----------|\r\n| `logIncoming: false` | Выкл. |\r\n| `logIncoming: 'messages'` | Только входящие сообщения (`message.rawData`). |\r\n| `logIncoming: 'verbose'` или `logIncomingVerbose: true` | Сообщения + `connected`, `raw_message`, `message_removed`, `chat_action`, `error`. |\r\n| не указано | По умолчанию: как `'messages'`; если **`WEBMAX_DEBUG=1`** — как `'verbose'`. Явное **`logIncoming: 'messages'`** отключает расширенный режим даже при `WEBMAX_DEBUG`. |\r\n| **`WEBMAX_SILENT=1`** | Выкл. всех дампов. |\r\n\r\nРучной вывод в том же формате: `client.logIncoming('my_label', data)`. Текущий режим: `client.incomingLogMode` (`'off' \\| 'messages' \\| 'verbose'`). Низкоуровнево: `resolveIncomingLogMode(options)`, `printIncomingLog(label, payload)` из пакета.\r\n\r\n#### Методы\r\n\r\n##### `start()`\r\n\r\nЗапускает клиент и устанавливает соединение.\r\n\r\n```javascript\r\nawait client.start();\r\n```\r\n\r\n##### `authorizeBySMS(phone)`\r\n\r\nАвторизация по номеру телефона через SMS (только для ANDROID). Возвращает объект с полями **`tempToken`**, **`phone`**, **`sendCode`**.\r\n\r\n**`sendCode(code)`** после ввода кода из SMS:\r\n\r\n- если пароль 2FA **не** требуется — возвращает **строку-токен** (внутри уже выполнены сохранение сессии и **`sync()`**);\r\n- если требуется 2FA — возвращает объект **`{ needsPassword: true, passwordChallenge, trackId, sendPassword }`**. Вызовите **`await sendPassword(password)`**; при успехе выполняется **`sync()`**, при **`saveTwofaPassword !== false`** (по умолчанию `true`) в файл сессии записывается **`twofaPassword`** для следующих полных входов.\r\n\r\nОпция конструктора **`saveTwofaPassword: false`** отключает запись пароля 2FA в `sessions/*.json`.\r\n\r\nНизкоуровнево на TCP: **`sendCode`** → `AUTH` (18) с `authTokenType: 'CHECK_CODE'`; **`sendPassword`** → **`AUTH_LOGIN_CHECK_PASSWORD`** (`0x73`) с полями **`trackId`** и **`password`** (см. `MaxSocketTransport.sendLogin2FAPassword`).\r\n\r\n```javascript\r\nawait client.connect();\r\nconst authSession = await client.authorizeBySMS('+79001234567');\r\nconst out = await authSession.sendCode('123456');\r\nif (out && out.needsPassword) await out.sendPassword('…');\r\n```\r\n\r\n##### `showLinkDeviceQR(options)`\r\n\r\nПоказать в консоли **QR-код для привязки устройства** (как в приложении Max: телефон сканирует QR). Нужна **уже выполненная авторизация** (`start()` или `connect` + `sync`).\r\n\r\n- Для **WEB** запрос выполняется по текущему WebSocket.\r\n- Для **ANDROID** после входа по TCP используется **второе** WebSocket-подключение без повторного `LOGIN` на той сессии (иначе `GET_QR` на том же TCP недоступен).\r\n\r\n```javascript\r\nawait client.showLinkDeviceQR();\r\nawait client.showLinkDeviceQR({ waitForScan: false, small: false });\r\n```\r\n\r\nВозвращает `Promise<{ qrLink, trackId, pollingInterval, expiresAt }>`.\r\n\r\n##### `requestQR()`, `checkQRStatus(trackId)`, `loginByQR(trackId)`, `authorizeByQR()`\r\n\r\nНизкоуровневые шаги QR-авторизации для **WEB** (первый вход без SMS). Обычно достаточно `start()` без токена или `authorizeByQR()`.\r\n\r\n##### `sendMessage(options)`\r\n\r\nОтправляет сообщение в чат с уведомлением (notify: true).\r\n\r\n```javascript\r\nconst message = await client.sendMessage({\r\n  chatId: 123,\r\n  text: 'Привет!',\r\n  // cid опционально; на TCP не используйте Date.now() (нужен int32)\r\n  replyTo: null,        // ID сообщения для ответа (опционально)\r\n  attachments: []       // Вложения (опционально)\r\n});\r\n```\r\n\r\n##### `sendMessageChannel(options)`\r\n\r\nОтправляет сообщение в канал без уведомления (notify: false). Поля **`text`**, **`replyTo`**, **`attachments`** — те же, что у `sendMessage` (вложения из `uploadPhoto` / `uploadVideo` / `uploadFile` / `uploadAudio`).\r\n\r\n```javascript\r\nconst message = await client.sendMessageChannel({\r\n  chatId: 123,\r\n  text: 'Сообщение в канал',\r\n  replyTo: null,\r\n  attachments: [] // опционально: [attach] после upload*\r\n});\r\n```\r\n\r\n##### `editMessage(options)`\r\n\r\nРедактирует сообщение.\r\n\r\n```javascript\r\nawait client.editMessage({\r\n  messageId: 456,\r\n  chatId: 123,\r\n  text: 'Исправленный текст',\r\n  attachments: [] // опционально, после upload*\r\n});\r\n```\r\n\r\n##### Пины, реакции\r\n\r\n| Метод | Назначение |\r\n|--------|------------|\r\n| `pinMessage({ chatId, messageId, notifyPin })` | Закрепить сообщение |\r\n| `setMessageReaction({ chatId, messageId, emoji })` | Эмодзи-реакция |\r\n| `cancelMessageReaction({ chatId, messageId })` | Снять реакцию |\r\n| `getMessageReactions({ chatId, messageId, count })` | Список реакций |\r\n\r\n##### Чаты, каналы, группы\r\n\r\n| Метод | Назначение |\r\n|--------|------------|\r\n| `getChatInfo(chatIds)` | Информация по id (массив или одно число) |\r\n| `resolveLink(link)` | Разрешить URL / `join/…` (LINK_INFO) |\r\n| `joinChatByLink(link)` | Вступить по ссылке |\r\n| `setChatSubscription(chatId, subscribe)` | Подписка на канал |\r\n| `createGroup({ title, userIds })` | Новая группа |\r\n| `createChannel({ title })` | Новый канал |\r\n| `muteChat(chatId, mute)` | Уведомления чата (не беспокоить) |\r\n| `getChatMembers({ chatId, marker, count, type })` | Участники (count ≤ 500) |\r\n| `inviteToChat({ chatId, userIds, showHistory })` | Пригласить |\r\n| `removeFromChat({ chatId, userIds, cleanMsgPeriod })` | Исключить |\r\n| `addChatAdmins({ chatId, userIds, permissions })` | Выдать админку (по умолчанию `permissions: 120`) |\r\n| `removeChatAdmins({ chatId, userIds })` | Снять админку |\r\n| `transferChatOwnership({ chatId, newOwnerId })` | Передать владение |\r\n| `setGroupOptions({ chatId, options })` | Настройки группы (`ALL_CAN_PIN_MESSAGE`, …) |\r\n| `resolveChannelByUsername(username)` | Канал по @username |\r\n| `joinChannelByUsername(username)` | Вступить по @username |\r\n| `resolveInviteHash(hash)` | Инвайт по хэшу без префикса `join/` |\r\n\r\n##### Контакты и профиль\r\n\r\n| Метод | Назначение |\r\n|--------|------------|\r\n| `getContacts(contactIds)` | Несколько контактов (массив id) |\r\n| `addContact(userId)` | В контакты |\r\n| `blockUser(userId)` | Заблокировать |\r\n| `updateProfile({ firstName, lastName, description })` | Своё имя / описание |\r\n| `setHiddenOnline(hidden)` | Скрыть «в сети» |\r\n| `setFindableByPhone(mode)` | `'ALL'` \\| `'CONTACTS'` или boolean |\r\n| `setCallsPrivacyMode(mode)` | Кто может звонить |\r\n| `setChatsInvitePrivacy(mode)` | Кто может приглашать в чаты |\r\n\r\nЧасть методов требует прав в чате; ответы сервера зависят от роли и типа чата.\r\n\r\n##### `deleteMessage(options)`\r\n\r\nУдаляет сообщение.\r\n\r\n```javascript\r\nawait client.deleteMessage({\r\n  messageId: 456,\r\n  chatId: 123\r\n});\r\n```\r\n\r\n##### `forwardMessage(options)`\r\n\r\nПересылает сообщение.\r\n\r\n```javascript\r\nawait client.forwardMessage({\r\n  messageId: 456,\r\n  fromChatId: 123,\r\n  toChatId: 789\r\n});\r\n```\r\n\r\n##### Загрузка медиа для `attachments`\r\n\r\nВсе методы ниже возвращают объект(ы), которые передаются в **`attachments`** у `sendMessage`, **`sendMessageChannel`** и **`message.reply`**. Нужен **Node.js 18+** (`fetch`, `FormData`). Схема: опкод загрузки → `UPLOAD_ATTACH_PREP` (65) → HTTP POST на выданный URL. Для **видео** и **файлов** после POST клиент ждёт **`NOTIF_ATTACH` (opcode 136)**.\r\n\r\n| Метод | Результат для `attachments` |\r\n|--------|-----------------------------|\r\n| `uploadPhoto(chatId, filePath)` | `{ _type: 'PHOTO', photoToken }` |\r\n| `uploadVideo(chatId, filePath)` | `{ _type: 'VIDEO', videoId, token }` |\r\n| `uploadFile(chatId, filePath, options?)` | `{ _type: 'FILE', fileId }` — документы, архивы; `options`: `{ filename, mimeType }` |\r\n| `uploadAudio(chatId, filePath)` | то же, что `uploadFile` с MIME для `.mp3`, `.ogg`, `.m4a`, `.wav`, … |\r\n\r\n```javascript\r\nconst photo = await client.uploadPhoto(chatId, './a.png');\r\nconst video = await client.uploadVideo(chatId, './b.mp4');\r\nconst file = await client.uploadFile(chatId, './doc.pdf');\r\nconst audio = await client.uploadAudio(chatId, './track.mp3');\r\n\r\nawait client.sendMessage({\r\n  chatId,\r\n  text: 'Набор вложений',\r\n  attachments: [photo, video]\r\n});\r\n\r\nawait client.sendMessageChannel({\r\n  chatId,\r\n  text: 'В канал с файлом',\r\n  attachments: [file]\r\n});\r\n```\r\n\r\n##### `sendChatAction(chatId, action)`\r\n\r\nОтправляет действие в чате (печатает, выбирает стикер и т.д.).\r\n\r\n```javascript\r\nawait client.sendChatAction(123, ChatActions.TYPING);\r\n```\r\n\r\n##### `getUser(userId)`\r\n\r\nПолучает информацию о пользователе.\r\n\r\n```javascript\r\nconst user = await client.getUser(123);\r\n```\r\n\r\n##### `getUserByPhone(phone)` / `getUserIdByPhone(phone)`\r\n\r\nПоиск пользователя по номеру (`CONTACT_INFO_BY_PHONE`, opcode 46). Номер нормализуется (`+79001234567`). Если пользователь не найден или скрыл поиск по телефону — `null`.\r\n\r\n```javascript\r\nconst user = await client.getUserByPhone('+79001234567');\r\n// User { id, firstname, lastname, phone, ... } или null\r\n\r\nconst id = await client.getUserIdByPhone('89001234567');\r\n// 123456789 или null\r\n```\r\n\r\n##### `getChats(limit, offset)`\r\n\r\nПолучает список чатов.\r\n\r\n```javascript\r\nconst chats = await client.getChats(50, 0);\r\n```\r\n\r\n##### `getHistory(chatId, from?, backward?, forward?)`\r\n\r\nПолучает историю сообщений. У каждого элемента в массиве будет **`chatId`**, совпадающий с запрошенным чатом (в ответе сервера поле часто отсутствует).\r\n\r\n```javascript\r\nconst messages = await client.getHistory(123, Date.now(), 50, 0);\r\n```\r\n\r\n##### `requestFileDownloadUrl({ chatId, messageId, fileId, fileName?, requestId?, attachLocalId? })`\r\n\r\nЗапрашивает **временный HTTPS URL** для вложения **`FILE`**, если в **`attaches`** нет **`baseUrl`**. Идентификаторы **`messageId`**, **`fileId`**, **`chatId`** должны совпадать с данными сообщения (для больших id используйте **`bigint`** из объекта **`Message`**, не округляйте в обычный **`Number`**).\r\n\r\nВозвращает **`Promise<string>`** (URL). Проще вызывать **`message.downloadAttachment()`**, он подставит нужные поля сам.\r\n\r\n##### Свойство `lastSyncPayload`\r\n\r\nПосле успешного **`sync()`** — объект последнего ответа сервера (поля вроде **`chats`**, **`profile`**, …). Удобно, если **`getChats()`** на TCP вернул пустой список.\r\n\r\n##### `stop()`\r\n\r\nОстанавливает клиент.\r\n\r\n```javascript\r\nawait client.stop();\r\n```\r\n\r\n##### `logout()`\r\n\r\nВыполняет выход из аккаунта и удаляет сессию.\r\n\r\n```javascript\r\nawait client.logout();\r\n```\r\n\r\n#### Обработчики событий\r\n\r\n##### `onStart(handler)`\r\n\r\nРегистрирует обработчик запуска клиента.\r\n\r\n```javascript\r\nclient.onStart(async () => {\r\n  console.log('Клиент запущен!');\r\n});\r\n```\r\n\r\n##### `onMessage(handler)`\r\n\r\nРегистрирует обработчик новых сообщений.\r\n\r\n```javascript\r\nclient.onMessage(async (message) => {\r\n  console.log('Новое сообщение:', message.text);\r\n});\r\n```\r\n\r\n##### `onMessageRemoved(handler)`\r\n\r\nРегистрирует обработчик удаленных сообщений.\r\n\r\n```javascript\r\nclient.onMessageRemoved(async (message) => {\r\n  console.log('Сообщение удалено:', message.text);\r\n});\r\n```\r\n\r\n##### `onChatAction(handler)`\r\n\r\nРегистрирует обработчик действий в чате.\r\n\r\n```javascript\r\nclient.onChatAction(async (action) => {\r\n  console.log('Действие в чате:', action.type);\r\n});\r\n```\r\n\r\n##### `onError(handler)`\r\n\r\nРегистрирует обработчик ошибок.\r\n\r\n```javascript\r\nclient.onError(async (error) => {\r\n  console.error('Ошибка:', error.message);\r\n});\r\n```\r\n\r\n### Message\r\n\r\nКласс, представляющий сообщение.\r\n\r\n#### Свойства\r\n\r\n- `id` - ID сообщения\r\n- `cid` - Client ID сообщения\r\n- `chatId` - ID чата\r\n- `text` - Текст сообщения\r\n- `senderId` - ID отправителя\r\n- `sender` - Объект отправителя (User)\r\n- `timestamp` - Время отправки\r\n- `type` - Тип сообщения\r\n- `isEdited` - Флаг редактирования\r\n- `replyTo` - ID сообщения, на которое это является ответом\r\n- `attachments` - Вложения\r\n\r\n#### Методы\r\n\r\n##### `reply(options)`\r\n\r\nОтправляет текст **в тот же чат**. По умолчанию **без** цитаты исходного сообщения (`link REPLY`), т.к. на TCP-сокете сервер часто возвращает «Ошибка валидации» для ответа-цитаты. Чтобы попробовать ответ с цитатой: `{ text: '...', quote: true }`.\r\n\r\n```javascript\r\nawait message.reply({ text: 'Ответ на сообщение' });\r\nawait message.reply({ text: '...', quote: true });\r\n```\r\n\r\n##### `edit(options)`\r\n\r\nРедактирует сообщение.\r\n\r\n```javascript\r\nawait message.edit({\r\n  text: 'Новый текст'\r\n});\r\n```\r\n\r\n##### `delete()`\r\n\r\nУдаляет сообщение.\r\n\r\n```javascript\r\nawait message.delete();\r\n```\r\n\r\n##### `forward(chatId)`\r\n\r\nПересылает сообщение.\r\n\r\n```javascript\r\nawait message.forward(789);\r\n```\r\n\r\n##### `downloadAttachment(index, options?)`\r\n\r\nСкачивает вложение в файл (по умолчанию каталог **`os.tmpdir()`**). Логика:\r\n\r\n- если у вложения есть **`baseUrl`** или **`url`** (часто **`PHOTO`**, стикеры и т.д.) — обычный HTTPS-запрос;\r\n- если **`_type === 'FILE'`** и URL нет — внутри вызывается **`client.requestFileDownloadUrl()`** (нужны **`message.chatId`** и точный **`message.id`**; после **`getHistory`** они выставлены, **`id` может быть `bigint`**).\r\n\r\nОпции: **`dir`**, **`filename`** (basename). Расширение подбирается по **`Content-Type`** и типу вложения.\r\n\r\nВозвращает `{ path, contentType }`.\r\n\r\n```javascript\r\nif (message.attachments.length) {\r\n  const { path, contentType } = await message.downloadAttachment(0);\r\n  console.log('Сохранено:', path, contentType);\r\n  // после обработки можно удалить: fs.unlinkSync(path)\r\n}\r\n\r\n// Свой каталог или имя файла:\r\nawait message.downloadAttachment(0, {\r\n  dir: './downloads',\r\n  filename: 'photo.webp'\r\n});\r\n```\r\n\r\n### Утилиты скачивания медиа / Media download helpers\r\n\r\nЭкспортируются из пакета наряду с `WebMaxClient`:\r\n\r\n```javascript\r\nconst {\r\n  downloadUrlToTempFile,\r\n  extFromContentType,\r\n  extFromAttachType\r\n} = require('webmaxsocket');\r\n```\r\n\r\n##### `downloadUrlToTempFile(url, options?)`\r\n\r\nHTTP(S)-запрос с следованием редиректам, запись тела ответа в файл.\r\n\r\n| Опция | Описание |\r\n|--------|----------|\r\n| `dir` | Каталог (по умолчанию `os.tmpdir()`) |\r\n| `filename` | Имя файла (только basename); если не задано — `max-media-<time>-<random>.<ext>` |\r\n| `extFallback` | Расширение, если по `Content-Type` определить не удалось (например `'.jpg'`) |\r\n\r\n```javascript\r\nconst { path, contentType } = await downloadUrlToTempFile(\r\n  'https://i.oneme.ru/i?r=...',\r\n  { extFallback: '.jpg' }\r\n);\r\n```\r\n\r\n##### `extFromContentType(contentType)` / `extFromAttachType(attachType)`\r\n\r\nВспомогательные функции для подбора расширения по MIME или по `_type` вложения (`PHOTO`, `VIDEO`, …).\r\n\r\n### User\r\n\r\nКласс, представляющий пользователя.\r\n\r\n#### Свойства\r\n\r\n- `id` - ID пользователя\r\n- `firstname` - Имя\r\n- `lastname` - Фамилия\r\n- `username` - Имя пользователя\r\n- `phone` - Номер телефона\r\n- `avatar` - URL аватара\r\n- `status` - Статус\r\n- `bio` - Биография\r\n- `fullname` - Полное имя (getter)\r\n\r\n### ChatAction\r\n\r\nКласс, представляющий действие в чате.\r\n\r\n#### Свойства\r\n\r\n- `type` - Тип действия\r\n- `chatId` - ID чата\r\n- `userId` - ID пользователя\r\n- `user` - Объект пользователя (User)\r\n- `timestamp` - Время действия\r\n\r\n### Константы\r\n\r\n#### ChatActions\r\n\r\n```javascript\r\nconst { ChatActions } = require('webmaxsocket');\r\n\r\nChatActions.TYPING          // Печатает\r\nChatActions.STICKER         // Выбирает стикер\r\nChatActions.FILE            // Отправляет файл\r\nChatActions.RECORDING_VOICE // Записывает голосовое\r\nChatActions.RECORDING_VIDEO // Записывает видео\r\n```\r\n\r\n### MaxSocketTransport\r\n\r\nНизкоуровневый TCP Socket транспорт для ANDROID (api.oneme.ru). Входящие пакеты с флагом сжатия распаковываются через **LZ4** (см. раздел **«Зависимости для Socket транспорта»** выше).\r\n\r\n#### Прямое использование (advanced)\r\n\r\n```javascript\r\nconst { MaxSocketTransport } = require('webmaxsocket');\r\n\r\nconst transport = new MaxSocketTransport({\r\n  deviceType: 'ANDROID',\r\n  ua: 'Mozilla/5.0 (Linux; Android 14) ...',\r\n  deviceId: 'your-device-id',\r\n  debug: true\r\n});\r\n\r\nawait transport.connect();\r\nawait transport.handshake(userAgentPayload);\r\nconst syncData = await transport.sync(token, userAgent);\r\n```\r\n\r\n**Примечание:** В большинстве случаев используйте `WebMaxClient`, который автоматически выбирает нужный транспорт.\r\n\r\n## 📚 Примеры\r\n\r\n### Пример 1: QR-авторизация (example.js)\r\n\r\n```bash\r\nnode example.js\r\n```\r\n\r\nПервый запуск - QR-авторизация, повторные запуски - автоматический вход через TCP Socket.\r\n\r\n### Пример 2: Token авторизация (example-token.js)\r\n\r\n```bash\r\n# Через config файл\r\nnode example-token.js\r\nnode example-token.js myconfig  # config/myconfig.json\r\n\r\n# Через переменную окружения\r\nTOKEN=\"ваш_токен\" node example-token.js\r\n```\r\n\r\n### Пример 3: SMS авторизация (example-sms.js)\r\n\r\n```bash\r\n# Интерактивный ввод номера\r\nnode example-sms.js\r\n\r\n# С номером в аргументе\r\nnode example-sms.js +79001234567\r\n```\r\n\r\n### Пример 5: Скачивание вложений из истории чата (example-download-files.js)\r\n\r\nНужна **сохранённая Android-сессия** (`sessions/<name>.json`). Скрипт вызывает **`sync()`**, читает историю и сохраняет вложения в **`./downloads/`**.\r\n\r\n```bash\r\ncd node_modules/webmaxsocket   # или из корня клона репозитория\r\n\r\n# chatId — число или 0 (например «Избранное к себе»)\r\nnode example-download-files.js 0 30\r\n\r\n# Имя сессии и глубина истории через env\r\nSESSION_NAME=sms_session BACKWARD=50 node example-download-files.js 123456\r\n\r\nnpm run example:download -- 0 20\r\n```\r\n\r\n## Структура проекта\r\n\r\n```\r\nwebmaxsocket/\r\n├── lib/\r\n│   ├── client.js           # Основной клиент\r\n│   ├── socketTransport.js  # TCP Socket транспорт\r\n│   ├── session.js          # Управление сессиями\r\n│   ├── userAgent.js        # UserAgent генератор\r\n│   ├── opcodes.js          # Протокол опкоды\r\n│   ├── constants.js        # Константы\r\n│   ├── downloadMedia.js    # Скачивание медиа по URL во временный файл\r\n│   ├── incomingLog.js      # Режим logIncoming / печать входящих\r\n│   └── entities/\r\n│       ├── User.js         # Класс пользователя\r\n│       ├── Message.js      # Класс сообщения\r\n│       ├── ChatAction.js   # Класс действия в чате\r\n│       └── index.js        # Экспорт сущностей\r\n├── config/                 # Конфигурационные файлы\r\n│   └── example.json        # Пример конфига\r\n├── sessions/               # Директория с сохраненными сессиями\r\n├── index.js                # Точка входа\r\n├── example.js              # QR-авторизация\r\n├── example-token.js        # Token авторизация\r\n├── example-sms.js          # SMS авторизация\r\n├── example-download-files.js  # Скачивание вложений из истории чата\r\n├── package.json\r\n├── api.package.md          # Справочник API (все методы)\r\n└── README.md\r\n```\r\n\r\n## Сессии\r\n\r\nБиблиотека автоматически сохраняет сессии в директории `sessions/`. При повторном запуске с тем же именем сессии авторизация не требуется.\r\n\r\n**Токен после `sync()`:** при успешном `LOGIN` (вызов `sync()`) сервер может вернуть новый токен в `tokenAttrs.LOGIN.token`. Если он отличается от сохранённого, библиотека обновляет `this._token` и файл сессии (если `saveToken !== false`). Так ротация на стороне Max не теряется между перезапусками.\r\n\r\n**TCP (ANDROID) и повторный `sync()`:** на одном TLS‑сокете **второй подряд `LOGIN` (19)** сервер отклоняет («Недопустимое состояние сессии»). Запрос **`SYNC` (21)** на том же транспорте стабильно даёт «Что-то пошло не так» (в веб-клиенте повторная синхронизация идёт через **`LOGIN` (19)**, не через 21). Поэтому после первого успешного `LOGIN` каждый следующий **`sync()`** на TCP: **закрыть сокет → новое соединение → полный `LOGIN` (19)** с телом как у веб (`lastLogin`, счётчики, `presenceSync: -1`, `userAgent`). На **WEB** каждый `sync()` по-прежнему идёт как `LOGIN` на том же WebSocket.\r\n\r\n**Параллельные RPC на одном TCP:** транспорт сопоставляет ответы по **`seq % 256`**. Не вызывайте **`sendAndWait`** (и методы поверх него: `sync`, `getSessionsInfo`, …) **параллельно** на одном клиенте — возможна путаница ответов и ложные ошибки. Выполняйте запросы **последовательно** или используйте очередь.\r\n\r\n**Периодическое обновление:** опция **`sessionRefreshIntervalMs`** (или **`autoSyncIntervalMs`**) — интервал для повторного `sync()` (минимум **10 с**). На **TCP** каждый такой вызов обычно **снова открывает TLS** и шлёт **`LOGIN`**. Таймер снимается в **`stop()`**. Ручная очистка: **`client.session.clear()`**.\r\n\r\n**Повторный вход при ошибке токена из config:** при неудачном `sync()` с токеном из **`options.token`** или **`config`** файл `sessions/*.json` **не очищается** (чтобы сохранить актуальный токен из прошлой авторизации). Для **`connectWithSession()`** очистка перед `authorize()` после ошибки `sync()` выключена по умолчанию; включите **`clearSessionOnFailedSync: true`**, если нужно прежнее поведение «чистый лист».\r\n\r\n```javascript\r\n// Создание новой сессии\r\nconst client1 = new WebMaxClient({ name: 'account1', phone: '+1234567890' });\r\n\r\n// Использование существующей сессии\r\nconst client2 = new WebMaxClient({ name: 'account1' }); // phone не требуется\r\n\r\n// Пример: раз в 45 минут — sync() для продления ротации токена\r\nconst client3 = new WebMaxClient({\r\n  name: 'account1',\r\n  sessionRefreshIntervalMs: 45 * 60 * 1000\r\n});\r\n```\r\n\r\n## Обработка ошибок\r\n\r\nРекомендуется всегда оборачивать вызовы API в try-catch блоки:\r\n\r\n```javascript\r\ntry {\r\n  const message = await client.sendMessage({\r\n    chatId: 123,\r\n    text: 'Привет!'\r\n  });\r\n} catch (error) {\r\n  console.error('Ошибка:', error.message);\r\n}\r\n```\r\n\r\n## 🔧 Отладка / Debug\r\n\r\nДля включения отладочного вывода:\r\n\r\n```javascript\r\nconst client = new WebMaxClient({\r\n  name: 'my_session',\r\n  debug: true  // или process.env.DEBUG = '1'\r\n});\r\n```\r\n\r\nИли через переменную окружения:\r\n\r\n```bash\r\nDEBUG=1 node example.js\r\n```\r\n\r\n## 💡 Важные замечания\r\n\r\n1. **TCP Socket после QR-авторизации:** После первой успешной QR-авторизации клиент автоматически сохраняет `clientSessionId` и переключается на TCP Socket транспорт при следующем запуске для повышения стабильности.\r\n\r\n2. **QR для нового устройства после входа по SMS/TCP:** Используйте `showLinkDeviceQR()`. Это не отдельный опкод в протоколе, а тот же `GET_QR`, что и у веб-клиента; для уже залогиненного TCP-сокета запрос выполняется через **эфемерное WebSocket-подключение** (временный файл сессии `_link_qr_*` удаляется после завершения).\r\n\r\n3. **Версия `appVersion` и QR/SMS:** Слишком старая версия в User-Agent даёт `qr_login.disabled` или «Приложение устарело». По умолчанию **26.19.2** / **6733**. Константы: `APP_VERSION`, `BUILD_NUMBER` в `lib/constants.js`.\r\n\r\n4. **Разница между sendMessage и sendMessageChannel:**\r\n   - `sendMessage()` - отправка с уведомлением (notify: true) для обычных чатов\r\n   - `sendMessageChannel()` - отправка без уведомления (notify: false) для каналов\r\n\r\n5. **Автоматический выбор транспорта:** Клиент автоматически определяет какой транспорт использовать на основе `deviceType` в сессии или config файле.\r\n\r\n6. **`cid` при отправке сообщений (TCP/Socket):** сервер проверяет **signed int32**. Не передавайте `Date.now()` (миллисекунды ~1e12) — будет «Ошибка валидации». Либо не указывайте `cid` (клиент подставит свой), либо передайте целое в диапазоне **−2³¹ … 2³¹−1**.\r\n\r\n7. **TCP и keep-alive (PING):** сервер периодически шлёт `PING`. На WebSocket клиент отвечает `sendPong`; на **TCP** ответ на серверный `PING` — **`PING` с пустым payload**. Дополнительно клиент может слать исходящий **`PING` с `{ interactive: true }`** раз в **30 с** (как веб), опция **`tcpInteractivePingMs`** ( **`0`** — выключить).\r\n\r\n8. **LZ4:** для ANDROID входящие данные распаковываются из LZ4-блоков; **`lz4js`** входит в зависимости пакета. При необходимости можно установить нативный **`lz4`** (см. раздел **«Зависимости для Socket транспорта»**).\r\n\r\n9. **Повторный `sync()` на TCP:** см. **«Сессии»** — **новое TLS и снова `LOGIN` (19)**; второй **`LOGIN` (19)** подряд на **том же** сокете сервер не принимает; **`SYNC` (21)** на TCP не использовать.\r\n\r\n10. **`closeAllSessionsExceptCurrent`:** не подставляйте в **`closeSessions`** сырые флаги «закрыть все кроме текущего» без явного списка сессий — есть риск инвалидации своего токена; используйте готовый метод.\r\n\r\n## 📌 История версий / Changelog\r\n\r\n### 1.2.7\r\n\r\n- **Fingerprint 26.19.2 (6733):** обновлены `APP_VERSION` / `BUILD_NUMBER` — сервер больше не отвечает «Приложение устарело» на SMS `AUTH_REQUEST`.\r\n- **Старые сессии:** `appVersion`/`buildNumber` больше не читаются из `sessions/*.json` (только options/config/дефолт), чтобы устаревший fingerprint не залипал.\r\n- **`getUserByPhone(phone)` / `getUserIdByPhone(phone)`:** поиск пользователя по номеру через opcode `CONTACT_INFO_BY_PHONE` (46). При `contact.not.found` возвращают `null`.\r\n\r\n### 1.2.6\r\n\r\n- **`client.lastSyncPayload`** — сохраняется последний успешный ответ **`LOGIN`/`sync()`** (в т.ч. массив `chats`). На **TCP** список **`getChats()`** иногда пустой, тогда чаты брать из **`lastSyncPayload.chats`**.\r\n- **Скачивание документов `FILE` без `baseUrl` в истории:** **`requestFileDownloadUrl({ chatId, messageId, fileId, fileName?, … })`** — сервер возвращает временный HTTPS-**`url`** для скачивания.\r\n- **`message.downloadAttachment()`** — для **`_type: FILE`** без URL сам вызывает **`requestFileDownloadUrl`** (нужны корректный **`chatId`** сообщения и **`messageId`**).\r\n- **`getHistory`**: в каждое сообщение подмешивается **`chatId`** из аргумента запроса (в сырых сообщениях его часто нет).\r\n- **`Message`**: корректно обрабатывается **`chatId === 0`** (например «Избранное к себе»).\r\n- **TCP + msgpack:** при наличии **`BigInt`** в исходящем payload включается **`useBigInt64`** при кодировании; входящие пакеты декодируются с **`useBigInt64`**, чтобы **`message.id`** и другие int64 не терялись (выше **`Number.MAX_SAFE_INTEGER`**).\r\n- **`downloadMedia`:** расширена карта MIME → расширение (`text/plain`, `application/pdf`, …).\r\n- Новый пример: **`example-download-files.js`** (история чата → папка `downloads/`).\r\n\r\n### 1.2.5\r\n\r\n- **`Opcode.NOTIF_INCOMING_CALL` (137)** — имя опкода в `getOpcodeName`; обработка в TCP/WebSocket: событие **`incoming_call`**, **`onIncomingCall`**, плюс **`raw_message`** как раньше.\r\n- **`onCallLog`** / событие **`call_log`**: при **`NOTIF_MESSAGE`** с вложением **`_type: \"CALL\"`** (итог звонка: `hangupType`, `duration`, `conversationId`).\r\n- **`rejectIncomingCall`** / **`hangupCall`**: экспериментальная отправка сброса звонка через OK API метод **`vchat.hangupConversation`** (`conversationId`, `reason=REJECTED`).\r\n- Модуль **`lib/callHelpers.js`** (экспорт из пакета): `summarizeIncomingCall`, `extractCallAttachesFromNotifPayload`, `summarizeCallAttach`, `formatCallLogLine`, `isCallAttach`.\r\n- **`EventTypes.INCOMING_CALL`**, **`EventTypes.CALL_LOG`**.\r\n\r\n### 1.2.4\r\n\r\n- **ANDROID по умолчанию для SMS/TCP:** `device_type: 2/3` нормализуется в `ANDROID`; дефолтный fingerprint обновлён до `appVersion: 26.14.1`, `buildNumber: 6686`.\r\n- **Удалён устаревший socket example:** SMS-примеры и низкоуровневый TCP-путь теперь используют Android-профиль.\r\n\r\n### 1.2.3\r\n\r\n- **TCP / повторный `sync()`:** после первого `LOGIN` каждый следующий `sync()` — **переподключение и полный `LOGIN` (19)** (op. **21** на TCP сервер отклоняет; тело LOGIN с **`lastLogin`** и счётчиками из сессии).\r\n- **TCP:** периодический исходящий **`PING` `{ interactive: true }`** (~30 с), опция **`tcpInteractivePingMs`**.\r\n- **`closeAllSessionsExceptCurrent`:** закрытие только по **явным `times`** чужих сессий; без флагов `allExceptCurrent` / `excludeCurrent`; учёт **`deviceId`** и **`current`** при выборе «своей» сессии.\r\n- **`normalizeSessionsList`:** поле **`deviceId`**, доп. признаки текущей сессии в ответе.\r\n- **`sync()` / LOGIN:** сохранение нового токена из ответа `tokenAttrs.LOGIN.token` при ротации на сервере.\r\n- **Ротация токена из входящих пакетов:** рекурсивный разбор **`tokenAttrs.LOGIN.token`** в любом **уведомлении TCP** и в **сообщениях WebSocket** (как в официальном клиенте при пушах ротации), плюс вложенные массивы в ответе LOGIN — чтобы файл сессии не оставался со старым токеном после смены на сервере.\r\n- **`sessionRefreshIntervalMs`** / **`autoSyncIntervalMs`:** периодический `sync()` в фоне (минимум 10 с), таймер в `stop()`; на TCP типичен **новый TLS** на каждый тик.\r\n- **`start()`:** при ошибке `sync()` с токеном из config/options вызов **`session.clear()`** убран — файл сессии не теряется.\r\n- **`clearSessionOnFailedSync`** (по умолчанию `false`): для **`connectWithSession()`** — опционально вызывать **`session.clear()`** перед повторной авторизацией после ошибки `sync()`.\r\n\r\n### 1.2.1\r\n\r\n- Список устройств и завершение других сеансов: **`getSessionsInfo`**, **`normalizeSessionsList`**, **`closeSessions`**, **`closeAllSessionsExceptCurrent`**.\r\n- 2FA в аккаунте: **`getTwoFADetails`**, **`setTwoFAPassword`**. Пример: **`example-sessions-2fa.js`**.\r\n\r\n### 1.2.0\r\n\r\n- SMS-авторизация: поддержка **2FA по паролю** после кода из SMS (`passwordChallenge`, `AUTH_LOGIN_CHECK_PASSWORD` / opcode `0x73`).\r\n- Опция **`saveTwofaPassword`** (по умолчанию включена): сохранение пароля 2FA в файл сессии **`twofaPassword`**.\r\n- **`MaxSocketTransport`**: метод **`sendLogin2FAPassword(trackId, password)`**.\r\n\r\n### 1.1.6 и ранее\r\n\r\n- См. коммиты и теги в [репозитории](https://github.com/Tellarion/webmaxsocket).\r\n\r\n## 🔗 Ссылки / Links\r\n\r\n- [GitHub Repository](https://github.com/Tellarion/webmaxsocket)\r\n- [NPM Package](https://www.npmjs.com/package/webmaxsocket)\r\n\r\n## 📄 Лицензия / License\r\n\r\nMIT License - see LICENSE file for details\r\n\r\n## 👤 Автор / Author\r\n\r\nTellarion - [tellarion.dev](https://tellarion.dev)\r\n\r\n## 💝 Поддержка / Support\r\n\r\nЕсли вам нравится эта библиотека и вы хотите поддержать разработку:\r\n\r\n**USDT (TRC20):** `TXfs1iVbp2aLd3rbc4cenVzMoTevP5RbBE`\r\n\r\nСпасибо за вашу поддержку!","readmeFilename":"README.md"}