commit f778221f3c58cc14f412ce8032afc4a1e08dd155 Author: hugo Date: Sun Mar 15 15:46:07 2026 -0400 V1 diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..ab1f416 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/Emusks.iml b/.idea/Emusks.iml new file mode 100644 index 0000000..c956989 --- /dev/null +++ b/.idea/Emusks.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/emusks.iml b/.idea/emusks.iml new file mode 100644 index 0000000..c956989 --- /dev/null +++ b/.idea/emusks.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..30d19f3 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml new file mode 100644 index 0000000..f324872 --- /dev/null +++ b/.idea/php.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..3d33eba --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1581 @@ +{ + "name": "twitter-worker", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "twitter-worker", + "version": "1.0.0", + "dependencies": { + "axios": "^1.6.0", + "cycletls": "^2.0.5", + "express": "^4.18.2", + "js-yaml": "^4.1.0", + "x-client-transaction-id": "^0.1.9" + }, + "devDependencies": { + "nodemon": "^3.0.1" + } + }, + "node_modules/@types/node": { + "version": "20.19.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.37.tgz", + "integrity": "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "license": "MIT" + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "license": "MIT" + }, + "node_modules/cycletls": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cycletls/-/cycletls-2.0.5.tgz", + "integrity": "sha512-Nud94JBPZu1JTXWJ1GpIoQNR1xxU84WYt7G0dxzwpUe1xAAs6YbihvlQhIhPv9xljjonINJfWPFaeb8Ex1wLhQ==", + "license": "GPL3", + "dependencies": { + "@types/node": "^20.14.0", + "form-data": "^4.0.0", + "ws": "^8.17.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", + "content-type": "~1.0.4", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "~0.1.12", + "proxy-addr": "~2.0.7", + "qs": "~6.14.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "~0.19.0", + "serve-static": "~1.16.2", + "setprototypeof": "1.2.0", + "statuses": "~2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true, + "license": "ISC" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/linkedom": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.18.12.tgz", + "integrity": "sha512-jalJsOwIKuQJSeTvsgzPe9iJzyfVaEJiEXl+25EkKevsULHvMJzpNqwvj1jOESWdmgKDiXObyjOYwlUqG7wo1Q==", + "license": "ISC", + "dependencies": { + "css-select": "^5.1.0", + "cssom": "^0.5.0", + "html-escaper": "^3.0.3", + "htmlparser2": "^10.0.0", + "uhyphen": "^0.2.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "canvas": ">= 2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nodemon": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.14.tgz", + "integrity": "sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^10.2.1", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true, + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", + "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "dev": true, + "license": "ISC", + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/uhyphen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.2.0.tgz", + "integrity": "sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==", + "license": "ISC" + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true, + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/x-client-transaction-id": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/x-client-transaction-id/-/x-client-transaction-id-0.1.9.tgz", + "integrity": "sha512-CES4zgkJ0wbfFWm0qgdKphthyb+L7lVHymgOY15v6ivcWSx5p9lp5kzAed+BuqJSP7bS0GbQyJ16ONkRthgsUw==", + "license": "MIT", + "dependencies": { + "linkedom": "^0.18.9" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..680620e --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "twitter-worker", + "version": "1.0.0", + "type": "module", + "description": "Microservice Twitter API avec Emusks", + "main": "src/app.js", + "scripts": { + "start": "node src/app.js", + "dev": "node --watch src/app.js", + "test": "curl -X POST http://localhost:3000/api/twitter/call -H 'Authorization: Bearer test123' -H 'Content-Type: application/json' -d '{\"auth_token\":\"xxx\",\"domain\":\"twitter\",\"method\":\"verify\",\"args\":[]}'" + }, + "dependencies": { + "axios": "^1.6.0", + "cycletls": "^2.0.5", + "express": "^4.18.2", + "js-yaml": "^4.1.0", + "x-client-transaction-id": "^0.1.9" + }, + "devDependencies": { + "nodemon": "^3.0.1" + } +} diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..25c0484 --- /dev/null +++ b/src/app.js @@ -0,0 +1,255 @@ +import express from 'express'; +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import yaml from 'js-yaml'; +import Emusks from './emusks-local/index.js'; + +// --- GESTION DES CHEMINS (ES Modules) --- +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +// --- LECTURE DE LA CONFIGURATION (YAML ou JSON) --- +let config = {}; +const configPaths = [ + path.join(__dirname, 'config.yml'), + path.join(__dirname, 'config.yaml'), + path.join(__dirname, '../config.yml'), + path.join(process.cwd(), 'config.yml') +]; + +for (const configPath of configPaths) { + try { + if (fs.existsSync(configPath)) { + const fileContents = fs.readFileSync(configPath, 'utf8'); + config = yaml.load(fileContents); + console.log(`✅ Configuration chargée depuis : ${configPath}`); + break; + } + } catch (e) { + console.warn(`⚠️ Erreur lecture config ${configPath}: ${e.message}`); + } +} + +if (Object.keys(config).length === 0) { + console.warn("⚠️ Aucun fichier de configuration trouvé, utilisation des variables d'environnement."); +} + +// --- CONFIGURATION --- +const API_SECRET = config.api_secret || process.env.API_SECRET || 'secret_par_defaut'; +const PORT = config.port || process.env.PORT || 3000; +const NODE_ENV = process.env.NODE_ENV || 'development'; + +console.log(`🔧 Environment: ${NODE_ENV}`); +console.log(`🔐 API Secret configured: ${API_SECRET ? 'Yes' : 'No'}`); +console.log(`🚀 Port: ${PORT}`); + +// --- INITIALISATION EXPRESS --- +const app = express(); + +// Middleware pour parser le JSON (avec limite augmentée si besoin) +app.use(express.json({ limit: '10mb' })); + +// Logging des requêtes (seulement en dev) +if (NODE_ENV === 'development') { + app.use((req, res, next) => { + console.log(`[${new Date().toISOString()}] ${req.method} ${req.path}`); + next(); + }); +} + +// --- ENDPOINT DE SANTÉ (Health Check) --- +app.get('/health', (req, res) => { + res.json({ + status: 'ok', + service: 'twitter-worker', + timestamp: new Date().toISOString(), + environment: NODE_ENV + }); +}); + +// --- ENDPOINT RACINE --- +app.get('/', (req, res) => { + res.json({ + service: 'Twitter Worker API', + version: '1.0.0', + endpoints: { + health: 'GET /health', + call: 'POST /api/twitter/call' + } + }); +}); + +// --- MIDDLEWARE DE SÉCURITÉ --- +const authMiddleware = (req, res, next) => { + const authHeader = req.headers.authorization; + + if (!authHeader) { + return res.status(401).json({ + error: 'Non autorisé. Header Authorization manquant.', + required: 'Bearer ' + }); + } + + const [scheme, token] = authHeader.split(' '); + + if (scheme !== 'Bearer' || token !== API_SECRET) { + console.warn(`⚠️ Tentative d'accès non autorisé depuis ${req.ip}`); + return res.status(401).json({ + error: 'Non autorisé. Clé API invalide.' + }); + } + + next(); +}; + +// Appliquer l'authentification uniquement sur les routes API +app.use('/api', authMiddleware); + +// --- ENDPOINT PROXY DYNAMIQUE --- +app.post('/api/twitter/call', async (req, res) => { + const { auth_token, proxy, domain, method, args } = req.body; + + // Validation des paramètres requis + if (!auth_token) { + return res.status(400).json({ + error: "auth_token requis.", + hint: "Le token d'authentification Twitter est obligatoire." + }); + } + + if (!domain || !method) { + return res.status(400).json({ + error: "domain et method requis.", + hint: "Exemple: domain='twitter', method='search'" + }); + } + + console.log(`📡 Requête reçue: ${domain}.${method}()`); + + let client = null; + + try { + // Initialisation du client Emusks + client = new Emusks(); + + // Connexion avec les paramètres fournis + await client.login({ + auth_token, + proxy, + client: "web" + }); + + // Vérification que la méthode existe + if (!client[domain] || typeof client[domain][method] !== 'function') { + return res.status(400).json({ + error: `La méthode client.${domain}.${method}() n'existe pas.`, + available_domains: Object.keys(client).filter(k => typeof client[k] === 'object') + }); + } + + // Exécution de la méthode + const startTime = Date.now(); + const result = await client[domain][method](...(args || [])); + const duration = Date.now() - startTime; + + console.log(`✅ Succès: ${domain}.${method}() en ${duration}ms`); + + res.json({ + success: true, + data: result, + meta: { + duration_ms: duration, + timestamp: new Date().toISOString() + } + }); + + } catch (error) { + const duration = Date.now() - (startTime || Date.now()); + + console.error(`❌ [ERREUR] Action: ${domain}.${method}`); + console.error(` Message: ${error.message}`); + console.error(` Duration: ${duration}ms`); + + if (NODE_ENV === 'development') { + console.error(error.stack); + } + + res.status(500).json({ + success: false, + error: error.message || "Erreur interne du serveur", + details: error.response?.data || error.response?.body || null, + meta: { + duration_ms: duration, + timestamp: new Date().toISOString() + } + }); + } finally { + // Nettoyage si nécessaire + if (client && typeof client.logout === 'function') { + // optionnel: await client.logout(); + } + } +}); + +// --- GESTION DES ERREURS 404 --- +app.use((req, res) => { + res.status(404).json({ + error: 'Endpoint non trouvé', + path: req.path, + method: req.method, + available_endpoints: ['GET /', 'GET /health', 'POST /api/twitter/call'] + }); +}); + +// --- GESTION DES ERREURS GLOBALES --- +app.use((err, req, res, next) => { + console.error('🔥 Erreur globale:', err.message); + + res.status(500).json({ + success: false, + error: 'Erreur interne du serveur', + message: NODE_ENV === 'development' ? err.message : undefined + }); +}); + +// --- DÉMARRAGE DU SERVEUR --- +const server = app.listen(PORT, () => { + console.log(''); + console.log('╔════════════════════════════════════════════╗'); + console.log('║ 🐦 Twitter Worker API Démarrée ║'); + console.log('╠════════════════════════════════════════════╣'); + console.log(`║ 🌍 URL: http://localhost:${PORT} ║`); + console.log(`║ 🔐 Auth: Bearer ${API_SECRET.substring(0, 8)}... ║`); + console.log(`║ 🚀 Env: ${NODE_ENV.padEnd(28)}║`); + console.log('╚════════════════════════════════════════════╝'); + console.log(''); +}); + +// --- GESTION DES SIGNAUX POUR ARRÊT PROPRE --- +process.on('SIGTERM', () => { + console.log('📶 Signal SIGTERM reçu, fermeture en cours...'); + server.close(() => { + console.log('✅ Serveur fermé proprement'); + process.exit(0); + }); +}); + +process.on('SIGINT', () => { + console.log('📶 Signal SIGINT reçu (Ctrl+C), fermeture en cours...'); + server.close(() => { + console.log('✅ Serveur fermé proprement'); + process.exit(0); + }); +}); + +// Gestion des erreurs non capturées +process.on('uncaughtException', (err) => { + console.error('💥 Exception non capturée:', err); + process.exit(1); +}); + +process.on('unhandledRejection', (reason, promise) => { + console.error('💥 Rejection non gérée:', reason); + process.exit(1); +}); \ No newline at end of file diff --git a/src/config.yml b/src/config.yml new file mode 100644 index 0000000..74d5d76 --- /dev/null +++ b/src/config.yml @@ -0,0 +1,3 @@ +api_secret: test123 +port: 3000 +debug: true \ No newline at end of file diff --git a/src/emusks-local/clients.js b/src/emusks-local/clients.js new file mode 100644 index 0000000..60d5518 --- /dev/null +++ b/src/emusks-local/clients.js @@ -0,0 +1,62 @@ +const chrome_fingerprint = { + "user-agent": + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36", + ja3: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,35-5-27-16-0-10-13-23-45-65037-17613-18-65281-51-43-11,4588-29-23-24,0", + ja4r: "t13d1516h2_002f,0035,009c,009d,1301,1302,1303,c013,c014,c02b,c02c,c02f,c030,cca8,cca9_0005,000a,000b,000d,0012,0017,001b,0023,002b,002d,0033,44cd,fe0d,ff01_0403,0804,0401,0503,0805,0501,0806,0601", +}; + +const android_fingerprint = { + ja3: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,23-0-16-11-17613-27-43-35-13-65037-51-18-65281-45-5-10-41,4588-29-23-24,0", + ja4r: "t13d1517h2_002f,0035,009c,009d,1301,1302,1303,c013,c014,c02b,c02c,c02f,c030,cca8,cca9_0005,000a,000b,000d,0012,0017,001b,0023,0029,002b,002d,0033,44cd,fe0d,ff01_0403,0804,0401,0503,0805,0501,0806,0601", + + userAgent: "TwitterAndroid/10.93.0-release.00 (Android 14; Google Pixel 7 Pro)", +}; + +const iphone_fingerprint = { + ja3: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,23-0-16-11-17613-27-43-35-13-65037-51-18-65281-45-5-10-41,4588-29-23-24,0", + ja4r: "t13d1517h2_002f,0035,009c,009d,1301,1302,1303,c013,c014,c02b,c02c,c02f,c030,cca8,cca9_0005,000a,000b,000d,0012,0017,001b,0023,0029,002b,002d,0033,44cd,fe0d,ff01_0403,0804,0401,0503,0805,0501,0806,0601", + + userAgent: "Twitter-iPhone/10.93.0-release.00 (iPhone; iOS 16.5.1; Scale/3.00)", +}; + +export default { + android: { + // beware! this might get your account locked when tweeting + bearer: + "AAAAAAAAAAAAAAAAAAAAAFXzAwAAAAAAMHCxpeSDG1gLNLghVe8d74hl6k4%3DRUMF4xAQLsbeBhTSRrCiQpJtxoGWeyHrDb5te2jpGskWDFW82F", + fingerprints: android_fingerprint, + }, + iphone: { + bearer: + "AAAAAAAAAAAAAAAAAAAAAAj4AQAAAAAAPraK64zCZ9CSzdLesbE7LB%2Bw4uE%3DVJQREvQNCZJNiz3rHO7lOXlkVOQkzzdsgu6wWgcazdMUaGoUGm", + fingerprints: iphone_fingerprint, + }, + ipad: { + bearer: + "AAAAAAAAAAAAAAAAAAAAAGHtAgAAAAAA%2Bx7ILXNILCqkSGIzy6faIHZ9s3Q%3DQy97w6SIrzE7lQwPJEYQBsArEE2fC25caFwRBvAGi456G09vGR", + fingerprints: iphone_fingerprint, + }, + mac: { + bearer: + "AAAAAAAAAAAAAAAAAAAAAIWCCAAAAAAA2C25AxqI%2BYCS7pdfJKRH8Xh19zA%3D8vpDZzPHaEJhd20MKVWp3UR38YoPpuTX7UD2cVYo3YNikubuxd", + fingerprints: iphone_fingerprint, + }, + + old: { + // doesn't seem to work + bearer: + "AAAAAAAAAAAAAAAAAAAAAPYXBAAAAAAACLXUNDekMxqa8h%2F40K4moUkGsoc%3DTYfbDKbT3jJPCEVnMYqilB28NHfOPqkca3qaAxGfsyKCs0wRbw", + fingerprints: chrome_fingerprint, + }, + web: { + bearer: + "AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA", + fingerprints: chrome_fingerprint, + }, + tweetdeck: { + // requires premium + bearer: + "AAAAAAAAAAAAAAAAAAAAAFQODgEAAAAAVHTp76lzh3rFzcHbmHVvQxYYpTw%3DckAlMINMjmCwxUcaXbAN4XqJVdgMJaHqNOFgPMK0zN1qLqLQCF", + fingerprints: chrome_fingerprint, + }, +}; \ No newline at end of file diff --git a/src/emusks-local/cycletls.js b/src/emusks-local/cycletls.js new file mode 100644 index 0000000..e873e40 --- /dev/null +++ b/src/emusks-local/cycletls.js @@ -0,0 +1,26 @@ +import initCycleTLS from "cycletls"; + +let cycleTLS; + +initCycleTLS().then((c) => { + cycleTLS = c; +}); + +export default async function getCycleTLS() { + if (!cycleTLS) { + await new Promise((r) => { + const c = setInterval(() => { + if (cycleTLS) { + clearInterval(c); + r(); + } + }, 10); + }); + } + + return cycleTLS; +} + +process.on("exit", () => { + if (cycleTLS) cycleTLS.exit(); +}); diff --git a/src/emusks-local/flow.js b/src/emusks-local/flow.js new file mode 100644 index 0000000..e687f24 --- /dev/null +++ b/src/emusks-local/flow.js @@ -0,0 +1,399 @@ +import getCycleTLS from "./cycletls.js"; +import clients from "./clients.js"; + +const BASE_URL = "https://api.x.com/1.1/onboarding/task.json"; +const GUEST_ACTIVATE_URL = "https://api.x.com/1.1/guest/activate.json"; + +const USER_AGENT = + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36"; + +const SUBTASK_VERSIONS = { + action_list: 2, + alert_dialog: 1, + app_download_cta: 1, + check_logged_in_account: 2, + choice_selection: 3, + contacts_live_sync_permission_prompt: 0, + cta: 7, + email_verification: 2, + end_flow: 1, + enter_date: 1, + enter_email: 2, + enter_password: 5, + enter_phone: 2, + enter_recaptcha: 1, + enter_text: 5, + generic_urt: 3, + in_app_notification: 1, + interest_picker: 3, + js_instrumentation: 1, + menu_dialog: 1, + notifications_permission_prompt: 2, + open_account: 2, + open_home_timeline: 1, + open_link: 1, + phone_verification: 4, + privacy_options: 1, + security_key: 3, + select_avatar: 4, + select_banner: 2, + settings_list: 7, + show_code: 1, + sign_up: 2, + sign_up_review: 4, + tweet_selection_urt: 1, + update_users: 1, + upload_media: 1, + user_recommendations_list: 4, + user_recommendations_urt: 1, + wait_spinner: 3, + web_modal: 1, +}; + +const MAX_FLOW_STEPS = 20; + +class CookieSession { + constructor(cycleTLS, proxy) { + this.cycleTLS = cycleTLS; + this.cookies = {}; + this.proxy = proxy; + } + + getCookieString() { + return Object.entries(this.cookies) + .map(([k, v]) => `${k}=${v}`) + .join("; "); + } + + parseCookies(cookieValue) { + if (!cookieValue) return; + const cookies = Array.isArray(cookieValue) ? cookieValue : [cookieValue]; + for (const cookie of cookies) { + const parts = cookie.split(";")[0].split("="); + if (parts.length >= 2) { + this.cookies[parts[0].trim()] = parts.slice(1).join("=").trim(); + } + } + } + + async post(url, options = {}) { + const headers = options.headers || {}; + const cookieString = this.getCookieString(); + if (cookieString) { + headers["Cookie"] = cookieString; + } + + const response = await this.cycleTLS( + url, + { + body: options.json ? JSON.stringify(options.json) : options.body, + ja3: clients.web.fingerprints.ja3, + ja4r: clients.web.fingerprints.ja4r, + userAgent: USER_AGENT, + headers, + proxy: this.proxy || undefined, + }, + "post", + ); + + const setCookie = response.headers?.["Set-Cookie"] || response.headers?.["set-cookie"]; + if (setCookie) { + this.parseCookies(setCookie); + } + + return response; + } +} + +function getFlowHeaders(guestToken) { + const headers = { + Authorization: `Bearer ${clients.tweetdeck.bearer}`, + "Content-Type": "application/json", + Accept: "*/*", + "Accept-Language": "en-US", + "X-Twitter-Client-Language": "en-US", + Origin: "https://x.com", + Referer: "https://x.com/", + }; + if (guestToken) { + headers["X-Guest-Token"] = guestToken; + } + return headers; +} + +async function makeRequest(session, headers, flowToken, subtaskData) { + const payload = { + flow_token: flowToken, + subtask_inputs: Array.isArray(subtaskData) ? subtaskData : [subtaskData], + }; + + const response = await session.post(BASE_URL, { json: payload, headers }); + + if (response.status !== 200) { + const errorBody = + typeof response.body === "string" + ? response.body + : JSON.stringify(response.body || response.data); + throw new Error(`Flow request failed: ${response.status} - ${errorBody}`); + } + + const data = + typeof response.body === "string" ? JSON.parse(response.body) : response.body || response.data; + + const newFlowToken = data.flow_token; + if (!newFlowToken) { + throw new Error("Failed to get flow token from response"); + } + + return [newFlowToken, data]; +} + +async function getGuestToken(session) { + const response = await session.post(GUEST_ACTIVATE_URL, { + headers: { Authorization: `Bearer ${clients.tweetdeck.bearer}` }, + }); + + if (response.status !== 200) { + throw new Error("Failed to obtain guest token"); + } + + const data = + typeof response.body === "string" ? JSON.parse(response.body) : response.body || response.data; + + const guestToken = data.guest_token; + if (!guestToken) { + throw new Error("Failed to obtain guest token"); + } + + return guestToken; +} + +async function initFlow(session, guestToken) { + const headers = getFlowHeaders(guestToken); + const payload = { + input_flow_data: { + flow_context: { + debug_overrides: {}, + start_location: { location: "manual_link" }, + }, + subtask_versions: SUBTASK_VERSIONS, + }, + }; + + const response = await session.post(`${BASE_URL}?flow_name=login`, { + json: payload, + headers, + }); + + if (response.status !== 200) { + throw new Error("Failed to initialize login flow"); + } + + const data = + typeof response.body === "string" ? JSON.parse(response.body) : response.body || response.data; + + const flowToken = data.flow_token; + if (!flowToken) { + throw new Error("Failed to get initial flow token"); + } + + return [flowToken, headers, data]; +} + +async function submitJsInstrumentation(session, flowToken, headers) { + return await makeRequest(session, headers, flowToken, { + subtask_id: "LoginJsInstrumentationSubtask", + js_instrumentation: { + response: + '{"rf":{"a4fc506d24bb4843c48a1966940c2796bf4fb7617a2d515ad3297b7df6b459b6":121,"bff66e16f1d7ea28c04653dc32479cf416a9c8b67c80cb8ad533b2a44fee82a3":-1,"ac4008077a7e6ca03210159dbe2134dea72a616f03832178314bb9931645e4f7":-22,"c3a8a81a9b2706c6fec42c771da65a9597c537b8e4d9b39e8e58de9fe31ff239":-12},"s":"ZHYaDA9iXRxOl2J3AZ9cc23iJx-Fg5E82KIBA_fgeZFugZGYzRtf8Bl3EUeeYgsK30gLFD2jTQx9fAMsnYCw0j8ahEy4Pb5siM5zD6n7YgOeWmFFaXoTwaGY4H0o-jQnZi5yWZRAnFi4lVuCVouNz_xd2BO2sobCO7QuyOsOxQn2CWx7bjD8vPAzT5BS1mICqUWyjZDjLnRZJU6cSQG5YFIHEPBa8Kj-v1JFgkdAfAMIdVvP7C80HWoOqYivQR7IBuOAI4xCeLQEdxlGeT-JYStlP9dcU5St7jI6ExyMeQnRicOcxXLXsan8i5Joautk2M8dAJFByzBaG4wtrPhQ3QAAAZEi-_t7"}', + link: "next_link", + }, + }); +} + +async function submitUsername(session, flowToken, headers, username) { + const [newFlowToken, data] = await makeRequest(session, headers, flowToken, { + subtask_id: "LoginEnterUserIdentifierSSO", + settings_list: { + setting_responses: [ + { + key: "user_identifier", + response_data: { text_data: { result: username } }, + }, + ], + link: "next_link", + }, + }); + + if (data.subtasks?.[0]?.cta?.primary_text?.text) { + throw new Error(`Login denied: ${data.subtasks[0].cta.primary_text.text}`); + } + + return [newFlowToken, data]; +} + +async function submitPassword(session, flowToken, headers, password) { + return await makeRequest(session, headers, flowToken, { + subtask_id: "LoginEnterPassword", + enter_password: { password, link: "next_link" }, + }); +} + +async function submitAlternateIdentifier(session, flowToken, headers, text) { + return await makeRequest(session, headers, flowToken, { + subtask_id: "LoginEnterAlternateIdentifierSubtask", + enter_text: { text: text.trim(), link: "next_link" }, + }); +} + +async function submit2FA(session, flowToken, headers, code) { + return await makeRequest(session, headers, flowToken, { + subtask_id: "LoginTwoFactorAuthChallenge", + enter_text: { text: code.trim(), link: "next_link" }, + }); +} + +async function submitLoginAcid(session, flowToken, headers, code) { + return await makeRequest(session, headers, flowToken, { + subtask_id: "LoginAcid", + enter_text: { text: code.trim(), link: "next_link" }, + }); +} + +async function submitAccountDuplicationCheck(session, flowToken, headers) { + return await makeRequest(session, headers, flowToken, { + subtask_id: "AccountDuplicationCheck", + check_logged_in_account: { link: "AccountDuplicationCheck_false" }, + }); +} + +function getSubtaskIds(data) { + if (!data?.subtasks) return []; + return data.subtasks.map((s) => s.subtask_id); +} + +function isLoginComplete(data) { + if (!data?.subtasks) return false; + for (const subtask of data.subtasks) { + if (subtask.open_account || subtask.subtask_id === "LoginSuccessSubtask") { + return true; + } + } + return false; +} + +function extractUserId(cookies) { + const twid = (cookies.twid || "").replace(/"/g, ""); + for (const prefix of ["u=", "u%3D"]) { + if (twid.includes(prefix)) { + return twid.split(prefix)[1].split("&")[0].replace(/"/g, ""); + } + } + return null; +} + +async function resolve(staticValue, onRequest, type) { + if (staticValue) return staticValue; + + if (onRequest) { + const value = await onRequest(type); + if (value != null && value !== "") return value; + } + + throw new Error( + `the login flow is asking for "${type}" but no value was provided. either pass it directly or handle it in onRequest.`, + ); +} + +export default async function flowLogin(opts) { + const { username, password, email, phone, onRequest, proxy } = opts; + + if (!username) throw new Error("username is required for flow login"); + if (!password) throw new Error("password is required for flow login"); + + const cycleTLS = await getCycleTLS(); + const session = new CookieSession(cycleTLS, proxy); + + const guestToken = await getGuestToken(session); + + let [flowToken, headers, data] = await initFlow(session, guestToken); + headers["X-Guest-Token"] = guestToken; + + let step = 0; + + while (!isLoginComplete(data) && step < MAX_FLOW_STEPS) { + step++; + const subtaskIds = getSubtaskIds(data); + + if (subtaskIds.length === 0) { + throw new Error("Login flow returned no subtasks and login is not complete"); + } + + const current = subtaskIds[0]; + + switch (current) { + case "LoginJsInstrumentationSubtask": + [flowToken, data] = await submitJsInstrumentation(session, flowToken, headers); + break; + + case "LoginEnterUserIdentifierSSO": + [flowToken, data] = await submitUsername(session, flowToken, headers, username); + break; + + case "LoginEnterPassword": + [flowToken, data] = await submitPassword(session, flowToken, headers, password); + break; + + case "LoginEnterAlternateIdentifierSubtask": { + const value = await resolve(email || phone, onRequest, "alternate_identifier"); + [flowToken, data] = await submitAlternateIdentifier(session, flowToken, headers, value); + break; + } + + case "LoginTwoFactorAuthChallenge": { + const code = await resolve(null, onRequest, "two_factor_code"); + [flowToken, data] = await submit2FA(session, flowToken, headers, code); + break; + } + + case "LoginAcid": { + const code = await resolve(null, onRequest, "email_code"); + [flowToken, data] = await submitLoginAcid(session, flowToken, headers, code); + break; + } + + case "AccountDuplicationCheck": + [flowToken, data] = await submitAccountDuplicationCheck(session, flowToken, headers); + break; + + case "LoginSuccessSubtask": + break; + + case "DenyLoginSubtask": + throw new Error("Login was denied by Twitter. Your account may be locked or suspended."); + + default: + throw new Error( + `Unhandled login subtask: "${current}". All subtasks: [${subtaskIds.join(", ")}]`, + ); + } + } + + if (!isLoginComplete(data)) { + throw new Error( + `Login flow did not complete after ${MAX_FLOW_STEPS} steps. ` + + `Last subtasks: [${getSubtaskIds(data).join(", ")}]`, + ); + } + + const cookies = { ...session.cookies }; + const authToken = cookies.auth_token || null; + const csrfToken = cookies.ct0 || null; + const userId = extractUserId(cookies); + + if (!authToken) { + throw new Error("Login flow completed but no auth_token was found in cookies"); + } + + return { authToken, csrfToken, userId, cookies }; +} diff --git a/src/emusks-local/graphql.js b/src/emusks-local/graphql.js new file mode 100644 index 0000000..10ea9b0 --- /dev/null +++ b/src/emusks-local/graphql.js @@ -0,0 +1,148 @@ +import { ClientTransaction, handleXMigration } from "x-client-transaction-id"; +import getCycleTLS from "./cycletls.js"; +import graphqlApi from "./static/graphql.js"; + +const GRAPHQL_ENDPOINTS = { + main: { + base: "https://api.x.com/graphql", + referrer: "https://x.com/", + secFetchSite: "same-site", + }, + main_twitter: { + base: "https://api.twitter.com/graphql", + referrer: "https://twitter.com/", + secFetchSite: "same-site", + }, + web: { + base: "https://x.com/i/api/graphql", + referrer: "https://x.com/", + secFetchSite: "same-origin", + }, + web_twitter: { + base: "https://twitter.com/i/api/graphql", + referrer: "https://twitter.com/", + secFetchSite: "same-origin", + }, + tweetdeck: { + base: "https://pro.x.com/i/api/graphql", + referrer: "https://pro.x.com/", + secFetchSite: "same-origin", + }, + tweetdeck_twitter: { + base: "https://pro.twitter.com/i/api/graphql", + referrer: "https://pro.twitter.com/", + secFetchSite: "same-origin", + }, +}; + +export { GRAPHQL_ENDPOINTS }; + +export default async function graphql(queryName, { variables, fieldToggles, body, headers } = {}) { + const entry = graphqlApi[queryName]; + if (!entry) { + throw new Error(`graphql query ${queryName} not found`); + } + + const [method, , features, queryId] = entry; + const isPost = method.toLowerCase() === "post"; + + const endpointName = this.graphqlEndpoint || "web"; + const endpoint = GRAPHQL_ENDPOINTS[endpointName]; + if (!endpoint) { + throw new Error( + `unknown graphql endpoint "${endpointName}", expected: ${Object.keys(GRAPHQL_ENDPOINTS).join(", ")}`, + ); + } + + let finalUrl = `${endpoint.base}/${queryId}/${queryName}`; + let requestBody; + + if (isPost) { + requestBody = { + ...body, + variables: { ...variables, ...body?.variables }, + queryId, + }; + if (features) requestBody.features = features; + if (fieldToggles && Object.keys(fieldToggles).length) { + requestBody.fieldToggles = fieldToggles; + } + } else { + if (variables && Object.keys(variables).length) { + const separator = finalUrl.includes("?") ? "&" : "?"; + finalUrl = `${finalUrl}${separator}variables=${encodeURIComponent(JSON.stringify(variables))}`; + } + if (features) { + const separator = finalUrl.includes("?") ? "&" : "?"; + finalUrl = `${finalUrl}${separator}features=${encodeURIComponent(JSON.stringify(features))}`; + } + if (fieldToggles && Object.keys(fieldToggles).length) { + const separator = finalUrl.includes("?") ? "&" : "?"; + finalUrl = `${finalUrl}${separator}fieldToggles=${encodeURIComponent(JSON.stringify(fieldToggles))}`; + } + } + + const url = new URL(finalUrl); + const pathname = url.pathname; + + const useTransactionIds = + this.transactionIds !== undefined ? this.transactionIds : endpointName === "web"; + + const requestHeaders = { + accept: "*/*", + "accept-language": "en-US,en;q=0.9", + authorization: `Bearer ${this.auth.client.bearer}`, + "content-type": "application/json", + "x-csrf-token": this.auth.csrfToken, + "x-twitter-active-user": "yes", + "x-twitter-auth-type": "OAuth2Session", + "x-twitter-client-language": "en", + priority: "u=1, i", + "sec-ch-ua": '"Not(A:Brand";v="8", "Chromium";v="144"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"macOS"', + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": endpoint.secFetchSite, + "sec-gpc": "1", + cookie: + this.auth.client.headers.cookie + (this.elevatedCookies ? `; ${this.elevatedCookies}` : ""), + ...headers, + }; + + if (useTransactionIds) { + if (!this.auth.generateTransactionId) { + const document = await handleXMigration(); + const transaction = new ClientTransaction(document); + await transaction.initialize(); + this.auth.generateTransactionId = transaction.generateTransactionId.bind(transaction); + } + requestHeaders["x-client-transaction-id"] = await this.auth.generateTransactionId( + method.toUpperCase(), + pathname, + ); + } + + const cycleTLS = await getCycleTLS(); + const res = await ( + await cycleTLS( + finalUrl, + { + headers: requestHeaders, + userAgent: this.auth.client.fingerprints.userAgent, + ja3: this.auth.client.fingerprints.ja3, + ja4r: this.auth.client.fingerprints.ja4r, + body: isPost ? JSON.stringify(requestBody) : undefined, + proxy: this.proxy || undefined, + referrer: endpoint.referrer, + }, + method, + ) + ).json(); + + if (res?.errors?.[0]) { + throw new Error(res.errors.map((err) => err.message).join(", ")); + } + + return res; +} diff --git a/src/emusks-local/helpers/account.js b/src/emusks-local/helpers/account.js new file mode 100644 index 0000000..0c792cf --- /dev/null +++ b/src/emusks-local/helpers/account.js @@ -0,0 +1,269 @@ +import parseUser from "../parsers/user.js"; + +export async function settings() { + const res = await this.v1_1("get:account/settings", {}); + return await res.json(); +} + +export async function updateSettings(params = {}) { + const res = await this.v1_1("post:account/settings", { + body: JSON.stringify(params), + }); + return await res.json(); +} + +export async function verifyPassword(password) { + const res = await this.v1_1("account/verify_password", { + body: `password=${encodeURIComponent(password)}`, + headers: { "content-type": "application/x-www-form-urlencoded" }, + }); + return await res.json(); +} + +export async function changePassword(currentPassword, newPassword) { + const res = await this.v1_1("account/change_password", { + body: JSON.stringify({ + current_password: currentPassword, + password: newPassword, + password_confirmation: newPassword, + }), + }); + return await res.json(); +} + +export async function deactivate() { + const res = await this.v1_1("account/deactivate", {}); + return await res.json(); +} + +export async function logout() { + const res = await this.v1_1("account/logout", {}); + return await res.json(); +} + +export async function rateLimitStatus(params = {}) { + const res = await this.v1_1("application/rate_limit_status", { params }); + return await res.json(); +} + +export async function viewer() { + const res = await this.graphql("Viewer", { + variables: { withCommunitiesMemberships: true }, + fieldToggles: { withAuxiliaryUserLabels: false }, + }); + const user = res?.data?.viewer?.user_results?.result; + return user ? parseUser(user) : res; +} + +export async function sessions() { + return await this.graphql("UserSessionsList", { + variables: {}, + }); +} + +export async function preferences() { + return await this.graphql("UserPreferences", { + variables: {}, + }); +} + +export async function claims() { + return await this.graphql("GetUserClaims", { + variables: {}, + }); +} + +export async function phoneState() { + return await this.graphql("ProfileUserPhoneState", { + variables: {}, + }); +} + +export async function passwordStrength(password) { + const res = await this.v1_1("account/password_strength", { + body: JSON.stringify({ password }), + }); + return await res.json(); +} + +export async function resendConfirmationEmail() { + const res = await this.v1_1("account/resend_confirmation_email", {}); + return await res.json(); +} + +export async function emailPhoneInfo(params = {}) { + const res = await this.v1_1("users/email_phone_info", { params }); + return await res.json(); +} + +export async function emailAvailable(email) { + const res = await this.v1_1("users/email_available", { + params: { email }, + }); + return await res.json(); +} + +export async function phoneAvailable(phone) { + const res = await this.v1_1("users/phone_number_available", { + params: { phone_number: phone }, + }); + return await res.json(); +} + +export async function usernameAvailable(username) { + return await this.graphql("GetUsernameAvailabilityAndSuggestions", { + body: { variables: { username } }, + }); +} + +export async function backupCode() { + const res = await this.v1_1("get:account/backup_code", {}); + return await res.json(); +} + +export async function generateBackupCode() { + const res = await this.v1_1("post:account/backup_code", {}); + return await res.json(); +} + +export async function disable2FA() { + const res = await this.v1_1("account/login_verification_enrollment", {}); + return await res.json(); +} + +export async function remove2FAMethod(methodId) { + const res = await this.v1_1("account/login_verification/remove_method", { + body: JSON.stringify({ method_id: methodId }), + }); + return await res.json(); +} + +export async function tempPassword() { + const res = await this.v1_1("account/login_verification/temporary_password", {}); + return await res.json(); +} + +export async function renameSecurityKey(methodId, name) { + const res = await this.v1_1("account/login_verification/rename_security_key_method", { + body: JSON.stringify({ method_id: methodId, name }), + }); + return await res.json(); +} + +export async function connectedApps() { + const res = await this.v1_1("oauth/list", {}); + return await res.json(); +} + +export async function revokeApp(token) { + const res = await this.v1_1("oauth/revoke", { + body: JSON.stringify({ token }), + }); + return await res.json(); +} + +export async function deleteSSOConnection(connectionId) { + const res = await this.v1_1("sso/delete_connection", { + body: JSON.stringify({ connection_id: connectionId }), + }); + return await res.json(); +} + +export async function personalizationInterests() { + const res = await this.v1_1("account/personalization/twitter_interests", {}); + return await res.json(); +} + +export async function emailYourData() { + const res = await this.v1_1("account/personalization/email_your_data", {}); + return await res.json(); +} + +export async function multiList() { + const res = await this.v1_1("account/multi/list", {}); + return await res.json(); +} + +export async function enableVerifiedPhoneLabel() { + return await this.graphql("EnableVerifiedPhoneLabel", { + body: { variables: {} }, + }); +} + +export async function disableVerifiedPhoneLabel() { + return await this.graphql("DisableVerifiedPhoneLabel", { + body: { variables: {} }, + }); +} + +export async function dataSaverMode() { + return await this.graphql("DataSaverMode", { + variables: {}, + }); +} + +export async function setDataSaver(dataSaverMode) { + return await this.graphql("WriteDataSaverPreferences", { + body: { variables: { dataSaverMode } }, + }); +} + +export async function mutedKeywords() { + const res = await this.v1_1("mutes/keywords/list", {}); + return await res.json(); +} + +export async function deleteMutedKeyword(keywordId) { + const res = await this.v1_1("mutes/keywords/destroy", { + body: JSON.stringify({ ids: keywordId }), + }); + return await res.json(); +} + +export async function updateMutedKeyword(params = {}) { + const res = await this.v1_1("mutes/keywords/update", { + body: JSON.stringify(params), + }); + return await res.json(); +} + +export async function advancedFilters() { + const res = await this.v1_1("get:mutes/advanced_filters", {}); + return await res.json(); +} + +export async function updateAdvancedFilters(params = {}) { + const res = await this.v1_1("post:mutes/advanced_filters", { + body: JSON.stringify(params), + }); + return await res.json(); +} + +export async function helpSettings() { + const res = await this.v1_1("help/settings", {}); + return await res.json(); +} + +export async function emailNotificationSettings(params = {}) { + return await this.graphql("WriteEmailNotificationSettings", { + body: { variables: { ...params } }, + }); +} + +export async function viewerEmailSettings() { + return await this.graphql("ViewerEmailSettings", { + variables: {}, + }); +} + +export async function accountLabel() { + return await this.graphql("UserAccountLabel", { + variables: {}, + }); +} + +export async function disableAccountLabel() { + return await this.graphql("DisableUserAccountLabel", { + body: { variables: {} }, + }); +} diff --git a/src/emusks-local/helpers/bookmarks.js b/src/emusks-local/helpers/bookmarks.js new file mode 100644 index 0000000..ec504c7 --- /dev/null +++ b/src/emusks-local/helpers/bookmarks.js @@ -0,0 +1,118 @@ +import parseTimeline from "../parsers/timeline.js"; + +export async function create(tweetId) { + return await this.graphql("CreateBookmark", { + body: { variables: { tweet_id: tweetId } }, + }); +} + +export async function remove(tweetId) { + return await this.graphql("DeleteBookmark", { + body: { variables: { tweet_id: tweetId } }, + }); +} + +export async function deleteAll() { + return await this.graphql("BookmarksAllDelete", { + body: { variables: {} }, + }); +} + +export async function get(opts = {}) { + const raw = await this.graphql("Bookmarks", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); + return parseTimeline(raw); +} + +export async function search(query, opts = {}) { + const raw = await this.graphql("BookmarkSearchTimeline", { + variables: { + search_query: query, + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + ...opts.variables, + }, + }); + return parseTimeline(raw); +} + +export async function folders() { + return await this.graphql("BookmarkFoldersSlice", { + variables: {}, + }); +} + +export async function createFolder(name) { + return await this.graphql("createBookmarkFolder", { + body: { variables: { bookmark_collection_name: name } }, + }); +} + +export async function deleteFolder(folderId) { + return await this.graphql("DeleteBookmarkFolder", { + body: { variables: { bookmark_collection_id: folderId } }, + }); +} + +export async function editFolder(folderId, name) { + return await this.graphql("EditBookmarkFolder", { + body: { + variables: { + bookmark_collection_id: folderId, + bookmark_collection_name: name, + }, + }, + }); +} + +export async function addToFolder(tweetId, folderId) { + return await this.graphql("bookmarkTweetToFolder", { + body: { + variables: { + tweet_id: tweetId, + bookmark_collection_id: folderId, + }, + }, + }); +} + +export async function removeFromFolder(tweetId, folderId) { + return await this.graphql("RemoveTweetFromBookmarkFolder", { + body: { + variables: { + tweet_id: tweetId, + bookmark_collection_id: folderId, + }, + }, + }); +} + +export async function folderTimeline(folderId, opts = {}) { + const raw = await this.graphql("BookmarkFolderTimeline", { + variables: { + bookmark_collection_id: folderId, + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); + return parseTimeline(raw); +} diff --git a/src/emusks-local/helpers/communities.js b/src/emusks-local/helpers/communities.js new file mode 100644 index 0000000..bcab63f --- /dev/null +++ b/src/emusks-local/helpers/communities.js @@ -0,0 +1,269 @@ +export async function create(name, opts = {}) { + return await this.graphql("CreateCommunity", { + body: { + variables: { + name, + description: opts.description || "", + ...(opts.rules ? { rules: opts.rules } : {}), + ...opts.variables, + }, + }, + }); +} + +export async function get(communityId) { + return await this.graphql("CommunityByRestId", { + variables: { communityId }, + }); +} + +export async function join(communityId) { + return await this.graphql("JoinCommunity", { + body: { variables: { communityId } }, + }); +} + +export async function leave(communityId) { + return await this.graphql("LeaveCommunity", { + body: { variables: { communityId } }, + }); +} + +export async function requestJoin(communityId, opts = {}) { + return await this.graphql("RequestToJoinCommunity", { + body: { + variables: { + communityId, + ...(opts.answer ? { answer: opts.answer } : {}), + }, + }, + }); +} + +export async function timeline(communityId, opts = {}) { + return await this.graphql("CommunityTweetsTimeline", { + variables: { + communityId, + count: opts.count || 20, + cursor: opts.cursor, + rankingMode: opts.rankingMode || "Recency", + withCommunity: true, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); +} + +export async function media(communityId, opts = {}) { + return await this.graphql("CommunityMediaTimeline", { + variables: { + communityId, + count: opts.count || 20, + cursor: opts.cursor, + withCommunity: true, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); +} + +export async function about(communityId, opts = {}) { + return await this.graphql("CommunityAboutTimeline", { + variables: { + communityId, + count: opts.count || 20, + cursor: opts.cursor, + withCommunity: true, + ...opts.variables, + }, + }); +} + +export async function hashtags(communityId, opts = {}) { + return await this.graphql("CommunityHashtagsTimeline", { + variables: { + communityId, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function editName(communityId, name) { + return await this.graphql("CommunityEditName", { + body: { variables: { communityId, name } }, + }); +} + +export async function editPurpose(communityId, purpose) { + return await this.graphql("CommunityEditPurpose", { + body: { variables: { communityId, purpose } }, + }); +} + +export async function editBanner(communityId, mediaId) { + return await this.graphql("CommunityEditBannerMedia", { + body: { variables: { communityId, mediaId } }, + }); +} + +export async function removeBanner(communityId) { + return await this.graphql("CommunityRemoveBannerMedia", { + body: { variables: { communityId } }, + }); +} + +export async function createRule(communityId, name, opts = {}) { + return await this.graphql("CommunityCreateRule", { + body: { + variables: { + communityId, + name, + description: opts.description || "", + }, + }, + }); +} + +export async function editRule(communityId, ruleId, name, opts = {}) { + return await this.graphql("CommunityEditRule", { + body: { + variables: { + communityId, + ruleId, + name, + ...(opts.description !== undefined ? { description: opts.description } : {}), + }, + }, + }); +} + +export async function removeRule(communityId, ruleId) { + return await this.graphql("CommunityRemoveRule", { + body: { variables: { communityId, ruleId } }, + }); +} + +export async function reorderRules(communityId, ruleIds) { + return await this.graphql("CommunityReorderRules", { + body: { variables: { communityId, ruleIds } }, + }); +} + +export async function editQuestion(communityId, question) { + return await this.graphql("CommunityEditQuestion", { + body: { variables: { communityId, question } }, + }); +} + +export async function updateRole(communityId, userId, role) { + return await this.graphql("CommunityUpdateRole", { + body: { variables: { communityId, userId, role } }, + }); +} + +export async function invite(communityId, userId) { + return await this.graphql("CommunityUserInvite", { + body: { variables: { communityId, userId } }, + }); +} + +export async function keepTweet(communityId, tweetId) { + return await this.graphql("CommunityModerationKeepTweet", { + body: { variables: { communityId, tweetId } }, + }); +} + +export async function moderationCases(communityId, opts = {}) { + return await this.graphql("CommunityModerationTweetCasesSlice", { + variables: { + communityId, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function moderationLog(communityId, opts = {}) { + return await this.graphql("CommunityTweetModerationLogSlice", { + variables: { + communityId, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function explore(opts = {}) { + return await this.graphql("CommunitiesExploreTimeline", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function discover(opts = {}) { + return await this.graphql("CommunitiesMainDiscoveryModule", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function ranked(opts = {}) { + return await this.graphql("CommunitiesRankedTimeline", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function memberships(userId, opts = {}) { + return await this.graphql("CommunitiesMembershipsTimeline", { + variables: { + userId, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function memberSearch(communityId, query, opts = {}) { + return await this.graphql("CommunityMemberRelationshipTypeahead", { + variables: { + communityId, + query, + count: opts.count || 20, + ...opts.variables, + }, + }); +} + +export async function userSearch(communityId, query, opts = {}) { + return await this.graphql("CommunityUserRelationshipTypeahead", { + variables: { + communityId, + query, + count: opts.count || 20, + ...opts.variables, + }, + }); +} diff --git a/src/emusks-local/helpers/dms.js b/src/emusks-local/helpers/dms.js new file mode 100644 index 0000000..d7bcd97 --- /dev/null +++ b/src/emusks-local/helpers/dms.js @@ -0,0 +1,129 @@ +export async function inbox(params = {}) { + const res = await this.v1_1("dm/inbox_initial_state", { params }); + return await res.json(); +} + +export async function conversation(conversationId, params = {}) { + const res = await this.v1_1("dm/conversation", { + params: { id: conversationId, ...params }, + }); + return await res.json(); +} + +export async function search(query, opts = {}) { + return await this.graphql("DmAllSearchSlice", { + variables: { + query, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function searchGroups(query, opts = {}) { + return await this.graphql("DmGroupSearchSlice", { + variables: { + query, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function searchPeople(query, opts = {}) { + return await this.graphql("DmPeopleSearchSlice", { + variables: { + query, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function block(userId) { + return await this.graphql("dmBlockUser", { + body: { variables: { user_id: userId } }, + }); +} + +export async function unblock(userId) { + return await this.graphql("dmUnblockUser", { + body: { variables: { user_id: userId } }, + }); +} + +export async function deleteConversations(conversationIds) { + const ids = Array.isArray(conversationIds) ? conversationIds : [conversationIds]; + const res = await this.v1_1("dm/conversation/bulk_delete", { + body: JSON.stringify({ conversation_ids: ids }), + }); + return await res.json(); +} + +export async function updateLastSeen(eventId) { + const res = await this.v1_1("dm/update_last_seen_event_id", { + body: JSON.stringify({ last_seen_event_id: eventId, trusted_last_seen_event_id: eventId }), + }); + return await res.json(); +} + +export async function muted(opts = {}) { + return await this.graphql("DmMutedTimeline", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function edit(messageId, conversationId, text) { + const res = await this.v1_1("dm/edit", { + body: JSON.stringify({ + message_id: messageId, + conversation_id: conversationId, + text, + }), + }); + return await res.json(); +} + +export async function permissions(params = {}) { + const res = await this.v1_1("dm/permissions", { params }); + return await res.json(); +} + +export async function nsfwFilter(enabled) { + return await this.graphql("DmNsfwMediaFilterUpdate", { + body: { variables: { enabled } }, + }); +} + +export async function updateRelationship(userId, action) { + const res = await this.v1_1("dm/user/update_relationship_state", { + body: JSON.stringify({ user_id: userId, action }), + }); + return await res.json(); +} + +export async function reportSpam(conversationId, messageId) { + const res = await this.v1_1("direct_messages/report_spam", { + body: JSON.stringify({ conversation_id: conversationId, message_id: messageId }), + }); + return await res.json(); +} + +export async function report(conversationId, messageId) { + const res = await this.v1_1("dm/report", { + body: JSON.stringify({ conversation_id: conversationId, message_id: messageId }), + }); + return await res.json(); +} + +export async function userUpdates(params = {}) { + const res = await this.v1_1("dm/user_updates", { params }); + return await res.json(); +} diff --git a/src/emusks-local/helpers/index.js b/src/emusks-local/helpers/index.js new file mode 100644 index 0000000..bc8269f --- /dev/null +++ b/src/emusks-local/helpers/index.js @@ -0,0 +1,51 @@ +import * as account from "./account.js"; +import * as bookmarks from "./bookmarks.js"; +import * as communities from "./communities.js"; +import * as dms from "./dms.js"; +import * as lists from "./lists.js"; +import * as media from "./media.js"; +import * as notifications from "./notifications.js"; +import * as search from "./search.js"; +import * as spaces from "./spaces.js"; +import * as syndication from "./syndication.js"; +import * as timelines from "./timelines.js"; +import * as topics from "./topics.js"; +import * as trends from "./trends.js"; +import * as tweets from "./tweets.js"; +import * as users from "./users.js"; + +function namespace(proto, name, methods) { + Object.defineProperty(proto, name, { + get() { + const bound = {}; + for (const [k, fn] of Object.entries(methods)) { + if (typeof fn === "function") bound[k] = fn.bind(this); + } + Object.defineProperty(this, name, { + value: bound, + writable: true, + configurable: true, + }); + return bound; + }, + configurable: true, + }); +} + +export default function initHelpers(proto) { + namespace(proto, "tweets", tweets); + namespace(proto, "users", users); + namespace(proto, "timelines", timelines); + namespace(proto, "bookmarks", bookmarks); + namespace(proto, "dms", dms); + namespace(proto, "lists", lists); + namespace(proto, "communities", communities); + namespace(proto, "search", search); + namespace(proto, "spaces", spaces); + namespace(proto, "account", account); + namespace(proto, "notifications", notifications); + namespace(proto, "trends", trends); + namespace(proto, "topics", topics); + namespace(proto, "media", media); + namespace(proto, "syndication", syndication); +} diff --git a/src/emusks-local/helpers/lists.js b/src/emusks-local/helpers/lists.js new file mode 100644 index 0000000..6a67209 --- /dev/null +++ b/src/emusks-local/helpers/lists.js @@ -0,0 +1,227 @@ +export async function create(name, opts = {}) { + return await this.graphql("CreateList", { + body: { + variables: { + isPrivate: opts.private || false, + name, + description: opts.description || "", + }, + }, + }); +} + +export async function remove(listId) { + return await this.graphql("DeleteList", { + body: { variables: { listId } }, + }); +} + +export async function update(listId, opts = {}) { + return await this.graphql("UpdateList", { + body: { + variables: { + listId, + ...(opts.name !== undefined ? { name: opts.name } : {}), + ...(opts.description !== undefined ? { description: opts.description } : {}), + ...(opts.private !== undefined ? { isPrivate: opts.private } : {}), + }, + }, + }); +} + +export async function get(listId) { + return await this.graphql("ListByRestId", { + variables: { listId }, + }); +} + +export async function getBySlug(slug, opts = {}) { + return await this.graphql("ListBySlug", { + variables: { slug, listOwnerScreenName: opts.ownerScreenName || "" }, + }); +} + +export async function addMember(listId, userId) { + return await this.graphql("ListAddMember", { + body: { variables: { listId, userId } }, + }); +} + +export async function removeMember(listId, userId) { + return await this.graphql("ListRemoveMember", { + body: { variables: { listId, userId } }, + }); +} + +export async function members(listId, opts = {}) { + return await this.graphql("ListMembers", { + variables: { + listId, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function subscribers(listId, opts = {}) { + return await this.graphql("ListSubscribers", { + variables: { + listId, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function subscribe(listId) { + return await this.graphql("ListSubscribe", { + body: { variables: { listId } }, + }); +} + +export async function unsubscribe(listId) { + return await this.graphql("ListUnsubscribe", { + body: { variables: { listId } }, + }); +} + +export async function mute(listId) { + return await this.graphql("MuteList", { + body: { variables: { listId } }, + }); +} + +export async function unmute(listId) { + return await this.graphql("UnmuteList", { + body: { variables: { listId } }, + }); +} + +export async function timeline(listId, opts = {}) { + return await this.graphql("ListLatestTweetsTimeline", { + variables: { + listId, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); +} + +export async function ranked(listId, opts = {}) { + return await this.graphql("ListRankedTweetsTimeline", { + variables: { + listId, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); +} + +export async function search(listId, query, opts = {}) { + return await this.graphql("ListSearchTimeline", { + variables: { + listId, + search_query: query, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function ownerships(userId, opts = {}) { + return await this.graphql("ListOwnerships", { + variables: { + userId, + count: opts.count || 20, + cursor: opts.cursor, + isCreator: true, + ...opts.variables, + }, + }); +} + +export async function listMemberships(userId, opts = {}) { + return await this.graphql("ListMemberships", { + variables: { + userId, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function discover(opts = {}) { + return await this.graphql("ListsDiscovery", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function combined(opts = {}) { + return await this.graphql("CombinedLists", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function manage(opts = {}) { + return await this.graphql("ListsManagementPageTimeline", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function editBanner(listId, mediaId) { + return await this.graphql("EditListBanner", { + body: { variables: { listId, mediaId } }, + }); +} + +export async function deleteBanner(listId) { + return await this.graphql("DeleteListBanner", { + body: { variables: { listId } }, + }); +} + +export async function pinTimeline(timelineId) { + return await this.graphql("PinTimeline", { + body: { variables: { timeline_id: timelineId } }, + }); +} + +export async function unpinTimeline(timelineId) { + return await this.graphql("UnpinTimeline", { + body: { variables: { timeline_id: timelineId } }, + }); +} + +export async function pinned() { + return await this.graphql("PinnedTimelines", { + variables: {}, + }); +} diff --git a/src/emusks-local/helpers/media.js b/src/emusks-local/helpers/media.js new file mode 100644 index 0000000..f191ba9 --- /dev/null +++ b/src/emusks-local/helpers/media.js @@ -0,0 +1,289 @@ +import { readFile } from "fs/promises"; +import { extname } from "path"; +import getCycleTLS from "../cycletls.js"; + +const UPLOAD_URL = "https://upload.twitter.com/i/media/upload.json"; +const CHUNK_SIZE = 4 * 1024 * 1024; // 4 MB + +const MAX_IMAGE_SIZE = 5 * 1024 * 1024; // 5 MB +const MAX_GIF_SIZE = 15 * 1024 * 1024; // 15 MB +const MAX_VIDEO_SIZE = 512 * 1024 * 1024; // 512 MB + +const MIME_BY_EXT = { + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".png": "image/png", + ".gif": "image/gif", + ".webp": "image/webp", + ".mp4": "video/mp4", + ".mov": "video/quicktime", + ".webm": "video/webm", + ".avi": "video/x-msvideo", +}; + +function detectMediaType(buf) { + if (buf[0] === 0xff && buf[1] === 0xd8) return "image/jpeg"; + if (buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47) return "image/png"; + if (buf[0] === 0x47 && buf[1] === 0x49 && buf[2] === 0x46) return "image/gif"; + if ( + buf[0] === 0x52 && + buf[1] === 0x49 && + buf[2] === 0x46 && + buf[3] === 0x46 && + buf[8] === 0x57 && + buf[9] === 0x45 && + buf[10] === 0x42 && + buf[11] === 0x50 + ) + return "image/webp"; + if (buf.length > 7 && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70) + return "video/mp4"; + if (buf[0] === 0x1a && buf[1] === 0x45 && buf[2] === 0xdf && buf[3] === 0xa3) return "video/webm"; + return null; +} + +function getMediaCategory(mediaType, uploadType) { + if (mediaType === "image/gif") return `${uploadType}_gif`; + if (mediaType.startsWith("video/")) return `${uploadType}_video`; + if (mediaType.startsWith("image/")) return `${uploadType}_image`; + throw new Error(`unsupported media type: ${mediaType}`); +} + +function checkMediaSize(category, size) { + const fmt = (x) => `${(x / 1e6).toFixed(2)} MB`; + if (category.includes("image") && !category.includes("gif") && size > MAX_IMAGE_SIZE) + throw new Error(`cannot upload ${fmt(size)} image \u2014 max is ${fmt(MAX_IMAGE_SIZE)}`); + if (category.includes("gif") && size > MAX_GIF_SIZE) + throw new Error(`cannot upload ${fmt(size)} gif \u2014 max is ${fmt(MAX_GIF_SIZE)}`); + if (category.includes("video") && size > MAX_VIDEO_SIZE) + throw new Error(`cannot upload ${fmt(size)} video \u2014 max is ${fmt(MAX_VIDEO_SIZE)}`); +} + +async function makeUploadRequest(instance, method, params, body, extraHeaders = {}) { + const cycleTLS = await getCycleTLS(); + const url = `${UPLOAD_URL}?${new URLSearchParams(params).toString()}`; + + const headers = { + accept: "*/*", + "accept-language": "en-US,en;q=0.9", + authorization: `Bearer ${instance.auth.client.bearer}`, + "x-csrf-token": instance.auth.csrfToken, + "x-twitter-active-user": "yes", + "x-twitter-auth-type": "OAuth2Session", + "x-twitter-client-language": "en", + priority: "u=1, i", + "sec-ch-ua": "Not(A:Brand;v=8, Chromium;v=144", + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": "macOS", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-site", + "sec-gpc": "1", + cookie: + instance.auth.client.headers.cookie + + (instance.elevatedCookies ? `; ${instance.elevatedCookies}` : ""), + ...extraHeaders, + }; + + return await cycleTLS( + url, + { + headers, + userAgent: + instance.auth.client.fingerprints?.userAgent || + instance.auth.client.fingerprints?.["user-agent"], + ja3: instance.auth.client.fingerprints?.ja3, + ja4r: instance.auth.client.fingerprints?.ja4r, + body: body || undefined, + proxy: instance.proxy || undefined, + referrer: "https://x.com/", + }, + method, + ); +} + +export async function create(source, opts = {}) { + if (!this.auth) throw new Error("you must be logged in to upload media"); + + let buf; + let mediaType = opts.mediaType; + + if (typeof source === "string") { + buf = await readFile(source); + if (!mediaType) mediaType = MIME_BY_EXT[extname(source).toLowerCase()]; + } else if (typeof Blob !== "undefined" && source instanceof Blob) { + buf = Buffer.from(await source.arrayBuffer()); + if (!mediaType) mediaType = source.type || undefined; + } else if (source instanceof ArrayBuffer || source instanceof SharedArrayBuffer) { + buf = Buffer.from(source); + } else if (Buffer.isBuffer(source) || source instanceof Uint8Array) { + buf = Buffer.from(source); + } else { + throw new Error( + "source must be a file path (string), Buffer, Uint8Array, ArrayBuffer, or Blob", + ); + } + + if (!mediaType) mediaType = detectMediaType(buf); + if (!mediaType) + throw new Error("could not detect media type \u2014 pass opts.mediaType (e.g. 'image/png')"); + + const totalBytes = buf.length; + const uploadType = opts.type === "dm" ? "dm" : "tweet"; + const category = getMediaCategory(mediaType, uploadType); + checkMediaSize(category, totalBytes); + + const initRes = await makeUploadRequest(this, "post", { + command: "INIT", + media_type: mediaType, + total_bytes: totalBytes.toString(), + media_category: category, + }); + + const initData = await initRes.json(); + if (!initData?.media_id_string) { + throw new Error(`upload INIT failed: ${JSON.stringify(initData)}`); + } + const mediaId = initData.media_id_string; + + let segmentIndex = 0; + for (let offset = 0; offset < totalBytes; offset += CHUNK_SIZE) { + const chunk = buf.slice(offset, Math.min(offset + CHUNK_SIZE, totalBytes)); + const base64 = chunk.toString("base64"); + + await makeUploadRequest( + this, + "post", + { + command: "APPEND", + media_id: mediaId, + segment_index: segmentIndex.toString(), + }, + `media_data=${encodeURIComponent(base64)}`, + { "content-type": "application/x-www-form-urlencoded" }, + ); + segmentIndex++; + } + + const finalizeRes = await makeUploadRequest(this, "post", { + command: "FINALIZE", + media_id: mediaId, + allow_async: "true", + }); + + const finalizeData = await finalizeRes.json(); + if (finalizeData?.error) { + throw new Error(`upload FINALIZE failed: ${JSON.stringify(finalizeData)}`); + } + + let processingInfo = finalizeData?.processing_info; + while (processingInfo) { + if (processingInfo.error) { + throw new Error(`media processing error: ${JSON.stringify(processingInfo.error)}`); + } + if (processingInfo.state === "succeeded") break; + if (processingInfo.state === "failed") { + throw new Error(`media processing failed: ${JSON.stringify(processingInfo)}`); + } + + const wait = (processingInfo.check_after_secs || 2) * 1000; + await new Promise((r) => setTimeout(r, wait)); + + const statusRes = await makeUploadRequest(this, "get", { + command: "STATUS", + media_id: mediaId, + }); + const statusData = await statusRes.json(); + processingInfo = statusData?.processing_info; + } + + if (opts.alt_text) { + await this.v1_1("media/metadata/create", { + body: JSON.stringify({ + media_id: mediaId, + alt_text: { text: opts.alt_text }, + }), + }); + } + + return { media_id: mediaId, ...finalizeData }; +} + +export async function createFromUrl(url, opts = {}) { + if (!this.auth) throw new Error("you must be logged in to upload media"); + + const mediaType = opts.mediaType || "image/gif"; + const uploadType = opts.type === "dm" ? "dm" : "tweet"; + const category = opts.mediaCategory || getMediaCategory(mediaType, uploadType); + + const initRes = await makeUploadRequest(this, "post", { + command: "INIT", + source_url: url, + media_type: mediaType, + media_category: category, + }); + + const initData = await initRes.json(); + if (!initData?.media_id_string) { + throw new Error(`upload INIT failed: ${JSON.stringify(initData)}`); + } + const mediaId = initData.media_id_string; + + let processingInfo = initData?.processing_info; + while (processingInfo) { + if (processingInfo.error) { + throw new Error(`media processing error: ${JSON.stringify(processingInfo.error)}`); + } + if (processingInfo.state === "succeeded") break; + if (processingInfo.state === "failed") { + throw new Error(`media processing failed: ${JSON.stringify(processingInfo)}`); + } + + const wait = (processingInfo.check_after_secs || 2) * 1000; + await new Promise((r) => setTimeout(r, wait)); + + const statusRes = await makeUploadRequest(this, "get", { + command: "STATUS", + media_id: mediaId, + }); + const statusData = await statusRes.json(); + processingInfo = statusData?.processing_info; + } + + const metadataBody = { media_id: mediaId }; + const altText = opts.altText || opts.alt_text; + if (altText) metadataBody.alt_text = { text: altText }; + if (opts.origin) metadataBody.found_media_origin = opts.origin; + + if (altText || opts.origin) { + await this.v1_1("media/metadata/create", { + body: JSON.stringify(metadataBody), + }); + } + + return { media_id: mediaId, ...initData }; +} + +export async function createMetadata(mediaId, altText, opts = {}) { + const res = await this.v1_1("media/metadata/create", { + body: JSON.stringify({ + media_id: mediaId, + alt_text: { text: altText }, + ...opts, + }), + }); + return await res.json(); +} + +export async function createSubtitles(mediaId, subtitles) { + const res = await this.v1_1("media/subtitles/create", { + body: JSON.stringify({ + media_id: mediaId, + media_category: "tweet_video", + subtitle_info: { + subtitles: Array.isArray(subtitles) ? subtitles : [subtitles], + }, + }), + }); + return await res.json(); +} diff --git a/src/emusks-local/helpers/notifications.js b/src/emusks-local/helpers/notifications.js new file mode 100644 index 0000000..52a1efb --- /dev/null +++ b/src/emusks-local/helpers/notifications.js @@ -0,0 +1,48 @@ +export async function timeline(opts = {}) { + return await this.graphql("NotificationsTimeline", { + variables: { + timeline_type: opts.timeline_type || "All", + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); +} + +export async function enableWebNotifications() { + return await this.graphql("EnableLoggedOutWebNotifications", { + body: { variables: {} }, + }); +} + +export async function saveSettings(params = {}) { + const res = await this.v1_1("notifications/settings/save", { + body: JSON.stringify(params), + }); + return await res.json(); +} + +export async function loginSettings(params = {}) { + const res = await this.v1_1("notifications/settings/login", { + body: JSON.stringify(params), + }); + return await res.json(); +} + +export async function checkin(params = {}) { + const res = await this.v1_1("notifications/settings/checkin", { + body: JSON.stringify(params), + }); + return await res.json(); +} + +export async function badge(params = {}) { + const res = await this.v2("badge_count/badge_count", { params }); + return await res.json(); +} diff --git a/src/emusks-local/helpers/search.js b/src/emusks-local/helpers/search.js new file mode 100644 index 0000000..0b96d06 --- /dev/null +++ b/src/emusks-local/helpers/search.js @@ -0,0 +1,142 @@ +import parseTimeline from "../parsers/timeline.js"; + +export async function tweets(query, opts = {}) { + const raw = await this.graphql("SearchTimeline", { + variables: { + rawQuery: query, + count: opts.count || 20, + cursor: opts.cursor, + querySource: opts.querySource || "typed_query", + product: opts.product || "Top", + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); + return parseTimeline(raw); +} + +export async function users(query, opts = {}) { + const raw = await this.graphql("SearchTimeline", { + variables: { + rawQuery: query, + count: opts.count || 20, + cursor: opts.cursor, + querySource: opts.querySource || "typed_query", + product: "People", + ...opts.variables, + }, + }); + return parseTimeline(raw); +} + +export async function media(query, opts = {}) { + const raw = await this.graphql("SearchTimeline", { + variables: { + rawQuery: query, + count: opts.count || 20, + cursor: opts.cursor, + querySource: opts.querySource || "typed_query", + product: "Media", + ...opts.variables, + }, + }); + return parseTimeline(raw); +} + +export async function latest(query, opts = {}) { + const raw = await this.graphql("SearchTimeline", { + variables: { + rawQuery: query, + count: opts.count || 20, + cursor: opts.cursor, + querySource: opts.querySource || "typed_query", + product: "Latest", + ...opts.variables, + }, + }); + return parseTimeline(raw); +} + +export async function lists(query, opts = {}) { + const raw = await this.graphql("SearchTimeline", { + variables: { + rawQuery: query, + count: opts.count || 20, + cursor: opts.cursor, + querySource: opts.querySource || "typed_query", + product: "Lists", + ...opts.variables, + }, + }); + return parseTimeline(raw); +} + +export async function typeahead(query, params = {}) { + const res = await this.v1_1("search/typeahead", { + params: { + q: query, + src: params.src || "search_box", + result_type: params.result_type || "events,users,topics,lists", + ...params, + }, + }); + return await res.json(); +} + +export async function adaptive(query, params = {}) { + const res = await this.v2("search/adaptive", { + params: { + q: query, + count: params.count || 20, + query_source: params.query_source || "typed_query", + pc: params.pc || 1, + spelling_corrections: params.spelling_corrections || 1, + include_ext_edit_control: true, + ...params, + }, + }); + return await res.json(); +} + +export async function communities(query, opts = {}) { + const raw = await this.graphql("GlobalCommunitiesPostSearchTimeline", { + variables: { + rawQuery: query, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); + return parseTimeline(raw); +} + +export async function gifs(query, params = {}) { + const res = await this.v1_1("foundmedia/search", { + params: { + q: query, + ...(params.cursor ? { cursor: params.cursor } : {}), + ...params, + }, + }); + const json = await res.json(); + return { + items: json.data?.items || [], + cursor: json.cursor?.next || null, + }; +} + +export async function communitiesLatest(query, opts = {}) { + const raw = await this.graphql("GlobalCommunitiesLatestPostSearchTimeline", { + variables: { + rawQuery: query, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); + return parseTimeline(raw); +} diff --git a/src/emusks-local/helpers/spaces.js b/src/emusks-local/helpers/spaces.js new file mode 100644 index 0000000..a53e139 --- /dev/null +++ b/src/emusks-local/helpers/spaces.js @@ -0,0 +1,53 @@ +export async function get(spaceId) { + return await this.graphql("AudioSpaceById", { + variables: { + id: spaceId, + isMetatagsQuery: false, + withReplays: true, + withListeners: true, + }, + }); +} + +export async function search(query, opts = {}) { + return await this.graphql("AudioSpaceSearch", { + variables: { + query, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function browseTopics(opts = {}) { + return await this.graphql("BrowseSpaceTopics", { + variables: { + ...opts.variables, + }, + }); +} + +export async function subscribe(spaceId) { + return await this.graphql("SubscribeToScheduledSpace", { + body: { variables: { space_id: spaceId } }, + }); +} + +export async function unsubscribe(spaceId) { + return await this.graphql("UnsubscribeFromScheduledSpace", { + body: { variables: { space_id: spaceId } }, + }); +} + +export async function addSharing(spaceId) { + return await this.graphql("AudioSpaceAddSharing", { + body: { variables: { space_id: spaceId } }, + }); +} + +export async function deleteSharing(spaceId) { + return await this.graphql("AudioSpaceDeleteSharing", { + body: { variables: { space_id: spaceId } }, + }); +} diff --git a/src/emusks-local/helpers/syndication.js b/src/emusks-local/helpers/syndication.js new file mode 100644 index 0000000..17b8a42 --- /dev/null +++ b/src/emusks-local/helpers/syndication.js @@ -0,0 +1,31 @@ +import getCycleTLS from "../cycletls.js"; + +export async function getTweet(tweetId) { + const token = ((Number(tweetId) / 1e15) * Math.PI).toString(36).replace(/(0+|\.)/g, ""); + + const features = "tfw_timeline_list:;tfw_tweet_edit_backend:on;tfw_refsrc_session:on;tfw_fosnr_soft_interventions_enabled:on;tfw_mixed_media_15897:treatment;tfw_experiments_cookie_expiration:1209600;tfw_show_birdwatch_pivots_enabled:on;tfw_duplicate_scribes_to_settings:on;tfw_use_profile_image_shape_enabled:on;tfw_video_hls_dynamic_manifests_15082:true_bitrate;tfw_tweet_edit_frontend:on"; + + const url = `https://cdn.syndication.twimg.com/tweet-result?id=${tweetId}&lang=en&token=${token}&features=${encodeURIComponent(features)}`; + + try { + const cycleTLS = await getCycleTLS(); + + const res = await cycleTLS(url, { + headers: { + accept: "application/json, text/plain, */*", + }, + userAgent: this.auth?.client?.fingerprints?.userAgent, + ja3: this.auth?.client?.fingerprints?.ja3, + ja4r: this.auth?.client?.fingerprints?.ja4r, + proxy: this.proxy || undefined, + timeout: 3000, + }, "GET"); + + if (!res || res.status !== 200) return null; + + return await res.json(); + } catch (e) { + console.warn(e); + return null; + } +} \ No newline at end of file diff --git a/src/emusks-local/helpers/timelines.js b/src/emusks-local/helpers/timelines.js new file mode 100644 index 0000000..81b2df8 --- /dev/null +++ b/src/emusks-local/helpers/timelines.js @@ -0,0 +1,82 @@ +import parseTimeline from "../parsers/timeline.js"; + +export async function home(opts = {}) { + const raw = await this.graphql("HomeTimeline", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: true, + latestControlAvailable: true, + requestContext: "launch", + withCommunity: true, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); + return parseTimeline(raw); +} + +export async function homeLatest(opts = {}) { + const raw = await this.graphql("HomeLatestTimeline", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: true, + latestControlAvailable: true, + requestContext: "launch", + withCommunity: true, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); + return parseTimeline(raw); +} + +export async function connect(opts = {}) { + const raw = await this.graphql("ConnectTabTimeline", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + context: "{}", + ...opts.variables, + }, + }); + return parseTimeline(raw); +} + +export async function moderated(opts = {}) { + const raw = await this.graphql("ModeratedTimeline", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); + return parseTimeline(raw); +} + +export async function creatorSubscriptions(opts = {}) { + const raw = await this.graphql("CreatorSubscriptionsTimeline", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + ...opts.variables, + }, + }); + return parseTimeline(raw); +} diff --git a/src/emusks-local/helpers/topics.js b/src/emusks-local/helpers/topics.js new file mode 100644 index 0000000..a178131 --- /dev/null +++ b/src/emusks-local/helpers/topics.js @@ -0,0 +1,97 @@ +export async function follow(topicId) { + return await this.graphql("TopicFollow", { + body: { variables: { topic_id: topicId } }, + }); +} + +export async function unfollow(topicId) { + return await this.graphql("TopicUnfollow", { + body: { variables: { topic_id: topicId } }, + }); +} + +export async function notInterested(topicId) { + return await this.graphql("TopicNotInterested", { + body: { variables: { topic_id: topicId } }, + }); +} + +export async function undoNotInterested(topicId) { + return await this.graphql("TopicUndoNotInterested", { + body: { variables: { topic_id: topicId } }, + }); +} + +export async function get(topicId) { + return await this.graphql("TopicByRestId", { + variables: { topicId }, + }); +} + +export async function landingPage(topicId, opts = {}) { + return await this.graphql("TopicLandingPage", { + variables: { + topicId, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); +} + +export async function toFollow(opts = {}) { + return await this.graphql("TopicToFollowSidebar", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function manage(opts = {}) { + return await this.graphql("TopicsManagementPage", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function picker(opts = {}) { + return await this.graphql("TopicsPickerPage", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function pickerById(topicId, opts = {}) { + return await this.graphql("TopicsPickerPageById", { + variables: { + topicId, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function viewing(userId, opts = {}) { + return await this.graphql("ViewingOtherUsersTopicsPage", { + variables: { + userId, + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} diff --git a/src/emusks-local/helpers/trends.js b/src/emusks-local/helpers/trends.js new file mode 100644 index 0000000..909764a --- /dev/null +++ b/src/emusks-local/helpers/trends.js @@ -0,0 +1,84 @@ +export async function available() { + const res = await this.v1_1("trends/available", {}); + return await res.json(); +} + +export async function history(opts = {}) { + return await this.graphql("TrendHistory", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function relevantUsers(trendName, opts = {}) { + return await this.graphql("TrendRelevantUsers", { + variables: { + trend_name: trendName, + ...opts.variables, + }, + }); +} + +export async function explore(opts = {}) { + return await this.graphql("ExplorePage", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); +} + +export async function exploreSidebar(opts = {}) { + return await this.graphql("ExploreSidebar", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + ...opts.variables, + }, + }); +} + +export async function report(trendId) { + return await this.graphql("ReportTrend", { + body: { variables: { trend_id: trendId } }, + }); +} + +export async function save(trendId) { + return await this.graphql("SaveTrend", { + body: { variables: { trend_id: trendId } }, + }); +} + +export async function action(trendId, action) { + return await this.graphql("ActionTrend", { + body: { variables: { trend_id: trendId, action } }, + }); +} + +export async function getById(trendId) { + return await this.graphql("AiTrendByRestId", { + variables: { trendId }, + }); +} + +export async function exploreSettings() { + const res = await this.v2("guide/get_explore_settings", {}); + return await res.json(); +} + +export async function setExploreSettings(params = {}) { + const res = await this.v2("guide/set_explore_settings", { + body: JSON.stringify(params), + }); + return await res.json(); +} diff --git a/src/emusks-local/helpers/tweets.js b/src/emusks-local/helpers/tweets.js new file mode 100644 index 0000000..40762dc --- /dev/null +++ b/src/emusks-local/helpers/tweets.js @@ -0,0 +1,408 @@ +import getCycleTLS from "../cycletls.js"; +import parseTweet from "../parsers/tweet.js"; + +async function createPollCard(instance, poll) { + if (!poll.choices || poll.choices.length < 2) + throw new Error("a poll must have at least 2 choices"); + if (poll.choices.length > 4) throw new Error("a poll must not have more than 4 choices"); + + const hasImages = poll.choices.some((c) => typeof c === "object" && c.image); + const allImages = poll.choices.every((c) => typeof c === "object" && c.image); + if (hasImages && !allImages) + throw new Error("either all poll choices must have images, or none of them"); + + const labels = poll.choices.map((c) => (typeof c === "object" ? c.label : c)); + + for (const label of labels) { + if (typeof label !== "string" || label.length === 0) + throw new Error("each poll choice must have a non-empty label"); + if (label.length > 25) throw new Error(`poll choice "${label}" exceeds the 25-character limit`); + } + + const duration = poll.duration_minutes ?? 1440; + if (duration < 5 || duration > 10080) + throw new Error("poll duration must be between 5 and 10 080 minutes (7 days)"); + + const cycleTLS = await getCycleTLS(); + + const cardObj = { + "twitter:api:api:endpoint": "1", + "twitter:long:duration_minutes": duration, + }; + + if (hasImages) { + cardObj["twitter:card"] = "poll_choice_images"; + for (let i = 0; i < poll.choices.length; i++) { + cardObj[`twitter:string:choice${i + 1}_label`] = labels[i]; + cardObj[`twitter:image:choice${i + 1}_image:src:id`] = `mis://${poll.choices[i].image}`; + } + } else { + cardObj["twitter:card"] = `poll${poll.choices.length}choice_text_only`; + for (let i = 0; i < labels.length; i++) { + cardObj[`twitter:string:choice${i + 1}_label`] = labels[i]; + } + } + + const cardData = JSON.stringify(cardObj); + + const res = await cycleTLS( + "https://caps.x.com/v2/cards/create.json", + { + headers: { + accept: "*/*", + "accept-language": "en-US,en;q=0.9", + authorization: `Bearer ${instance.auth.client.bearer}`, + "content-type": "application/x-www-form-urlencoded", + "x-csrf-token": instance.auth.csrfToken, + "x-twitter-active-user": "yes", + "x-twitter-auth-type": "OAuth2Session", + "x-twitter-client-language": "en", + priority: "u=1, i", + "sec-ch-ua": "Not(A:Brand;v=8, Chromium;v=144", + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": "macOS", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-site", + "sec-gpc": "1", + cookie: + instance.auth.client.headers.cookie + + (instance.elevatedCookies ? `; ${instance.elevatedCookies}` : ""), + }, + body: `card_data=${encodeURIComponent(cardData)}`, + userAgent: + instance.auth.client.fingerprints?.userAgent || + instance.auth.client.fingerprints?.["user-agent"], + ja3: instance.auth.client.fingerprints?.ja3, + ja4r: instance.auth.client.fingerprints?.ja4r, + proxy: instance.proxy || undefined, + referrer: "https://x.com/", + }, + "post", + ); + + const data = await res.json(); + if (!data?.card_uri) { + throw new Error(`failed to create poll card: ${JSON.stringify(data)}`); + } + return data.card_uri; +} + +export async function create(text, opts = {}) { + let cardUri = opts.cardUri; + + if (opts.poll) { + if (cardUri) throw new Error("a tweet can\u0027t have both a poll and a cardUri"); + cardUri = await createPollCard(this, opts.poll); + } + + const mediaIds = opts.mediaIds ? [...opts.mediaIds] : []; + + if (opts.gif) { + const gif = opts.gif; + const gifUrl = gif.original_image?.url || gif.url; + if (!gifUrl) throw new Error("gif must have a url or original_image.url"); + + const provider = gif.found_media_origin?.provider || gif.provider; + const gifId = gif.found_media_origin?.id || gif.id; + const altText = gif.alt_text || gif.altText; + + const uploaded = await this.media.createFromUrl(gifUrl, { + origin: provider && gifId ? { provider, id: gifId } : undefined, + altText, + }); + mediaIds.push(uploaded.media_id); + } + + const res = await this.graphql("CreateTweet", { + body: { + variables: { + tweet_text: text, + dark_request: false, + card_uri: cardUri || undefined, + media: { + media_entities: mediaIds.map((id) => ({ + media_id: id, + tagged_users: [], + })), + possibly_sensitive: opts.sensitive || false, + }, + semantic_annotation_ids: [], + ...(opts.replyTo + ? { + reply: { + in_reply_to_tweet_id: opts.replyTo, + exclude_reply_user_ids: [], + }, + } + : {}), + ...(opts.quoteTweetId + ? { attachment_url: `https://x.com/i/status/${opts.quoteTweetId}` } + : {}), + ...(opts.conversationControl + ? { conversation_control: { mode: opts.conversationControl } } + : {}), + ...opts.variables, + }, + }, + }); + const tweet = res?.data?.create_tweet?.tweet_results?.result; + return tweet ? parseTweet(tweet) : res; +} + +export async function createNote(text, opts = {}) { + const res = await this.graphql("CreateNoteTweet", { + body: { + variables: { + tweet_text: text, + dark_request: false, + media: { + media_entities: + opts.mediaIds?.map((id) => ({ + media_id: id, + tagged_users: [], + })) || [], + possibly_sensitive: opts.sensitive || false, + }, + semantic_annotation_ids: [], + richtext_options: { richtext_tags: opts.richtext_tags || [] }, + ...(opts.replyTo + ? { + reply: { + in_reply_to_tweet_id: opts.replyTo, + exclude_reply_user_ids: [], + }, + } + : {}), + ...opts.variables, + }, + }, + }); + const tweet = res?.data?.notetweet_create?.tweet_results?.result; + return tweet ? parseTweet(tweet) : res; +} + +export async function remove(tweetId) { + return await this.graphql("DeleteTweet", { + body: { variables: { tweet_id: tweetId, dark_request: false } }, + }); +} + +export async function like(tweetId) { + return await this.graphql("FavoriteTweet", { + body: { variables: { tweet_id: tweetId } }, + }); +} + +export async function unlike(tweetId) { + return await this.graphql("UnfavoriteTweet", { + body: { variables: { tweet_id: tweetId } }, + }); +} + +export async function retweet(tweetId) { + return await this.graphql("CreateRetweet", { + body: { variables: { tweet_id: tweetId, dark_request: false } }, + }); +} + +export async function unretweet(tweetId) { + return await this.graphql("DeleteRetweet", { + body: { variables: { source_tweet_id: tweetId, dark_request: false } }, + }); +} + +export async function pin(tweetId) { + return await this.graphql("PinTweet", { + body: { variables: { tweet_id: tweetId } }, + }); +} + +export async function unpin(tweetId) { + return await this.graphql("UnpinTweet", { + body: { variables: { tweet_id: tweetId } }, + }); +} + +export async function get(tweetId) { + const res = await this.graphql("TweetResultByRestId", { + variables: { + tweetId, + withCommunity: false, + includePromotedContent: false, + withVoice: false, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); + const tweet = res?.data?.tweetResult?.result; + return tweet ? parseTweet(tweet) : res; +} + +export async function getMany(tweetIds) { + const res = await this.graphql("TweetResultsByRestIds", { + variables: { + tweetIds, + withCommunity: false, + includePromotedContent: false, + withVoice: false, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); + const results = res?.data?.tweetResult || []; + return Array.isArray(results) ? results.map((r) => (r?.result ? parseTweet(r.result) : r)) : res; +} + +export async function detail(tweetId, opts = {}) { + return await this.graphql("TweetDetail", { + variables: { + focalTweetId: tweetId, + with_rux_injections: false, + rankingMode: "Relevance", + includePromotedContent: true, + withCommunity: true, + withQuickPromoteEligibilityTweetFields: true, + withBirdwatchNotes: true, + withVoice: true, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); +} + +export async function editHistory(tweetId) { + return await this.graphql("TweetEditHistory", { + variables: { tweetId, withQuickPromoteEligibilityTweetFields: true }, + }); +} + +export async function retweeters(tweetId, opts = {}) { + return await this.graphql("Retweeters", { + variables: { + tweetId, + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + }, + }); +} + +export async function highlight(tweetId) { + return await this.graphql("CreateHighlight", { + body: { variables: { tweet_id: tweetId } }, + }); +} + +export async function unhighlight(tweetId) { + return await this.graphql("DeleteHighlight", { + body: { variables: { tweet_id: tweetId } }, + }); +} + +export async function schedule(text, scheduledAt, opts = {}) { + return await this.graphql("CreateScheduledTweet", { + body: { + variables: { + post_tweet_request: { + status: text, + ...(opts.mediaIds ? { media_ids: opts.mediaIds } : {}), + ...(opts.replyTo ? { in_reply_to_status_id: opts.replyTo } : {}), + auto_populate_reply_metadata: true, + }, + execute_at: Math.floor(new Date(scheduledAt).getTime() / 1000), + }, + }, + }); +} + +export async function deleteScheduled(scheduledTweetId) { + return await this.graphql("DeleteScheduledTweet", { + body: { variables: { scheduled_tweet_id: scheduledTweetId } }, + }); +} + +export async function getScheduled() { + return await this.graphql("FetchScheduledTweets", { + variables: {}, + }); +} + +export async function moderate(tweetId) { + return await this.graphql("ModerateTweet", { + body: { variables: { tweet_id: tweetId } }, + }); +} + +export async function unmoderate(tweetId) { + return await this.graphql("UnmoderateTweet", { + body: { variables: { tweet_id: tweetId } }, + }); +} + +export async function pinReply(tweetId) { + return await this.graphql("PinReply", { + body: { variables: { tweet_id: tweetId } }, + }); +} + +export async function unpinReply(tweetId) { + return await this.graphql("UnpinReply", { + body: { variables: { tweet_id: tweetId } }, + }); +} + +export async function setConversationControl(tweetId, mode) { + return await this.graphql("ConversationControlChange", { + body: { variables: { tweet_id: tweetId, mode } }, + }); +} + +export async function removeConversationControl(tweetId) { + return await this.graphql("ConversationControlDelete", { + body: { variables: { tweet_id: tweetId } }, + }); +} + +export async function unmention(tweetId) { + return await this.graphql("UnmentionUserFromConversation", { + body: { variables: { tweet_id: tweetId } }, + }); +} + +export async function createThread(items) { + if (!Array.isArray(items) || items.length < 2) + throw new Error("a thread must have at least 2 tweets"); + + const tweets = []; + let lastId = null; + + for (const item of items) { + const opts = typeof item === "string" ? {} : { ...item }; + const text = typeof item === "string" ? item : item.text; + + if (lastId) opts.replyTo = lastId; + + const tweet = await create.call(this, text, opts); + tweets.push(tweet); + lastId = tweet.id; + } + + return tweets; +} + +export async function similar(tweetId) { + return await this.graphql("SimilarPosts", { + variables: { tweet_id: tweetId }, + }); +} diff --git a/src/emusks-local/helpers/users.js b/src/emusks-local/helpers/users.js new file mode 100644 index 0000000..6addb2d --- /dev/null +++ b/src/emusks-local/helpers/users.js @@ -0,0 +1,319 @@ +import parseTimeline from "../parsers/timeline.js"; +import parseUser from "../parsers/user.js"; + +export async function get(userId) { + const res = await this.graphql("UserByRestId", { + variables: { userId, withSafetyModeUserFields: true }, + fieldToggles: { withAuxiliaryUserLabels: false }, + }); + const user = res?.data?.user?.result; + return user ? parseUser(user) : res; +} + +export async function getByUsername(username) { + const res = await this.graphql("UserByScreenName", { + variables: { screen_name: username, withSafetyModeUserFields: true }, + fieldToggles: { withAuxiliaryUserLabels: false }, + }); + const user = res?.data?.user?.result; + return user ? parseUser(user) : res; +} + +export async function getMany(userIds) { + const res = await this.graphql("UsersByRestIds", { + variables: { userIds, withSafetyModeUserFields: true }, + fieldToggles: { withAuxiliaryUserLabels: false }, + }); + const users = res?.data?.users || []; + return Array.isArray(users) + ? users.map((u) => (u?.result ? parseUser(u.result) : u)) + : res; +} + +export async function getManyByUsername(screenNames) { + const res = await this.graphql("UsersByScreenNames", { + variables: { screen_names: screenNames, withSafetyModeUserFields: true }, + fieldToggles: { withAuxiliaryUserLabels: false }, + }); + const users = res?.data?.users || []; + return Array.isArray(users) + ? users.map((u) => (u?.result ? parseUser(u.result) : u)) + : res; +} + +export async function tweets(userId, opts = {}) { + const raw = await this.graphql("UserTweets", { + variables: { + userId, + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: true, + withQuickPromoteEligibilityTweetFields: true, + withVoice: true, + withV2Timeline: true, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); + return parseTimeline(raw); +} + +export async function replies(userId, opts = {}) { + const raw = await this.graphql("UserTweetsAndReplies", { + variables: { + userId, + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: true, + withCommunity: true, + withVoice: true, + withV2Timeline: true, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); + return parseTimeline(raw); +} + +export async function userMedia(userId, opts = {}) { + const raw = await this.graphql("UserMedia", { + variables: { + userId, + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + withClientEventToken: false, + withBirdwatchNotes: false, + withVoice: true, + withV2Timeline: true, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); + return parseTimeline(raw); +} + +export async function highlights(userId, opts = {}) { + const raw = await this.graphql("UserHighlightsTweets", { + variables: { + userId, + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: true, + withVoice: true, + ...opts.variables, + }, + fieldToggles: { + withArticlePlainText: false, + withArticleRichContentState: false, + withAuxiliaryUserLabels: false, + }, + }); + return parseTimeline(raw); +} + +export async function followers(userId, opts = {}) { + const raw = await this.graphql("Followers", { + variables: { + userId, + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + }, + }); + return parseTimeline(raw); +} + +export async function following(userId, opts = {}) { + const raw = await this.graphql("Following", { + variables: { + userId, + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + }, + }); + return parseTimeline(raw); +} + +export async function verifiedFollowers(userId, opts = {}) { + const raw = await this.graphql("BlueVerifiedFollowers", { + variables: { + userId, + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + }, + }); + return parseTimeline(raw); +} + +export async function followersYouKnow(userId, opts = {}) { + const raw = await this.graphql("FollowersYouKnow", { + variables: { + userId, + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + }, + }); + return parseTimeline(raw); +} + +export async function follow(userId) { + const res = await this.v1_1("friendships/create", { + body: JSON.stringify({ user_id: userId }), + }); + const json = await res.json(); + return json ? parseUser(json) : res; +} + +export async function unfollow(userId) { + const res = await this.v1_1("friendships/destroy", { + body: JSON.stringify({ user_id: userId }), + }); + const json = await res.json(); + return json ? parseUser(json) : res; +} + +export async function block(userId) { + const res = await this.v1_1("blocks/create", { + body: JSON.stringify({ user_id: userId }), + }); + const json = await res.json(); + return json ? parseUser(json) : res; +} + +export async function unblock(userId) { + const res = await this.v1_1("blocks/destroy", { + body: JSON.stringify({ user_id: userId }), + }); + const json = await res.json(); + return json ? parseUser(json) : res; +} + +export async function mute(userId) { + const res = await this.v1_1("mutes/users/create", { + body: JSON.stringify({ user_id: userId }), + }); + const json = await res.json(); + return json ? parseUser(json) : res; +} + +export async function unmute(userId) { + const res = await this.v1_1("mutes/users/destroy", { + body: JSON.stringify({ user_id: userId }), + }); + const json = await res.json(); + return json ? parseUser(json) : res; +} + +export async function removeFollower(userId) { + return await this.graphql("RemoveFollower", { + body: { variables: { target_user_id: userId } }, + }); +} + +export async function blocked(opts = {}) { + const raw = await this.graphql("BlockedAccountsAll", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + }, + }); + return parseTimeline(raw); +} + +export async function muted(opts = {}) { + const raw = await this.graphql("MutedAccounts", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + }, + }); + return parseTimeline(raw); +} + +export async function lookup(params = {}) { + const res = await this.v1_1("users/lookup", { params }); + return await res.json(); +} + +export async function updateProfile(params = {}) { + const res = await this.v1_1("account/update_profile", { + body: JSON.stringify(params), + }); + const json = await res.json(); + return json ? parseUser(json) : res; +} + +export async function updateProfileImage(imageData) { + const res = await this.v1_1("account/update_profile_image", { + body: JSON.stringify({ image: imageData }), + }); + return await res.json(); +} + +export async function updateProfileBanner(bannerData) { + const res = await this.v1_1("account/update_profile_banner", { + body: JSON.stringify({ banner: bannerData }), + }); + return await res.json(); +} + +export async function removeProfileBanner() { + const res = await this.v1_1("account/remove_profile_banner", {}); + return await res.json(); +} + +export async function subscriptions(userId, opts = {}) { + const raw = await this.graphql("UserCreatorSubscriptions", { + variables: { + userId, + count: opts.count || 20, + cursor: opts.cursor, + }, + }); + return parseTimeline(raw); +} + +export async function subscribers(userId, opts = {}) { + const raw = await this.graphql("UserCreatorSubscribers", { + variables: { + userId, + count: opts.count || 20, + cursor: opts.cursor, + }, + }); + return parseTimeline(raw); +} + +export async function superFollowers(opts = {}) { + const raw = await this.graphql("SuperFollowers", { + variables: { + count: opts.count || 20, + cursor: opts.cursor, + includePromotedContent: false, + }, + }); + return parseTimeline(raw); +} + +export async function recommendations(params = {}) { + const res = await this.v1_1("users/recommendations", { params }); + return await res.json(); +} diff --git a/src/emusks-local/index.js b/src/emusks-local/index.js new file mode 100644 index 0000000..9e55cde --- /dev/null +++ b/src/emusks-local/index.js @@ -0,0 +1,196 @@ +import { ClientTransaction, handleXMigration } from "x-client-transaction-id"; +import clients from "./clients.js"; +import getCycleTLS from "./cycletls.js"; +import flowLogin from "./flow.js"; +import graphql, { GRAPHQL_ENDPOINTS } from "./graphql.js"; +import initHelpers from "./helpers/index.js"; +import parseUser from "./parsers/user.js"; +import v1_1 from "./v1.1.js"; +import v2 from "./v2.js"; + +export default class Emusks { + auth = null; + elevatedCookies = null; + graphqlEndpoint = "web"; + transactionIds = undefined; + + async elevate(password) { + if (!this.auth) throw new Error("must be logged in before calling elevate"); + + const res = await this.v1_1("account/verify_password", { + body: `password=${encodeURIComponent(password)}`, + headers: { + "content-type": "application/x-www-form-urlencoded", + }, + }); + + const setCookies = res.headers["Set-Cookie"] || []; + + const json = await res.json(); + if (json.status !== "ok") { + throw new Error("invalid password"); + } + + const cookieParts = []; + for (const setCookie of setCookies) { + const cookiePair = setCookie.split(";")[0]; + if (cookiePair) { + cookieParts.push(cookiePair); + } + } + + this.elevatedCookies = cookieParts.join("; "); + + return json; + } + + async login(p) { + if (typeof p === "string") { + if (p.length > 50 || p.length < 20) { + throw new Error("invalid auth token length!"); + } + p = { auth_token: p }; + } + + if (p.type === "password") { + if (!p.username) throw new Error("username is required for password login"); + if (!p.password) throw new Error("password is required for password login"); + + const flowResult = await flowLogin({ + username: p.username, + password: p.password, + email: p.email, + phone: p.phone, + onRequest: p.onRequest, + proxy: p.proxy, + }); + + p = { + auth_token: flowResult.authToken, + client: p.client, + proxy: p.proxy, + }; + } + + if (!p.client) p.client = "web"; + if (!p.auth_token) throw new Error("auth_token is required!"); + if (typeof p.client === "string") p.client = clients[p.client]; + if (!p.client) throw new Error("invalid client!"); + if (p.proxy) this.proxy = p.proxy; + + if (p.endpoint) { + if (!GRAPHQL_ENDPOINTS[p.endpoint]) { + throw new Error( + `unknown graphql endpoint "${p.endpoint}", expected: ${Object.keys(GRAPHQL_ENDPOINTS).join(", ")}`, + ); + } + this.graphqlEndpoint = p.endpoint; + } + + if (p.transactionIds !== undefined) { + this.transactionIds = p.transactionIds; + } + + if (!p.client.bearer) { + throw new Error("client is missing bearer token!"); + } + if (!p.client.userAgent || !p.client.fingerprints) { + p.client.userAgent = + p.client.userAgent || + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36"; + + p.client.fingerprints = p.client.fingerprints || { + ja3: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,35-5-27-16-0-10-13-23-45-65037-17613-18-65281-51-43-11,4588-29-23-24,0", + ja4r: "t13d1516h2_002f,0035,009c,009d,1301,1302,1303,c013,c014,c02b,c02c,c02f,c030,cca8,cca9_0005,000a,000b,000d,0012,0017,001b,0023,002b,002d,0033,44cd,fe0d,ff01_0403,0804,0401,0503,0805,0501,0806,0601", + }; + } + + p.client.headers = { + "accept-language": "en-US,en;q=0.9", + priority: "u=1, i", + "sec-ch-ua": '"Not(A:Brand";v="8", "Chromium";v="144"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"macOS"', + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-site", + "sec-gpc": "1", + }; + + const cycleTLS = await getCycleTLS(); + const res = await cycleTLS("https://x.com/", { + headers: { + accept: + "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + cookie: `auth_token=${p.auth_token};`, + ...p.client.headers, + }, + userAgent: p.client.fingerprints.userAgent, + ja3: p.client.fingerprints.ja3, + ja4r: p.client.fingerprints.ja4r, + proxy: p.proxy || undefined, + referrer: "https://x.com/", + }); + + const setCookies = res.headers["Set-Cookie"] || []; + const csrfToken = setCookies + .find((c) => c?.startsWith?.("ct0=")) + ?.split?.(";")?.[0] + ?.split?.("=")?.[1]; + + if (!csrfToken) { + throw new Error("[emusks] failed to log in"); + } + + this.auth = p; + this.auth.csrfToken = csrfToken; + + const cookieParts = [`auth_token=${p.auth_token}`]; + for (const setCookie of setCookies) { + const cookiePair = setCookie.split(";")[0]; + if (cookiePair && !cookiePair.startsWith("auth_token=")) { + cookieParts.push(cookiePair); + } + } + this.auth.client.headers.cookie = cookieParts.join("; "); + + const needsTransactionIds = + this.transactionIds !== undefined + ? this.transactionIds + : this.graphqlEndpoint === "web" || this.graphqlEndpoint === "web_twitter"; + + if (needsTransactionIds) { + const document = await handleXMigration(); + const transaction = new ClientTransaction(document); + await transaction.initialize(); + this.auth.generateTransactionId = transaction.generateTransactionId.bind(transaction); + } + + const responseText = await res.text(); + const initialStateMatch = responseText.match(/window\.__INITIAL_STATE__\s*=\s*({.*?});/s); + + if (!initialStateMatch) { + console.warn("[emusks] failed to extract initial state from response"); + return; + } + + const initialState = JSON.parse(initialStateMatch[1]); + const usersEntities = initialState?.entities?.users?.entities; + const initialStateUser = usersEntities && Object.values(usersEntities)[0]; + + if (!initialStateUser) { + console.warn("[emusks] failed to extract user from initial state"); + return; + } + + this.user = parseUser(initialStateUser); + this.settings = initialState?.settings?.remote?.settings; + + return this.user; + } +} + +Emusks.prototype.graphql = graphql; +Emusks.prototype.v1_1 = v1_1; +Emusks.prototype.v2 = v2; +initHelpers(Emusks.prototype); diff --git a/src/emusks-local/package-lock.json b/src/emusks-local/package-lock.json new file mode 100644 index 0000000..a6a556e --- /dev/null +++ b/src/emusks-local/package-lock.json @@ -0,0 +1,504 @@ +{ + "name": "emusks", + "version": "2.0.12", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "emusks", + "version": "2.0.12", + "license": "AGPL-3.0-only", + "dependencies": { + "cycletls": "^2.0.5", + "x-client-transaction-id": "^0.1.9" + } + }, + "node_modules/@types/node": { + "version": "20.19.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.37.tgz", + "integrity": "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "license": "MIT" + }, + "node_modules/cycletls": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cycletls/-/cycletls-2.0.5.tgz", + "integrity": "sha512-Nud94JBPZu1JTXWJ1GpIoQNR1xxU84WYt7G0dxzwpUe1xAAs6YbihvlQhIhPv9xljjonINJfWPFaeb8Ex1wLhQ==", + "license": "GPL3", + "dependencies": { + "@types/node": "^20.14.0", + "form-data": "^4.0.0", + "ws": "^8.17.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/linkedom": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.18.12.tgz", + "integrity": "sha512-jalJsOwIKuQJSeTvsgzPe9iJzyfVaEJiEXl+25EkKevsULHvMJzpNqwvj1jOESWdmgKDiXObyjOYwlUqG7wo1Q==", + "license": "ISC", + "dependencies": { + "css-select": "^5.1.0", + "cssom": "^0.5.0", + "html-escaper": "^3.0.3", + "htmlparser2": "^10.0.0", + "uhyphen": "^0.2.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "canvas": ">= 2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/uhyphen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.2.0.tgz", + "integrity": "sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==", + "license": "ISC" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/x-client-transaction-id": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/x-client-transaction-id/-/x-client-transaction-id-0.1.9.tgz", + "integrity": "sha512-CES4zgkJ0wbfFWm0qgdKphthyb+L7lVHymgOY15v6ivcWSx5p9lp5kzAed+BuqJSP7bS0GbQyJ16ONkRthgsUw==", + "license": "MIT", + "dependencies": { + "linkedom": "^0.18.9" + } + } + } +} diff --git a/src/emusks-local/package.json b/src/emusks-local/package.json new file mode 100644 index 0000000..74f48b3 --- /dev/null +++ b/src/emusks-local/package.json @@ -0,0 +1,31 @@ +{ + "name": "emusks", + "version": "2.0.12", + "description": "Reverse-engineered Twitter API client. Log in and interact with the unofficial X API using any client identity — web, Android, iOS, or TweetDeck", + "keywords": [ + "client", + "reverse-engineering", + "twitter", + "twitter-api", + "x", + "x-api" + ], + "homepage": "https://github.com/tiagozip/emusks", + "bugs": { + "url": "https://github.com/tiagozip/emusks/issues" + }, + "license": "AGPL-3.0-only", + "repository": { + "type": "git", + "url": "https://github.com/tiagozip/emusks.git" + }, + "type": "module", + "main": "src/index.js", + "exports": { + ".": "./src/index.js" + }, + "dependencies": { + "cycletls": "^2.0.5", + "x-client-transaction-id": "^0.1.9" + } +} diff --git a/src/emusks-local/parsers/timeline.js b/src/emusks-local/parsers/timeline.js new file mode 100644 index 0000000..b994c96 --- /dev/null +++ b/src/emusks-local/parsers/timeline.js @@ -0,0 +1,105 @@ +import parseTweet from "./tweet.js"; +import parseUser from "./user.js"; + +function findInstructions(obj) { + if (!obj || typeof obj !== "object") return null; + + if (Array.isArray(obj.instructions)) { + return obj.instructions; + } + + for (const key of Object.keys(obj)) { + const val = obj[key]; + if (val && typeof val === "object") { + const found = findInstructions(val); + if (found) return found; + } + } + + return null; +} + +function extractTweetFromEntry(entry) { + const tweetResult = + entry?.content?.itemContent?.tweet_results?.result || + entry?.item?.itemContent?.tweet_results?.result; + if (tweetResult) { + return parseTweet(tweetResult); + } + return null; +} + +function extractUserFromEntry(entry) { + const userResult = + entry?.content?.itemContent?.user_results?.result || + entry?.item?.itemContent?.user_results?.result; + if (userResult) { + return parseUser(userResult); + } + return null; +} + +export default function parseTimeline(raw) { + const instructions = findInstructions(raw?.data || raw); + + if (!instructions) { + return { tweets: [], users: [], nextCursor: null, previousCursor: null, raw }; + } + + const tweets = []; + const users = []; + let nextCursor = null; + let previousCursor = null; + + for (const instruction of instructions) { + if (instruction.type === "TimelineAddEntries" || instruction.entries) { + for (const entry of instruction.entries || []) { + processEntry(entry, tweets, users); + + if (entry.entryId?.startsWith("cursor-bottom") || entry.entryId?.includes("cursor-bottom")) { + nextCursor = + entry.content?.value || entry.content?.itemContent?.value || null; + } + if (entry.entryId?.startsWith("cursor-top") || entry.entryId?.includes("cursor-top")) { + previousCursor = + entry.content?.value || entry.content?.itemContent?.value || null; + } + } + } + + if (instruction.type === "TimelineReplaceEntry" && instruction.entry) { + processEntry(instruction.entry, tweets, users); + if (instruction.entry.entryId?.includes("cursor-bottom")) { + nextCursor = + instruction.entry.content?.value || + instruction.entry.content?.itemContent?.value || + null; + } + } + } + + return { tweets, users, nextCursor, previousCursor, raw }; +} + +function processEntry(entry, tweets, users) { + const tweet = extractTweetFromEntry(entry); + if (tweet) { + tweets.push(tweet); + return; + } + + const user = extractUserFromEntry(entry); + if (user) { + users.push(user); + return; + } + + if (entry.content?.items) { + for (const item of entry.content.items) { + const t = extractTweetFromEntry(item); + if (t) tweets.push(t); + const u = extractUserFromEntry(item); + if (u) users.push(u); + } + } +} diff --git a/src/emusks-local/parsers/tweet.js b/src/emusks-local/parsers/tweet.js new file mode 100644 index 0000000..6d0605b --- /dev/null +++ b/src/emusks-local/parsers/tweet.js @@ -0,0 +1,82 @@ +import parseUser from "./user.js"; + +export default function parseTweet(tweet) { + const get = (obj, path, fallback = undefined) => + path + .split(".") + .reduce((o, k) => (o && o[k] !== undefined ? o[k] : fallback), obj); + const data = tweet.data?.tweet || tweet; + + const legacy = data.legacy || data; + const core = data.core || {}; + const views = data.views || {}; + + return { + id: tweet.rest_id || legacy.id_str || tweet.id || tweet.id_str, + text: legacy.full_text || legacy.text || tweet.text, + created_at: legacy.created_at || tweet.created_at, + conversation_id: legacy.conversation_id_str || tweet.conversation_id_str, + in_reply_to_status_id: + legacy.in_reply_to_status_id_str || tweet.in_reply_to_status_id_str, + in_reply_to_user_id: + legacy.in_reply_to_user_id_str || tweet.in_reply_to_user_id_str, + in_reply_to_screen_name: + legacy.in_reply_to_screen_name || tweet.in_reply_to_screen_name, + + user: (() => { + const raw = + get(core, "user_results.result") || + get(data, "core.user_results.result") || + data.user; + return raw ? parseUser(raw) : null; + })(), + + stats: { + retweets: legacy.retweet_count || tweet.retweet_count || 0, + likes: legacy.favorite_count || tweet.favorite_count || 0, + replies: legacy.reply_count || tweet.reply_count || 0, + quotes: legacy.quote_count || tweet.quote_count || 0, + bookmarks: legacy.bookmark_count || tweet.bookmark_count || 0, + views: get(views, "count") || 0, + }, + + engagement: { + retweeted: legacy.retweeted || tweet.retweeted || false, + liked: legacy.favorited || tweet.favorited || false, + bookmarked: legacy.bookmarked || tweet.bookmarked || false, + }, + + media: + tweet.extended_entities?.media || + legacy.extended_entities?.media || + legacy.entities?.media || + tweet.entities?.media || + [], + urls: legacy.entities?.urls || tweet.entities?.urls || [], + hashtags: legacy.entities?.hashtags || tweet.entities?.hashtags || [], + user_mentions: + legacy.entities?.user_mentions || tweet.entities?.user_mentions || [], + + source: legacy.source || tweet.source, + lang: legacy.lang || tweet.lang, + + quoting: get(tweet, "quoted_status_result.result") + ? parseTweet(get(tweet, "quoted_status_result.result")) + : null, + + edit_control: data.edit_control || {}, + card: data.card || null, + unmention_data: data.unmention_data || {}, + + misc: { + display_text_range: legacy.display_text_range || tweet.display_text_range, + is_translatable: tweet.is_translatable || false, + possibly_sensitive: + legacy.possibly_sensitive || tweet.possibly_sensitive || false, + withheld_copyright: + legacy.withheld_copyright || tweet.withheld_copyright || false, + withheld_in_countries: + legacy.withheld_in_countries || tweet.withheld_in_countries || [], + }, + }; +} diff --git a/src/emusks-local/parsers/user.js b/src/emusks-local/parsers/user.js new file mode 100644 index 0000000..ba84641 --- /dev/null +++ b/src/emusks-local/parsers/user.js @@ -0,0 +1,142 @@ +export default function parseUser(user) { + if (typeof user?.stats?.followers?.count === "number") { + // we can safely assume this has already been parsed + return user; + } + + const get = (obj, path, fallback = undefined) => + path + .split(".") + .reduce((o, k) => (o && o[k] !== undefined ? o[k] : fallback), obj); + const data = user.data?.user || user; + + const legacy = data.legacy || data; + const core = data.core || {}; + const locationObj = data.location || {}; + const verification = data.verification || {}; + const parodyLabel = + data.parody_commentary_fan_label || legacy.parody_commentary_fan_label; + const highlightedLabel = + get(data, "affiliates_highlighted_label.label") || data.highlightedLabel; + + return { + id: data.rest_id || legacy.id_str || data.id || data.id_str, + name: core.name || legacy.name || data.name, + username: + core.screen_name || + legacy.screen_name || + data.screen_name || + data.username, + description: legacy.description || data.description, + banner: + legacy.profile_banner_url || + legacy.profile_background_image_url || + legacy.profile_background_image_url_https || + data.profile_banner_url || + data.profile_background_image_url || + data.profile_background_image_url_https, + url: legacy.url || data.url, + location: locationObj.location || legacy.location || data.location || null, + protected: get( + data, + "privacy.protected", + legacy.protected || data.protected + ), + created_at: get(core, "created_at", legacy.created_at || data.created_at), + backgroundColor: + legacy.profile_background_color || data.profile_background_color, + + profile_picture: { + url: + get(data, "avatar.image_url") || + legacy.profile_image_url_https || + data.profile_image_url_https || + "https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png", + shape: + data.profile_image_shape || + data.ext_profile_image_shape || + legacy.profile_image_shape || + "Circle", + }, + + stats: { + followers: { + count: legacy.followers_count || data.followers_count, + fast_followers: + legacy.fast_followers_count || data.fast_followers_count || 0, + normal_followers: + legacy.normal_followers_count || data.normal_followers_count, + }, + following: legacy.friends_count || data.friends_count, + subscriptions_count: + data.creator_subscriptions_count || + legacy.creator_subscriptions_count || + 0, + likes: legacy.favourites_count || data.favourites_count, + listed: legacy.listed_count || data.listed_count, + media: legacy.media_count || data.media_count, + posts: legacy.statuses_count || data.statuses_count, + }, + verification: { + verified: get(verification, "verified", legacy.verified || data.verified), + premium_verified: + data.is_blue_verified || + data.ext_is_blue_verified || + data.premium_verified || + data.premium_verified_type || + false, + }, + pinned_tweets: + legacy.pinned_tweet_ids_str || data.pinned_tweet_ids_str || [], + birthdate: data.birthdate || {}, + misc: { + default_profile: legacy.default_profile || data.default_profile, + default_profile_image: + legacy.default_profile_image || data.default_profile_image || false, + entities: legacy.entities || data.entities, + has_custom_timelines: + legacy.has_custom_timelines || data.has_custom_timelines, + is_translator: legacy.is_translator || data.is_translator || false, + translator_type: legacy.translator_type || data.translator_type, + is_profile_translatable: data.is_profile_translatable, + needs_phone_verification: data.needs_phone_verification, + possibly_sensitive: legacy.possibly_sensitive || data.possibly_sensitive, + profile_interstitial_type: + legacy.profile_interstitial_type || data.profile_interstitial_type, + want_retweets: legacy.want_retweets || data.want_retweets, + withheld_in_countries: + legacy.withheld_in_countries || data.withheld_in_countries || [], + tipjar_settings: data.tipjar_settings || {}, + can_dm: get(data, "dm_permissions.can_dm", data.can_dm), + can_media_tag: get( + data, + "media_permissions.can_media_tag", + data.can_media_tag + ), + blocked_by: get( + data, + "relationship_perspectives.followed_by", + data.blocked_by + ), + blocking: data.blocking, + following: get( + data, + "relationship_perspectives.following", + data.following + ), + muting: data.muting, + has_graduated_access: data.has_graduated_access, + geo_enabled: data.geo_enabled, + + advertising: { + service_levels: data.advertiser_account_service_levels || [], + account_type: data.advertiser_account_type || "none", + }, + }, + + labels: { + parody_commentary_fan_label: parodyLabel || "None", + highlightedLabel: highlightedLabel, + }, + }; +} diff --git a/src/emusks-local/static/graphql.js b/src/emusks-local/static/graphql.js new file mode 100644 index 0000000..0a95a40 --- /dev/null +++ b/src/emusks-local/static/graphql.js @@ -0,0 +1 @@ +export default {"AddContentDisclosure":["POST","https://x.com/i/api/graphql/-RlVfF2cSL1tdbOPGZ7G5w/AddContentDisclosure",{},"-RlVfF2cSL1tdbOPGZ7G5w"],"AuthenticatePeriscope":["GET","https://x.com/i/api/graphql/r7VUmxbfqNkx7uwjgONSNw/AuthenticatePeriscope",{},"r7VUmxbfqNkx7uwjgONSNw"],"getAltTextPromptPreference":["GET","https://x.com/i/api/graphql/PFIxTk8owMoZgiMccP0r4g/getAltTextPromptPreference",{},"PFIxTk8owMoZgiMccP0r4g"],"updateAltTextPromptPreference":["POST","https://x.com/i/api/graphql/aQKrduk_DA46XfOQDkcEng/updateAltTextPromptPreference",{},"aQKrduk_DA46XfOQDkcEng"],"BakeryQuery":["GET","https://x.com/i/api/graphql/pROR-yRiBVsEjJyHt3fvhg/BakeryQuery",{},"pROR-yRiBVsEjJyHt3fvhg"],"BlockedAccountsAll":["GET","https://x.com/i/api/graphql/GThiVP54lfC4X56v1BoFdQ/BlockedAccountsAll",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"GThiVP54lfC4X56v1BoFdQ"],"BlockedAccountsImported":["GET","https://x.com/i/api/graphql/kGwuE5ozdiMad32kttPeog/BlockedAccountsImported",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"kGwuE5ozdiMad32kttPeog"],"BlueVerifiedFollowers":["GET","https://x.com/i/api/graphql/YGl_IyrL0bFU7KHxQoSRVg/BlueVerifiedFollowers",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"YGl_IyrL0bFU7KHxQoSRVg"],"BookmarkSearchTimeline":["GET","https://x.com/i/api/graphql/1TNyDlFXsGJLqyQIMXqTQw/BookmarkSearchTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"1TNyDlFXsGJLqyQIMXqTQw"],"BroadcastQuery":["GET","https://x.com/i/api/graphql/UNQMlJe9Dr9rpaPu6qnk8w/BroadcastQuery",{"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":true},"UNQMlJe9Dr9rpaPu6qnk8w"],"CombinedLists":["GET","https://x.com/i/api/graphql/udSW4algWGE6PvbhVStuqA/CombinedLists",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"udSW4algWGE6PvbhVStuqA"],"CommunitiesExploreTimeline":["GET","https://x.com/i/api/graphql/bfarEpgj48LUdDZmqFCgKA/CommunitiesExploreTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"bfarEpgj48LUdDZmqFCgKA"],"CommunitiesMainDiscoveryModule":["GET","https://x.com/i/api/graphql/5OD8qPTxC3cQdEVPwA-oug/CommunitiesMainDiscoveryModule",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"5OD8qPTxC3cQdEVPwA-oug"],"CommunitiesMainPageTimeline":["GET","https://x.com/i/api/graphql/EkRezeH958TjZLQM8mS7QQ/CommunitiesMainPageTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"EkRezeH958TjZLQM8mS7QQ"],"CommunitiesMembershipsSlice":["GET","https://x.com/i/api/graphql/rF7mjHU4dwKjCiMoOw9u6g/CommunitiesMembershipsSlice",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"rF7mjHU4dwKjCiMoOw9u6g"],"CommunitiesMembershipsTimeline":["GET","https://x.com/i/api/graphql/9MJyCd-2UfqOUu1FQVhg9g/CommunitiesMembershipsTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"9MJyCd-2UfqOUu1FQVhg9g"],"CommunityAboutTimeline":["GET","https://x.com/i/api/graphql/UqkzyoXjgUSQpTOAUAeQCg/CommunityAboutTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"UqkzyoXjgUSQpTOAUAeQCg"],"CreateCommunity":["POST","https://x.com/i/api/graphql/tJ52pYK0g2cCMS277-57tg/CreateCommunity",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"tJ52pYK0g2cCMS277-57tg"],"CommunityCreateRule":["POST","https://x.com/i/api/graphql/aCJgkqUxo9-Jb25Fcomo6Q/CommunityCreateRule",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"aCJgkqUxo9-Jb25Fcomo6Q"],"CommunityDiscoveryTimeline":["GET","https://x.com/i/api/graphql/onri7QvZPoKWkznWVToOWQ/CommunityDiscoveryTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"onri7QvZPoKWkznWVToOWQ"],"CommunityEditBannerMedia":["POST","https://x.com/i/api/graphql/ScsZVF8xDfeGXFmb53NKVQ/CommunityEditBannerMedia",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"ScsZVF8xDfeGXFmb53NKVQ"],"CommunityEditName":["POST","https://x.com/i/api/graphql/XAxAnwy7L6QpW5MkWexHow/CommunityEditName",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"XAxAnwy7L6QpW5MkWexHow"],"CommunityEditPurpose":["POST","https://x.com/i/api/graphql/WbbgW83-DTF-2TG_Y1daAw/CommunityEditPurpose",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"WbbgW83-DTF-2TG_Y1daAw"],"CommunityEditQuestion":["POST","https://x.com/i/api/graphql/g0o3vQhXp0m4sa9lB9VLAg/CommunityEditQuestion",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"g0o3vQhXp0m4sa9lB9VLAg"],"CommunityEditRule":["POST","https://x.com/i/api/graphql/NyM5iRRpNmIecSV51mQZjw/CommunityEditRule",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"NyM5iRRpNmIecSV51mQZjw"],"CommunityByRestId":["GET","https://x.com/i/api/graphql/iO-Ycgd1CdS0xk9nQYMCaA/CommunityByRestId",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"iO-Ycgd1CdS0xk9nQYMCaA"],"CommunityHashtagsTimeline":["GET","https://x.com/i/api/graphql/CQ4RTiO2DOIzpzK0F8Uekg/CommunityHashtagsTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"CQ4RTiO2DOIzpzK0F8Uekg"],"JoinCommunity":["POST","https://x.com/i/api/graphql/b9bfcMQtJqWWCoyuM91Cpw/JoinCommunity",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"b9bfcMQtJqWWCoyuM91Cpw"],"LeaveCommunity":["POST","https://x.com/i/api/graphql/LLQ-xxy7KYe7VJFtRO31ig/LeaveCommunity",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"LLQ-xxy7KYe7VJFtRO31ig"],"CommunityMediaLoggedOutTimeline":["GET","https://x.com/i/api/graphql/QtI57Hc9Ee014f6d5_J3pw/CommunityMediaLoggedOutTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"QtI57Hc9Ee014f6d5_J3pw"],"CommunityMediaTimeline":["GET","https://x.com/i/api/graphql/Da-x1TY9ItOblAcdI6IK7w/CommunityMediaTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"Da-x1TY9ItOblAcdI6IK7w"],"CommunityMemberRelationshipTypeahead":["GET","https://x.com/i/api/graphql/wLq8nJhuzS5Tzq2p-dgIlw/CommunityMemberRelationshipTypeahead",{"responsive_web_graphql_timeline_navigation_enabled":true},"wLq8nJhuzS5Tzq2p-dgIlw"],"CommunityModerationKeepTweet":["POST","https://x.com/i/api/graphql/swOJtTWsuk3JthwFjK4yDw/CommunityModerationKeepTweet",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"swOJtTWsuk3JthwFjK4yDw"],"CommunityModerationTweetCasesSlice":["GET","https://x.com/i/api/graphql/eHjuIsiMULYyZE0z0M9dOA/CommunityModerationTweetCasesSlice",{"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":true},"eHjuIsiMULYyZE0z0M9dOA"],"CommunityRemoveBannerMedia":["POST","https://x.com/i/api/graphql/up4FbgqU3xhQF1ieA_m4TA/CommunityRemoveBannerMedia",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"up4FbgqU3xhQF1ieA_m4TA"],"CommunityRemoveRule":["POST","https://x.com/i/api/graphql/yhqzhiuAh4_5ar3L0wIyMA/CommunityRemoveRule",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"yhqzhiuAh4_5ar3L0wIyMA"],"CommunityReorderRules":["POST","https://x.com/i/api/graphql/JUSNGK2v5F2twR_vDIFl9w/CommunityReorderRules",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"JUSNGK2v5F2twR_vDIFl9w"],"RequestToJoinCommunity":["POST","https://x.com/i/api/graphql/fxdNIBbQkxH_U2NeRJTgPg/RequestToJoinCommunity",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"fxdNIBbQkxH_U2NeRJTgPg"],"CommunityTweetModerationLogSlice":["GET","https://x.com/i/api/graphql/yZ_RafVgTzG2KV1zHrFi6Q/CommunityTweetModerationLogSlice",{"creator_subscriptions_tweet_preview_api_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"yZ_RafVgTzG2KV1zHrFi6Q"],"CommunityTweetsLoggedOutTimeline":["GET","https://x.com/i/api/graphql/KdYopMu8okTwn9L4yJ-ofw/CommunityTweetsLoggedOutTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"KdYopMu8okTwn9L4yJ-ofw"],"CommunityTweetsRankedLoggedOutTimeline":["GET","https://x.com/i/api/graphql/8fkCp-WqTRbBJWRVjF6SGg/CommunityTweetsRankedLoggedOutTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"8fkCp-WqTRbBJWRVjF6SGg"],"CommunityTweetsTimeline":["GET","https://x.com/i/api/graphql/YPZv6-VEfy3CVvRyrLzI9w/CommunityTweetsTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"YPZv6-VEfy3CVvRyrLzI9w"],"CommunityUpdateRole":["POST","https://x.com/i/api/graphql/KTELaDcqvNaYgIVpvPPMng/CommunityUpdateRole",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"KTELaDcqvNaYgIVpvPPMng"],"CommunityUserInvite":["POST","https://x.com/i/api/graphql/bz8uZZOzk3SUQUKTPioZpQ/CommunityUserInvite",{"responsive_web_graphql_timeline_navigation_enabled":true},"bz8uZZOzk3SUQUKTPioZpQ"],"CommunityUserRelationshipTypeahead":["GET","https://x.com/i/api/graphql/_qsnOaYZy00m-KSiTIFyEA/CommunityUserRelationshipTypeahead",{"responsive_web_graphql_timeline_navigation_enabled":true},"_qsnOaYZy00m-KSiTIFyEA"],"ConnectTabTimeline":["GET","https://x.com/i/api/graphql/04nihojGRY7a623waPGUPQ/ConnectTabTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"04nihojGRY7a623waPGUPQ"],"ConversationControlChange":["POST","https://x.com/i/api/graphql/hb1elGcj6769uT8qVYqtjw/ConversationControlChange",{},"hb1elGcj6769uT8qVYqtjw"],"ConversationControlDelete":["POST","https://x.com/i/api/graphql/OoMO_aSZ1ZXjegeamF9QmA/ConversationControlDelete",{},"OoMO_aSZ1ZXjegeamF9QmA"],"CreateBookmark":["POST","https://x.com/i/api/graphql/aoDbu3RHznuiSkQ9aNM67Q/CreateBookmark",{},"aoDbu3RHznuiSkQ9aNM67Q"],"CreateHighlight":["POST","https://x.com/i/api/graphql/7jEc7ECTTDcNaqsMhjTxXg/CreateHighlight",{},"7jEc7ECTTDcNaqsMhjTxXg"],"CreateNoteTweet":["POST","https://x.com/i/api/graphql/mxov2Nc2Y-XglGy2ThzdEw/CreateNoteTweet",{"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"articles_preview_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":true},"mxov2Nc2Y-XglGy2ThzdEw"],"CreateRetweet":["POST","https://x.com/i/api/graphql/LFho5rIi4xcKO90p9jwG7A/CreateRetweet",{},"LFho5rIi4xcKO90p9jwG7A"],"CreateTweet":["POST","https://x.com/i/api/graphql/Ah3G_byjEDs_HSlgU0PyZw/CreateTweet",{"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"articles_preview_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":true},"Ah3G_byjEDs_HSlgU0PyZw"],"CreatorSubscriptionsTimeline":["GET","https://x.com/i/api/graphql/slXO2XTiqVXk7VUCA-aSTA/CreatorSubscriptionsTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"slXO2XTiqVXk7VUCA-aSTA"],"DataSaverMode":["GET","https://x.com/i/api/graphql/xF6sXnKJfS2AOylzxRjf6A/DataSaverMode",{},"xF6sXnKJfS2AOylzxRjf6A"],"WriteDataSaverPreferences":["POST","https://x.com/i/api/graphql/H03etWvZGz41YASxAU2YPg/WriteDataSaverPreferences",{},"H03etWvZGz41YASxAU2YPg"],"DeleteBookmark":["POST","https://x.com/i/api/graphql/Wlmlj2-xzyS1GN3a6cj-mQ/DeleteBookmark",{},"Wlmlj2-xzyS1GN3a6cj-mQ"],"DeleteContentDisclosure":["POST","https://x.com/i/api/graphql/YeIV-eqGwEZXDtYaDsJz2Q/DeleteContentDisclosure",{},"YeIV-eqGwEZXDtYaDsJz2Q"],"DeleteHighlight":["POST","https://x.com/i/api/graphql/ea-VVDSLIEYNY2_2aPg3Uw/DeleteHighlight",{},"ea-VVDSLIEYNY2_2aPg3Uw"],"DeleteRetweet":["POST","https://x.com/i/api/graphql/G4MoqBiE6aqyo4QWAgCy4w/DeleteRetweet",{},"G4MoqBiE6aqyo4QWAgCy4w"],"DeleteTweet":["POST","https://x.com/i/api/graphql/VaenaVgh5q5ih7kvyVjgtg/DeleteTweet",{},"VaenaVgh5q5ih7kvyVjgtg"],"DisableVerifiedPhoneLabel":["POST","https://x.com/i/api/graphql/g2m0pAOamawNtVIfjXNMJg/DisableVerifiedPhoneLabel",{},"g2m0pAOamawNtVIfjXNMJg"],"dmBlockUser":["POST","https://x.com/i/api/graphql/IYw9u1KEhrS-t-BXsau4Uw/dmBlockUser",{},"IYw9u1KEhrS-t-BXsau4Uw"],"DmNsfwMediaFilterUpdate":["POST","https://x.com/i/api/graphql/of_N6O33zfyD4qsFJMYFxA/DmNsfwMediaFilterUpdate",{},"of_N6O33zfyD4qsFJMYFxA"],"dmUnblockUser":["POST","https://x.com/i/api/graphql/Krbs6Nak_o7liWQwfV1jOQ/dmUnblockUser",{},"Krbs6Nak_o7liWQwfV1jOQ"],"EnableVerifiedPhoneLabel":["POST","https://x.com/i/api/graphql/C3RJFfMsb_KcEytpKmRRkw/EnableVerifiedPhoneLabel",{},"C3RJFfMsb_KcEytpKmRRkw"],"ExplorePage":["GET","https://x.com/i/api/graphql/fBh-Hh86uGqRgRs68v70Bg/ExplorePage",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"fBh-Hh86uGqRgRs68v70Bg"],"ExploreSidebar":["GET","https://x.com/i/api/graphql/G03DKZok3aNu7F3ndJPmXw/ExploreSidebar",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"G03DKZok3aNu7F3ndJPmXw"],"FavoriteTweet":["POST","https://x.com/i/api/graphql/lI07N6Otwv1PhnEgXILM7A/FavoriteTweet",{},"lI07N6Otwv1PhnEgXILM7A"],"Followers":["GET","https://x.com/i/api/graphql/efNzdTpE-mkUcLARCd3RPQ/Followers",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"efNzdTpE-mkUcLARCd3RPQ"],"FollowersYouKnow":["GET","https://x.com/i/api/graphql/dwvizjS4AcL6qn-i7Rgbdg/FollowersYouKnow",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"dwvizjS4AcL6qn-i7Rgbdg"],"Following":["GET","https://x.com/i/api/graphql/M3LO-sJg6BCWdEliN_C2fQ/Following",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"M3LO-sJg6BCWdEliN_C2fQ"],"GenerateDrmToken":["GET","https://x.com/i/api/graphql/6csp1Dw5r5zveD-1qaqXdA/GenerateDrmToken",{},"6csp1Dw5r5zveD-1qaqXdA"],"GenericTimelineById":["GET","https://x.com/i/api/graphql/44-y3H8pD6o0DvxOoZ6-IQ/GenericTimelineById",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"44-y3H8pD6o0DvxOoZ6-IQ"],"GetUsernameAvailabilityAndSuggestions":["POST","https://x.com/i/api/graphql/1bMz-9lPrmIXrhFmXntTHw/GetUsernameAvailabilityAndSuggestions",{},"1bMz-9lPrmIXrhFmXntTHw"],"GlobalCommunitiesLatestPostSearchTimeline":["GET","https://x.com/i/api/graphql/3PewHr8YKRoOlyHX7m8QjA/GlobalCommunitiesLatestPostSearchTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"3PewHr8YKRoOlyHX7m8QjA"],"GlobalCommunitiesPostSearchTimeline":["GET","https://x.com/i/api/graphql/GwoyCbMFgdEE8LUeRW-COQ/GlobalCommunitiesPostSearchTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"GwoyCbMFgdEE8LUeRW-COQ"],"HomeLatestTimeline":["GET","https://x.com/i/api/graphql/7LL9B2gjCKU7swZw3aKF7g/HomeLatestTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"7LL9B2gjCKU7swZw3aKF7g"],"HomeTimeline":["GET","https://x.com/i/api/graphql/y_gEr8-rsIu-XEOVAkh00A/HomeTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"y_gEr8-rsIu-XEOVAkh00A"],"Likes":["GET","https://x.com/i/api/graphql/JPxbOQGc_tXQ0Y29mvHKSw/Likes",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"JPxbOQGc_tXQ0Y29mvHKSw"],"ListAddMember":["POST","https://x.com/i/api/graphql/EadD8ivrhZhYQr2pDmCpjA/ListAddMember",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"EadD8ivrhZhYQr2pDmCpjA"],"DeleteListBanner":["POST","https://x.com/i/api/graphql/uT6t6CXdWqMF9UBPaQgxjw/DeleteListBanner",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"uT6t6CXdWqMF9UBPaQgxjw"],"EditListBanner":["POST","https://x.com/i/api/graphql/CChy7omMr21Rx5xgqzTDeA/EditListBanner",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"CChy7omMr21Rx5xgqzTDeA"],"ListBySlug":["GET","https://x.com/i/api/graphql/kPoa5ip1Zl3rYF0T-e2HcA/ListBySlug",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"kPoa5ip1Zl3rYF0T-e2HcA"],"CreateList":["POST","https://x.com/i/api/graphql/CzrvV0ePRFW1dPgLY6an7g/CreateList",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"CzrvV0ePRFW1dPgLY6an7g"],"ListCreationRecommendedUsers":["GET","https://x.com/i/api/graphql/XvltHB8d5ovCgxqbZCkYKw/ListCreationRecommendedUsers",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"XvltHB8d5ovCgxqbZCkYKw"],"DeleteList":["POST","https://x.com/i/api/graphql/UnN9Th1BDbeLjpgjGSpL3Q/DeleteList",{},"UnN9Th1BDbeLjpgjGSpL3Q"],"ListEditRecommendedUsers":["GET","https://x.com/i/api/graphql/uJa54v_kF89VL8JjzKrwkA/ListEditRecommendedUsers",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"uJa54v_kF89VL8JjzKrwkA"],"ListLatestTweetsTimeline":["GET","https://x.com/i/api/graphql/aJxgBm1YveGJCRiWJFx5WA/ListLatestTweetsTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"aJxgBm1YveGJCRiWJFx5WA"],"ListMembers":["GET","https://x.com/i/api/graphql/7FPk01hdc1jyzL6Gj8vMZw/ListMembers",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"7FPk01hdc1jyzL6Gj8vMZw"],"ListMemberships":["GET","https://x.com/i/api/graphql/pO-fNizLDMiRp2DodVNhbQ/ListMemberships",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"pO-fNizLDMiRp2DodVNhbQ"],"MuteList":["POST","https://x.com/i/api/graphql/ZYyanJsskNUcltu9bliMLA/MuteList",{},"ZYyanJsskNUcltu9bliMLA"],"ListOwnerships":["GET","https://x.com/i/api/graphql/ak2INPMd3uOVh26bGzOgKw/ListOwnerships",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"ak2INPMd3uOVh26bGzOgKw"],"ListByRestId":["GET","https://x.com/i/api/graphql/Tzkkg-NaBi_y1aAUUb6_eQ/ListByRestId",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"Tzkkg-NaBi_y1aAUUb6_eQ"],"ListRankedTweetsTimeline":["GET","https://x.com/i/api/graphql/DpPOvFDNcWz9UJvzQ2kO3A/ListRankedTweetsTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"DpPOvFDNcWz9UJvzQ2kO3A"],"ListRemoveMember":["POST","https://x.com/i/api/graphql/B5tMzrMYuFHJex_4EXFTSw/ListRemoveMember",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"B5tMzrMYuFHJex_4EXFTSw"],"ListSearchTimeline":["GET","https://x.com/i/api/graphql/_wNrVROKGXt6qlF06Lvvmw/ListSearchTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"_wNrVROKGXt6qlF06Lvvmw"],"ListSubscribe":["POST","https://x.com/i/api/graphql/qItCdxZic3vKHuF2nwO5cg/ListSubscribe",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"qItCdxZic3vKHuF2nwO5cg"],"ListSubscribers":["GET","https://x.com/i/api/graphql/1CItm5HI1tM0IdpFjG7nrQ/ListSubscribers",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"1CItm5HI1tM0IdpFjG7nrQ"],"UnmuteList":["POST","https://x.com/i/api/graphql/pMZrHRNsmEkXgbn3tOyr7Q/UnmuteList",{},"pMZrHRNsmEkXgbn3tOyr7Q"],"ListUnsubscribe":["POST","https://x.com/i/api/graphql/lJyQ2Rp6vk4h5czTYqOeLA/ListUnsubscribe",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"lJyQ2Rp6vk4h5czTYqOeLA"],"UpdateList":["POST","https://x.com/i/api/graphql/CToNDwmbHSq5tqV0ExBFeg/UpdateList",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"CToNDwmbHSq5tqV0ExBFeg"],"ListsDiscovery":["GET","https://x.com/i/api/graphql/cYGu1UfesoScFMv7sjOKiA/ListsDiscovery",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"cYGu1UfesoScFMv7sjOKiA"],"ListsManagementPageTimeline":["GET","https://x.com/i/api/graphql/FHavhcMS-6NrywtPkWiOHg/ListsManagementPageTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"FHavhcMS-6NrywtPkWiOHg"],"MediaTabVideoMixer":["GET","https://x.com/i/api/graphql/YuPIw3nKMWgS5Mfbz8VerA/MediaTabVideoMixer",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"YuPIw3nKMWgS5Mfbz8VerA"],"ModerateTweet":["POST","https://x.com/i/api/graphql/pjFnHGVqCjTcZol0xcBJjw/ModerateTweet",{},"pjFnHGVqCjTcZol0xcBJjw"],"ModeratedTimeline":["GET","https://x.com/i/api/graphql/pF0svfAO3blpIcrcVO1MNw/ModeratedTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"pF0svfAO3blpIcrcVO1MNw"],"MutedAccounts":["GET","https://x.com/i/api/graphql/mKBwSypgzeeZCF5A9W0dOQ/MutedAccounts",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"mKBwSypgzeeZCF5A9W0dOQ"],"PaymentsUsersTypeahead":["GET","https://x.com/i/api/graphql/pnP0TpmPEJiiJuN9T-LU4Q/PaymentsUsersTypeahead",{"responsive_web_graphql_timeline_navigation_enabled":true},"pnP0TpmPEJiiJuN9T-LU4Q"],"PinTimeline":["POST","https://x.com/i/api/graphql/y62a1ZmM0tI0kjTj4j8-LA/PinTimeline",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"y62a1ZmM0tI0kjTj4j8-LA"],"PinTweet":["POST","https://x.com/i/api/graphql/VIHsNu89pK-kW35JpHq7Xw/PinTweet",{},"VIHsNu89pK-kW35JpHq7Xw"],"PinnedTimelines":["GET","https://x.com/i/api/graphql/kjTRZeD3JnAnLEdAkVNyxw/PinnedTimelines",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"kjTRZeD3JnAnLEdAkVNyxw"],"ProfileFilter":["GET","https://x.com/i/api/graphql/mWqHJEVs-wPUNr5D1JdEUw/ProfileFilter",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"mWqHJEVs-wPUNr5D1JdEUw"],"ProfileUserPhoneState":["GET","https://x.com/i/api/graphql/5kUWP8C1hcd6omvg6HXXTQ/ProfileUserPhoneState",{},"5kUWP8C1hcd6omvg6HXXTQ"],"PutClientEducationFlag":["POST","https://x.com/i/api/graphql/IjQ-egg0uPkY11NyPMfRMQ/PutClientEducationFlag",{},"IjQ-egg0uPkY11NyPMfRMQ"],"CommunitiesRankedTimeline":["GET","https://x.com/i/api/graphql/UASdhg-4FnWLovFRZVmPYA/CommunitiesRankedTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"UASdhg-4FnWLovFRZVmPYA"],"RemoveFollower":["POST","https://x.com/i/api/graphql/QpNfg0kpPRfjROQ_9eOLXA/RemoveFollower",{},"QpNfg0kpPRfjROQ_9eOLXA"],"SearchTimeline":["GET","https://x.com/i/api/graphql/cGK-Qeg1XJc2sZ6kgQw_Iw/SearchTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"cGK-Qeg1XJc2sZ6kgQw_Iw"],"SharingAudiospacesListeningDataWithFollowersUpdate":["POST","https://x.com/i/api/graphql/5h0kNbk3ii97rmfY6CdgAA/SharingAudiospacesListeningDataWithFollowersUpdate",{},"5h0kNbk3ii97rmfY6CdgAA"],"SimilarPosts":["GET","https://x.com/i/api/graphql/gl18XUxEpg_YRLrz4k4iDw/SimilarPosts",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"gl18XUxEpg_YRLrz4k4iDw"],"SuperFollowers":["GET","https://x.com/i/api/graphql/JzdiOMUi4HnzdoSr6uyA8A/SuperFollowers",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"JzdiOMUi4HnzdoSr6uyA8A"],"SupportedLanguages":["GET","https://x.com/i/api/graphql/fZ5uZVeledO5SAseKnmTUg/SupportedLanguages",{},"fZ5uZVeledO5SAseKnmTUg"],"timelinesFeedback":["POST","https://x.com/i/api/graphql/vfVbgvTPTQ-dF_PQ5lD1WQ/timelinesFeedback",{},"vfVbgvTPTQ-dF_PQ5lD1WQ"],"TopicFollow":["POST","https://x.com/i/api/graphql/ElqSLWFmsPL4NlZI5e1Grg/TopicFollow",{},"ElqSLWFmsPL4NlZI5e1Grg"],"TopicLandingPage":["GET","https://x.com/i/api/graphql/mT6C7t5-i8KPwEpe5W7I0A/TopicLandingPage",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"mT6C7t5-i8KPwEpe5W7I0A"],"TopicNotInterested":["POST","https://x.com/i/api/graphql/cPCFdDAaqRjlMRYInZzoDA/TopicNotInterested",{},"cPCFdDAaqRjlMRYInZzoDA"],"TopicByRestId":["GET","https://x.com/i/api/graphql/4OUZZOonV2h60I0wdlQb_w/TopicByRestId",{},"4OUZZOonV2h60I0wdlQb_w"],"TopicToFollowSidebar":["GET","https://x.com/i/api/graphql/jczZMVDT2EoibbSsJe3Uxg/TopicToFollowSidebar",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"jczZMVDT2EoibbSsJe3Uxg"],"TopicUndoNotInterested":["POST","https://x.com/i/api/graphql/4tVnt6FoSxaX8L-mDDJo4Q/TopicUndoNotInterested",{},"4tVnt6FoSxaX8L-mDDJo4Q"],"TopicUnfollow":["POST","https://x.com/i/api/graphql/srwjU6JM_ZKTj_QMfUGNcw/TopicUnfollow",{},"srwjU6JM_ZKTj_QMfUGNcw"],"TopicsManagementPage":["GET","https://x.com/i/api/graphql/I5SLL-05bDm2-kJ4KgQ66g/TopicsManagementPage",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"I5SLL-05bDm2-kJ4KgQ66g"],"TopicsPickerPage":["GET","https://x.com/i/api/graphql/wJ53IRXDyNn4hqkmtQ3XiQ/TopicsPickerPage",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"wJ53IRXDyNn4hqkmtQ3XiQ"],"TopicsPickerPageById":["GET","https://x.com/i/api/graphql/3C93iAP7WsbMZHr6Y6mfrQ/TopicsPickerPageById",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"3C93iAP7WsbMZHr6Y6mfrQ"],"TrendHistory":["GET","https://x.com/i/api/graphql/eLzgJvZqZ8fR8jQav0EvCg/TrendHistory",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"eLzgJvZqZ8fR8jQav0EvCg"],"TrendRelevantUsers":["GET","https://x.com/i/api/graphql/6i7UZ_qAwmyqMt73C8W8pQ/TrendRelevantUsers",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"6i7UZ_qAwmyqMt73C8W8pQ"],"TVHomeMixer":["GET","https://x.com/i/api/graphql/nAZQBLZRVPJgouPNiqlOjQ/TVHomeMixer",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"nAZQBLZRVPJgouPNiqlOjQ"],"TweetDetail":["GET","https://x.com/i/api/graphql/ooUbmy0T2DmvwfjgARktiQ/TweetDetail",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"ooUbmy0T2DmvwfjgARktiQ"],"TweetResultByRestId":["GET","https://x.com/i/api/graphql/d6YKjvQ920F-D4Y1PruO-A/TweetResultByRestId",{"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":true},"d6YKjvQ920F-D4Y1PruO-A"],"TweetResultsByRestIds":["GET","https://x.com/i/api/graphql/vojBqBFpEyYMQ-LfRIKU4Q/TweetResultsByRestIds",{"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":true},"vojBqBFpEyYMQ-LfRIKU4Q"],"UnfavoriteTweet":["POST","https://x.com/i/api/graphql/ZYKSe-w7KEslx3JhSIk5LA/UnfavoriteTweet",{},"ZYKSe-w7KEslx3JhSIk5LA"],"UnmentionUserFromConversation":["POST","https://x.com/i/api/graphql/xVW9j3OqoBRY9d6_2OONEg/UnmentionUserFromConversation",{},"xVW9j3OqoBRY9d6_2OONEg"],"UnmoderateTweet":["POST","https://x.com/i/api/graphql/pVSyu6PA57TLvIE4nN2tsA/UnmoderateTweet",{},"pVSyu6PA57TLvIE4nN2tsA"],"UnpinTimeline":["POST","https://x.com/i/api/graphql/_flfMJhBPURJJLxAuIFAfw/UnpinTimeline",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"_flfMJhBPURJJLxAuIFAfw"],"UnpinTweet":["POST","https://x.com/i/api/graphql/BhKei844ypCyLYCg0nwigw/UnpinTweet",{},"BhKei844ypCyLYCg0nwigw"],"Upsells":["GET","https://x.com/i/api/graphql/Sg3BvwapuCMIjLJ7LGPhMA/Upsells",{"subscriptions_upsells_api_enabled":true},"Sg3BvwapuCMIjLJ7LGPhMA"],"UrtFixtures":["GET","https://x.com/i/api/graphql/Q0SMaJVOEfvuR1SJXa3ByA/UrtFixtures",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"Q0SMaJVOEfvuR1SJXa3ByA"],"UserArticlesTweets":["GET","https://x.com/i/api/graphql/pIjbNcwP5PudlVNVfYFGKQ/UserArticlesTweets",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"pIjbNcwP5PudlVNVfYFGKQ"],"UserBusinessProfileTeamTimeline":["GET","https://x.com/i/api/graphql/C6SXEtELFjzMKAD4ww7xOg/UserBusinessProfileTeamTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"C6SXEtELFjzMKAD4ww7xOg"],"UserByRestId":["GET","https://x.com/i/api/graphql/pBP53RhZiQHExruxf-I8ig/UserByRestId",{"hidden_profile_subscriptions_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"highlights_tweets_tab_ui_enabled":true,"responsive_web_twitter_article_notes_tab_enabled":true,"subscriptions_feature_can_gift_premium":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"pBP53RhZiQHExruxf-I8ig"],"UserByScreenName":["GET","https://x.com/i/api/graphql/AWbeRIdkLtqTRN7yL_H8yw/UserByScreenName",{"hidden_profile_subscriptions_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"subscriptions_verification_info_is_identity_verified_enabled":true,"subscriptions_verification_info_verified_since_enabled":true,"highlights_tweets_tab_ui_enabled":true,"responsive_web_twitter_article_notes_tab_enabled":true,"subscriptions_feature_can_gift_premium":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"AWbeRIdkLtqTRN7yL_H8yw"],"GetUserClaims":["GET","https://x.com/i/api/graphql/aQ-b88K_Lp7dgHX53MqNQQ/GetUserClaims",{},"aQ-b88K_Lp7dgHX53MqNQQ"],"UserCreatorSubscribers":["GET","https://x.com/i/api/graphql/gvalaVH93kd-pSan3k24XQ/UserCreatorSubscribers",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"gvalaVH93kd-pSan3k24XQ"],"UserCreatorSubscriptions":["GET","https://x.com/i/api/graphql/5nn_EKhv4toQ_rhMjjwGoA/UserCreatorSubscriptions",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"5nn_EKhv4toQ_rhMjjwGoA"],"UserHighlightsTweets":["GET","https://x.com/i/api/graphql/dZc2IL7haTg9IbZ-vDV3xw/UserHighlightsTweets",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"dZc2IL7haTg9IbZ-vDV3xw"],"UserMedia":["GET","https://x.com/i/api/graphql/SJpoWbz8n_i3vN3sOPfXvw/UserMedia",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"SJpoWbz8n_i3vN3sOPfXvw"],"UserPreferences":["GET","https://x.com/i/api/graphql/xFxU-O8hEYe74ovNVU74jA/UserPreferences",{},"xFxU-O8hEYe74ovNVU74jA"],"UserPromotableTweets":["GET","https://x.com/i/api/graphql/eJJnyGJXq8hBhT5bSRRsZg/UserPromotableTweets",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"eJJnyGJXq8hBhT5bSRRsZg"],"UserSessionsList":["GET","https://x.com/i/api/graphql/vJ-XatpmQSG8bDch8-t9Jw/UserSessionsList",{},"vJ-XatpmQSG8bDch8-t9Jw"],"UserSuperFollowTweets":["GET","https://x.com/i/api/graphql/pEf_Sj0MjLKQlZYaIvp0tw/UserSuperFollowTweets",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"pEf_Sj0MjLKQlZYaIvp0tw"],"UserTweets":["GET","https://x.com/i/api/graphql/eApPT8jppbYXlweF_ByTyA/UserTweets",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"eApPT8jppbYXlweF_ByTyA"],"UserTweetsAndReplies":["GET","https://x.com/i/api/graphql/aDl2OEiH_EFH10mA_ewZ9A/UserTweetsAndReplies",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"aDl2OEiH_EFH10mA_ewZ9A"],"UsersByRestIds":["GET","https://x.com/i/api/graphql/xavgLWWbFH8wm_8MQN8plQ/UsersByRestIds",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"xavgLWWbFH8wm_8MQN8plQ"],"UsersByScreenNames":["GET","https://x.com/i/api/graphql/ujL_oXbgVlDHQzWSTgzvnA/UsersByScreenNames",{"hidden_profile_subscriptions_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"subscriptions_verification_info_is_identity_verified_enabled":true,"subscriptions_verification_info_verified_since_enabled":true,"highlights_tweets_tab_ui_enabled":true,"responsive_web_twitter_article_notes_tab_enabled":true,"subscriptions_feature_can_gift_premium":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"ujL_oXbgVlDHQzWSTgzvnA"],"UsersVerifiedAvatars":["GET","https://x.com/i/api/graphql/x3JZoNX9ubSzoCIHoYo2NA/UsersVerifiedAvatars",{"responsive_web_graphql_timeline_navigation_enabled":true},"x3JZoNX9ubSzoCIHoYo2NA"],"Viewer":["GET","https://x.com/i/api/graphql/178EtFdhcGqmoyzKL4muaA/Viewer",{"subscriptions_upsells_api_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"178EtFdhcGqmoyzKL4muaA"],"ViewingOtherUsersTopicsPage":["GET","https://x.com/i/api/graphql/s8dU1-Vrf-P2pggeuDVAcw/ViewingOtherUsersTopicsPage",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"s8dU1-Vrf-P2pggeuDVAcw"],"AudioSpaceAddSharing":["POST","https://x.com/i/api/graphql/m6GroAvD3WU9kZ327yrHiA/AudioSpaceAddSharing",{"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":true},"m6GroAvD3WU9kZ327yrHiA"],"AudioSpaceById":["GET","https://x.com/i/api/graphql/VBZepNCJM3v3701b4s_CqA/AudioSpaceById",{"spaces_2022_h2_spaces_communities":true,"spaces_2022_h2_clipping":true,"creator_subscriptions_tweet_preview_api_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"VBZepNCJM3v3701b4s_CqA"],"AudioSpaceDeleteSharing":["POST","https://x.com/i/api/graphql/YMbfLMTUUEzEEMibvvR26Q/AudioSpaceDeleteSharing",{},"YMbfLMTUUEzEEMibvvR26Q"],"AudioSpaceSearch":["GET","https://x.com/i/api/graphql/NTq79TuSz6fHj8lQaferJw/AudioSpaceSearch",{},"NTq79TuSz6fHj8lQaferJw"],"BrowseSpaceTopics":["GET","https://x.com/i/api/graphql/TYpVV9QioZfViHqEqRZxJA/BrowseSpaceTopics",{},"TYpVV9QioZfViHqEqRZxJA"],"SubscribeToScheduledSpace":["POST","https://x.com/i/api/graphql/Sxn4YOlaAwEKjnjWV0h7Mw/SubscribeToScheduledSpace",{},"Sxn4YOlaAwEKjnjWV0h7Mw"],"UnsubscribeFromScheduledSpace":["POST","https://x.com/i/api/graphql/Zevhh76Msw574ZSs2NQHGQ/UnsubscribeFromScheduledSpace",{},"Zevhh76Msw574ZSs2NQHGQ"],"PinReply":["POST","https://x.com/i/api/graphql/GA2_1uKP9b_GyR4MVAQXAw/PinReply",{},"GA2_1uKP9b_GyR4MVAQXAw"],"UnpinReply":["POST","https://x.com/i/api/graphql/iRe6ig5OV1EzOtldNIuGDQ/UnpinReply",{},"iRe6ig5OV1EzOtldNIuGDQ"],"CreateDraftTweet":["POST","https://x.com/i/api/graphql/cH9HZWz_EW9gnswvA4ZRiQ/CreateDraftTweet",{},"cH9HZWz_EW9gnswvA4ZRiQ"],"CreateScheduledTweet":["POST","https://x.com/i/api/graphql/LCVzRQGxOaGnOnYH01NQXg/CreateScheduledTweet",{},"LCVzRQGxOaGnOnYH01NQXg"],"DeleteDraftTweet":["POST","https://x.com/i/api/graphql/bkh9G3FGgTldS9iTKWWYYw/DeleteDraftTweet",{},"bkh9G3FGgTldS9iTKWWYYw"],"DeleteScheduledTweet":["POST","https://x.com/i/api/graphql/CTOVqej0JBXAZSwkp1US0g/DeleteScheduledTweet",{},"CTOVqej0JBXAZSwkp1US0g"],"EditDraftTweet":["POST","https://x.com/i/api/graphql/JIeXE-I6BZXHfxsgOkyHYQ/EditDraftTweet",{},"JIeXE-I6BZXHfxsgOkyHYQ"],"EditScheduledTweet":["POST","https://x.com/i/api/graphql/_mHkQ5LHpRRjSXKOcG6eZw/EditScheduledTweet",{},"_mHkQ5LHpRRjSXKOcG6eZw"],"FetchDraftTweets":["GET","https://x.com/i/api/graphql/ff5ciLFuifghdOtDoJj6Ww/FetchDraftTweets",{},"ff5ciLFuifghdOtDoJj6Ww"],"FetchScheduledTweets":["GET","https://x.com/i/api/graphql/cmwoO7AWw5zCpd8TaPFQHg/FetchScheduledTweets",{},"cmwoO7AWw5zCpd8TaPFQHg"],"BirdwatchAdmitUser":["POST","https://x.com/i/api/graphql/s_L4H2iPhZoMtWiqHxd9LA/BirdwatchAdmitUser",{},"s_L4H2iPhZoMtWiqHxd9LA"],"BirdwatchAliasSelect":["POST","https://x.com/i/api/graphql/3ss48WFwGokBH_gj8t_8aQ/BirdwatchAliasSelect",{},"3ss48WFwGokBH_gj8t_8aQ"],"BirdwatchFetchAuthenticatedBirdwatchMatchSlice":["GET","https://x.com/i/api/graphql/SP1viw4lDEQTcdcxeB_cig/BirdwatchFetchAuthenticatedBirdwatchMatchSlice",{"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":true},"SP1viw4lDEQTcdcxeB_cig"],"BirdwatchFetchContributorNotesSlice":["GET","https://x.com/i/api/graphql/NCj9b6LWMM1IUawrngTEkA/BirdwatchFetchContributorNotesSlice",{"responsive_web_birdwatch_media_notes_enabled":true,"responsive_web_birdwatch_fast_notes_badge_enabled":true,"responsive_web_birdwatch_url_notes_enabled":true,"responsive_web_birdwatch_live_note_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":true},"NCj9b6LWMM1IUawrngTEkA"],"BirdwatchCreateAppeal":["POST","https://x.com/i/api/graphql/TKdL0YFsX4DMOpMKeneLvA/BirdwatchCreateAppeal",{},"TKdL0YFsX4DMOpMKeneLvA"],"BirdwatchCreateBatSignal":["POST","https://x.com/i/api/graphql/hflLsUawCquMOPVnpZuNPg/BirdwatchCreateBatSignal",{},"hflLsUawCquMOPVnpZuNPg"],"BirdwatchCreateNote":["POST","https://x.com/i/api/graphql/lE3V3JvTjuPA4y_pGo77Ww/BirdwatchCreateNote",{"responsive_web_birdwatch_media_notes_enabled":true,"responsive_web_birdwatch_url_notes_enabled":true,"responsive_web_grok_community_note_translation_is_enabled":true,"responsive_web_birdwatch_fast_notes_badge_enabled":true,"responsive_web_birdwatch_live_note_enabled":true,"responsive_web_birdwatch_note_internal_insights_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true},"lE3V3JvTjuPA4y_pGo77Ww"],"BirdwatchCreateRating":["POST","https://x.com/i/api/graphql/gbshFt1Vmddrlio4vHWhhQ/BirdwatchCreateRating",{},"gbshFt1Vmddrlio4vHWhhQ"],"BirdwatchDeleteBatSignal":["POST","https://x.com/i/api/graphql/yQF40wfWdHfXeKL4ZVklcw/BirdwatchDeleteBatSignal",{},"yQF40wfWdHfXeKL4ZVklcw"],"BirdwatchDeleteNote":["POST","https://x.com/i/api/graphql/IKS_qrShkDyor6Ri1ahd9g/BirdwatchDeleteNote",{},"IKS_qrShkDyor6Ri1ahd9g"],"BirdwatchDeleteRating":["POST","https://x.com/i/api/graphql/OpvCOyOoQClUND66zDzrnA/BirdwatchDeleteRating",{},"OpvCOyOoQClUND66zDzrnA"],"BirdwatchEditNotificationSettings":["POST","https://x.com/i/api/graphql/FLgLReVIssXjB_ui3wcrRQ/BirdwatchEditNotificationSettings",{},"FLgLReVIssXjB_ui3wcrRQ"],"BirdwatchEditUserSettings":["POST","https://x.com/i/api/graphql/k1Unfqb74V4sf2d7-kFkhg/BirdwatchEditUserSettings",{},"k1Unfqb74V4sf2d7-kFkhg"],"BirdwatchFetchAliasSelfSelectOptions":["GET","https://x.com/i/api/graphql/szoXMke8AZOErso908iglw/BirdwatchFetchAliasSelfSelectOptions",{},"szoXMke8AZOErso908iglw"],"BirdwatchFetchAliasSelfSelectStatus":["GET","https://x.com/i/api/graphql/LUEdtkcpBlGktUtms4BvwA/BirdwatchFetchAliasSelfSelectStatus",{},"LUEdtkcpBlGktUtms4BvwA"],"BirdwatchFetchAuthenticatedUserProfile":["GET","https://x.com/i/api/graphql/kD74-qBfrdRT5rO9YOl57g/BirdwatchFetchAuthenticatedUserProfile",{"responsive_web_birdwatch_top_contributor_enabled":true,"responsive_web_birdwatch_note_limit_enabled":true},"kD74-qBfrdRT5rO9YOl57g"],"BirdwatchFetchBatSignal":["GET","https://x.com/i/api/graphql/7LFdey6iP2bf5f2_aN80Ng/BirdwatchFetchBatSignal",{"responsive_web_birdwatch_note_request_sources_enabled":true,"responsive_web_birdwatch_live_note_enabled":true},"7LFdey6iP2bf5f2_aN80Ng"],"BirdwatchFetchBirdwatchProfile":["GET","https://x.com/i/api/graphql/id9iGfEQF47W1kvRBHUmRQ/BirdwatchFetchBirdwatchProfile",{"responsive_web_birdwatch_top_contributor_enabled":true},"id9iGfEQF47W1kvRBHUmRQ"],"BirdwatchFetchCanTweetBeMediaNote":["GET","https://x.com/i/api/graphql/0EW8KDGMK0g3EfCF0iAhsg/BirdwatchFetchCanTweetBeMediaNote",{"responsive_web_birdwatch_media_notes_enabled":true},"0EW8KDGMK0g3EfCF0iAhsg"],"BirdwatchFetchGlobalTimeline":["GET","https://x.com/i/api/graphql/P0cB4BIhkiz7xsCwFlLeIQ/BirdwatchFetchGlobalTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"P0cB4BIhkiz7xsCwFlLeIQ"],"BirdwatchFetchNoteTranslation":["GET","https://x.com/i/api/graphql/P6c4dkUUlxR6cz7uWAGzrw/BirdwatchFetchNoteTranslation",{"responsive_web_birdwatch_translation_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true},"P6c4dkUUlxR6cz7uWAGzrw"],"BirdwatchFetchNotes":["GET","https://x.com/i/api/graphql/ScWHi30kNlPHzGySYsoFPg/BirdwatchFetchNotes",{"responsive_web_birdwatch_live_note_enabled":true,"responsive_web_birdwatch_enforce_author_user_quotas":true,"responsive_web_birdwatch_media_notes_enabled":true,"responsive_web_birdwatch_url_notes_enabled":true,"responsive_web_grok_community_note_translation_is_enabled":true,"responsive_web_birdwatch_fast_notes_badge_enabled":true,"responsive_web_birdwatch_note_internal_insights_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true},"ScWHi30kNlPHzGySYsoFPg"],"BirdwatchFetchOneNote":["GET","https://x.com/i/api/graphql/iHtw3OiprlkkPBel6kOEfg/BirdwatchFetchOneNote",{"responsive_web_birdwatch_media_notes_enabled":true,"responsive_web_birdwatch_url_notes_enabled":true,"responsive_web_grok_community_note_translation_is_enabled":true,"responsive_web_birdwatch_fast_notes_badge_enabled":true,"responsive_web_birdwatch_live_note_enabled":true,"responsive_web_birdwatch_note_internal_insights_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true},"iHtw3OiprlkkPBel6kOEfg"],"BirdwatchFetchPublicData":["GET","https://x.com/i/api/graphql/T4Qdev0aBeS9tK9v4TkgQg/BirdwatchFetchPublicData",{"responsive_web_birdwatch_note_request_download_enabled":true},"T4Qdev0aBeS9tK9v4TkgQg"],"BirdwatchFetchSignUpEligiblity":["GET","https://x.com/i/api/graphql/yASGrjmFWghK2T0XC3uGVg/BirdwatchFetchSignUpEligiblity",{"responsive_web_birdwatch_signup_prompt_enabled":true},"yASGrjmFWghK2T0XC3uGVg"],"BirdwatchFetchSourceLinkSlice":["GET","https://x.com/i/api/graphql/kbK3GGahK3jtq6iGSCHlSQ/BirdwatchFetchSourceLinkSlice",{"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":true},"kbK3GGahK3jtq6iGSCHlSQ"],"BirdwatchFetchSourceLinkTweet":["GET","https://x.com/i/api/graphql/izQ6fkwrtwKkpNB4M-J0SA/BirdwatchFetchSourceLinkTweet",{"responsive_web_birdwatch_note_request_sources_enabled":true},"izQ6fkwrtwKkpNB4M-J0SA"],"BirdwatchFetchSuggestionFeedbackOverview":["GET","https://x.com/i/api/graphql/BC399HnZUmUHadS8gHKRfA/BirdwatchFetchSuggestionFeedbackOverview",{"responsive_web_birdwatch_media_notes_enabled":true,"responsive_web_birdwatch_fast_notes_badge_enabled":true,"responsive_web_birdwatch_url_notes_enabled":true,"responsive_web_birdwatch_live_note_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_enhance_cards_enabled":true},"BC399HnZUmUHadS8gHKRfA"],"BirdwatchProfileAcknowledgeEarnOut":["POST","https://x.com/i/api/graphql/cED9wJy8Nd1kZCCYuIq9zQ/BirdwatchProfileAcknowledgeEarnOut",{},"cED9wJy8Nd1kZCCYuIq9zQ"],"BirdwatchRemoveUser":["POST","https://x.com/i/api/graphql/6ZEO6UxqjlK4nefrhotZHw/BirdwatchRemoveUser",{},"6ZEO6UxqjlK4nefrhotZHw"],"BookmarkFolderTimeline":["GET","https://x.com/i/api/graphql/LdT6YZk9yx_o1xbLN61epw/BookmarkFolderTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"LdT6YZk9yx_o1xbLN61epw"],"BookmarkFoldersSlice":["GET","https://x.com/i/api/graphql/i78YDd0Tza-dV4SYs58kRg/BookmarkFoldersSlice",{},"i78YDd0Tza-dV4SYs58kRg"],"bookmarkTweetToFolder":["POST","https://x.com/i/api/graphql/4KHZvvNbHNf07bsgnL9gWA/bookmarkTweetToFolder",{},"4KHZvvNbHNf07bsgnL9gWA"],"Bookmarks":["GET","https://x.com/i/api/graphql/MhXAbUeE0RsRoCfv-bgscA/Bookmarks",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"MhXAbUeE0RsRoCfv-bgscA"],"ClearGrokConversations":["POST","https://x.com/i/api/graphql/83Gg0lfI-47Z3-ZOxyUjiQ/ClearGrokConversations",{},"83Gg0lfI-47Z3-ZOxyUjiQ"],"createBookmarkFolder":["POST","https://x.com/i/api/graphql/6Xxqpq8TM_CREYiuof_h5w/createBookmarkFolder",{},"6Xxqpq8TM_CREYiuof_h5w"],"CreateGrokConversation":["POST","https://x.com/i/api/graphql/vvC5uy7pWWHXS2aDi1FZeA/CreateGrokConversation",{},"vvC5uy7pWWHXS2aDi1FZeA"],"BookmarksAllDelete":["POST","https://x.com/i/api/graphql/skiACZKC1GDYli-M8RzEPQ/BookmarksAllDelete",{},"skiACZKC1GDYli-M8RzEPQ"],"DeleteBookmarkFolder":["POST","https://x.com/i/api/graphql/2UTTsO-6zs93XqlEUZPsSg/DeleteBookmarkFolder",{},"2UTTsO-6zs93XqlEUZPsSg"],"DeleteGrokMessage":["POST","https://x.com/i/api/graphql/kaH0vdJmbuocpRAeWpRC7A/DeleteGrokMessage",{},"kaH0vdJmbuocpRAeWpRC7A"],"EditBookmarkFolder":["POST","https://x.com/i/api/graphql/a6kPp1cS1Dgbsjhapz1PNw/EditBookmarkFolder",{},"a6kPp1cS1Dgbsjhapz1PNw"],"GrokConversationItemsByRestId":["GET","https://x.com/i/api/graphql/RKN_Oo4LhSVbNg6S77byxg/GrokConversationItemsByRestId",{"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":true},"RKN_Oo4LhSVbNg6S77byxg"],"GrokHistory":["GET","https://x.com/i/api/graphql/9Hyh5D4-WXLnExZkONSkZg/GrokHistory",{},"9Hyh5D4-WXLnExZkONSkZg"],"GrokHome":["GET","https://x.com/i/api/graphql/QAPGIKJVaPXYD-gO9kxc9w/GrokHome",{},"QAPGIKJVaPXYD-gO9kxc9w"],"GrokMediaHistory":["GET","https://x.com/i/api/graphql/azn3Sg0APPjb2Jtd7gqxsw/GrokMediaHistory",{},"azn3Sg0APPjb2Jtd7gqxsw"],"GrokPinConversation":["POST","https://x.com/i/api/graphql/_6czUDKiWzcvBUKMoDZ19w/GrokPinConversation",{},"_6czUDKiWzcvBUKMoDZ19w"],"GrokPinnedConversations":["GET","https://x.com/i/api/graphql/BHKxYTkc5SCupV7oqJBr0g/GrokPinnedConversations",{},"BHKxYTkc5SCupV7oqJBr0g"],"SearchGrokConversations":["GET","https://x.com/i/api/graphql/Sr2QEitvnemma5D2NJlA2Q/SearchGrokConversations",{},"Sr2QEitvnemma5D2NJlA2Q"],"GrokShare":["GET","https://x.com/i/api/graphql/1gugdyPHktFP3Y_zBRk8Vg/GrokShare",{"creator_subscriptions_tweet_preview_api_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":true},"1gugdyPHktFP3Y_zBRk8Vg"],"GrokUnpinConversation":["POST","https://x.com/i/api/graphql/-5e798p4EVbuhGGFFuw3Tg/GrokUnpinConversation",{},"-5e798p4EVbuhGGFFuw3Tg"],"GrokUserEventsLog":["POST","https://x.com/i/api/graphql/AB0damyVo0wBhhebQIwtsg/GrokUserEventsLog",{},"AB0damyVo0wBhhebQIwtsg"],"RemoveTweetFromBookmarkFolder":["POST","https://x.com/i/api/graphql/2Qbj9XZvtUvyJB4gFwWfaA/RemoveTweetFromBookmarkFolder",{},"2Qbj9XZvtUvyJB4gFwWfaA"],"SetGrokPreferences":["POST","https://x.com/i/api/graphql/NqLS09LPofalCjVhFolKtA/SetGrokPreferences",{},"NqLS09LPofalCjVhFolKtA"],"SidebarUserRecommendations":["GET","https://x.com/i/api/graphql/-Afl9E3-pBgYsJ3jNUWV3Q/SidebarUserRecommendations",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"-Afl9E3-pBgYsJ3jNUWV3Q"],"NotificationsTimeline":["GET","https://x.com/i/api/graphql/6Ak-UGq5AlPojzMzjd_j6A/NotificationsTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"6Ak-UGq5AlPojzMzjd_j6A"],"EnableLoggedOutWebNotifications":["POST","https://x.com/i/api/graphql/BqIHKmwZKtiUBPi07jKctg/EnableLoggedOutWebNotifications",{},"BqIHKmwZKtiUBPi07jKctg"],"ListProductSubscriptions":["GET","https://x.com/i/api/graphql/V8-RP7SxlI4qzRmpCmEqgw/ListProductSubscriptions",{"subscriptions_management_fetch_next_billing_time":true,"subscriptions_marketing_page_fetch_promotions":true},"V8-RP7SxlI4qzRmpCmEqgw"],"NotABotCheckoutUrlWithEligibility":["POST","https://x.com/i/api/graphql/RM4x9h3tF8bCn69VV3-gRg/NotABotCheckoutUrlWithEligibility",{},"RM4x9h3tF8bCn69VV3-gRg"],"SubscriptionCheckoutUrlWithEligibility":["POST","https://x.com/i/api/graphql/-kH-xt82ZhKnAMTXv1Fuzg/SubscriptionCheckoutUrlWithEligibility",{},"-kH-xt82ZhKnAMTXv1Fuzg"],"SubscriptionProductDetails":["GET","https://x.com/i/api/graphql/el6V21NAvHxCSbMqcuY45w/SubscriptionProductDetails",{"subscriptions_marketing_page_fetch_promotions":true},"el6V21NAvHxCSbMqcuY45w"],"SwitchTier":["POST","https://x.com/i/api/graphql/73t92vAzJ9DI1WygCcD7WQ/SwitchTier",{},"73t92vAzJ9DI1WygCcD7WQ"],"DmAllSearchSlice":["GET","https://x.com/i/api/graphql/b8pIQTo7MQZPLKm3Yet-QA/DmAllSearchSlice",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"b8pIQTo7MQZPLKm3Yet-QA"],"DmGroupSearchSlice":["GET","https://x.com/i/api/graphql/LxrvmqF3Lokl_BYZ1c83LA/DmGroupSearchSlice",{},"LxrvmqF3Lokl_BYZ1c83LA"],"DmMutedTimeline":["GET","https://x.com/i/api/graphql/_J2hUTLldFgNVxLCIYimUA/DmMutedTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"_J2hUTLldFgNVxLCIYimUA"],"DmPeopleSearchSlice":["GET","https://x.com/i/api/graphql/c1MnRRmI-_Bggpntlq9-hQ/DmPeopleSearchSlice",{},"c1MnRRmI-_Bggpntlq9-hQ"],"CreateWebSessionBind":["POST","https://x.com/i/api/graphql/0qFmnKTY3JwBZnqDdQrtHw/CreateWebSessionBind",{},"0qFmnKTY3JwBZnqDdQrtHw"],"RefreshWebSessionBind":["POST","https://x.com/i/api/graphql/N9LNeEU2xRb9vX_JRjgEjg/RefreshWebSessionBind",{},"N9LNeEU2xRb9vX_JRjgEjg"],"ArticleTimeline":["GET","https://x.com/i/api/graphql/Z9LagzcMhdZrkj8MVnFPAQ/ArticleTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"Z9LagzcMhdZrkj8MVnFPAQ"],"ArticleTweetsTimeline":["GET","https://x.com/i/api/graphql/841Us3lmuHDM63-mWZm65g/ArticleTweetsTimeline",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"841Us3lmuHDM63-mWZm65g"],"CommunityBoostCreateRating":["POST","https://x.com/i/api/graphql/k1gINntkffB5NvtVgJBFKw/CommunityBoostCreateRating",{},"k1gINntkffB5NvtVgJBFKw"],"CommunityBoostDeleteRating":["POST","https://x.com/i/api/graphql/Az1pj83H-fBSENAeV-lNMA/CommunityBoostDeleteRating",{},"Az1pj83H-fBSENAeV-lNMA"],"CommunityBoostFetchPivot":["GET","https://x.com/i/api/graphql/ob-WH21vXAVZP7S4JwqN1Q/CommunityBoostFetchPivot",{},"ob-WH21vXAVZP7S4JwqN1Q"],"CommunityBoostFetchPublicData":["GET","https://x.com/i/api/graphql/mtel1c9ozKWaWr9-D2wMwg/CommunityBoostFetchPublicData",{},"mtel1c9ozKWaWr9-D2wMwg"],"ActionTrend":["POST","https://x.com/i/api/graphql/imr0xefZmILHTgb6-9pe3g/ActionTrend",{},"imr0xefZmILHTgb6-9pe3g"],"AiTrendByRestId":["GET","https://x.com/i/api/graphql/70T_WmJSm2lBjaT1xzorRQ/AiTrendByRestId",{"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_enhance_cards_enabled":true},"70T_WmJSm2lBjaT1xzorRQ"],"ReportTrend":["POST","https://x.com/i/api/graphql/3BZlCEmD645zQ-MpJM19CA/ReportTrend",{},"3BZlCEmD645zQ-MpJM19CA"],"SaveTrend":["POST","https://x.com/i/api/graphql/_fJD2rm-lJI06lKxbUZT2Q/SaveTrend",{},"_fJD2rm-lJI06lKxbUZT2Q"],"LiveCommerceItemsSlice":["GET","https://x.com/i/api/graphql/-lnNX56S2YrZYrLzbccFAQ/LiveCommerceItemsSlice",{},"-lnNX56S2YrZYrLzbccFAQ"],"ArticleEntitiesSlice":["GET","https://x.com/i/api/graphql/cMMcpaRIk_-FJKdQ08HiDQ/ArticleEntitiesSlice",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"cMMcpaRIk_-FJKdQ08HiDQ"],"ArticleEntityDelete":["POST","https://x.com/i/api/graphql/e4lWqB6m2TA8Fn_j9L9xEA/ArticleEntityDelete",{},"e4lWqB6m2TA8Fn_j9L9xEA"],"ArticleEntityDraftCreate":["POST","https://x.com/i/api/graphql/t5-e2kJcCqqJ_MsZ0c07Rg/ArticleEntityDraftCreate",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"t5-e2kJcCqqJ_MsZ0c07Rg"],"ArticleEntityPublish":["POST","https://x.com/i/api/graphql/D7SXoTdAoDmYacGzp9KQQw/ArticleEntityPublish",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"D7SXoTdAoDmYacGzp9KQQw"],"ArticleEntityResultByRestId":["GET","https://x.com/i/api/graphql/id8pHQbQi7eZ6P9mA1th1Q/ArticleEntityResultByRestId",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"id8pHQbQi7eZ6P9mA1th1Q"],"ArticleEntityUnpublish":["POST","https://x.com/i/api/graphql/hQGA3NRU9IkosCbkAJQLjA/ArticleEntityUnpublish",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"hQGA3NRU9IkosCbkAJQLjA"],"ArticleEntityUpdateContent":["POST","https://x.com/i/api/graphql/IzVdegTuct9uoXRK5L93Qg/ArticleEntityUpdateContent",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"IzVdegTuct9uoXRK5L93Qg"],"ArticleEntityUpdateCoverMedia":["POST","https://x.com/i/api/graphql/ImdpGnpk1xo9yYJBIwHsvw/ArticleEntityUpdateCoverMedia",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"ImdpGnpk1xo9yYJBIwHsvw"],"ArticleEntityUpdateTitle":["POST","https://x.com/i/api/graphql/5wp_YbfxSfYJTiLWb4tYnA/ArticleEntityUpdateTitle",{"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true},"5wp_YbfxSfYJTiLWb4tYnA"],"SetDefault":["POST","https://x.com/i/api/graphql/QEMLEzEMzoPNbeauKCCLbg/SetDefault",{},"QEMLEzEMzoPNbeauKCCLbg"],"DeletePaymentMethod":["POST","https://x.com/i/api/graphql/VaaLGwK5KNLoc7wsOmp4uw/DeletePaymentMethod",{},"VaaLGwK5KNLoc7wsOmp4uw"],"PaymentMethods":["GET","https://x.com/i/api/graphql/mPF_G9okpbZuLcD6mN8K9g/PaymentMethods",{},"mPF_G9okpbZuLcD6mN8K9g"],"AdAccounts":["GET","https://x.com/i/api/graphql/a8KxGfFQAmm3WxqemuqSRA/AdAccounts",{},"a8KxGfFQAmm3WxqemuqSRA"],"AudienceEstimate":["GET","https://x.com/i/api/graphql/1LYVUabJBYkPlUAWRabB3g/AudienceEstimate",{},"1LYVUabJBYkPlUAWRabB3g"],"BoostAudienceEstimate":["GET","https://x.com/i/api/graphql/hiAXpFX4zFb6vOvGctGYyQ/BoostAudienceEstimate",{},"hiAXpFX4zFb6vOvGctGYyQ"],"Budgets":["GET","https://x.com/i/api/graphql/mbK3oSQotwcJXyQIBE3uYw/Budgets",{},"mbK3oSQotwcJXyQIBE3uYw"],"Coupons":["GET","https://x.com/i/api/graphql/R1h43jnAl2bsDoUkgZb7NQ/Coupons",{},"R1h43jnAl2bsDoUkgZb7NQ"],"CreateQuickPromotion":["POST","https://x.com/i/api/graphql/oDSoVgHhJxnd5IkckgPZdg/CreateQuickPromotion",{},"oDSoVgHhJxnd5IkckgPZdg"],"QuickPromoteEligibility":["GET","https://x.com/i/api/graphql/LtpCXh66W-uXh7u7XSRA8Q/QuickPromoteEligibility",{},"LtpCXh66W-uXh7u7XSRA8Q"],"EnrollCoupon":["POST","https://x.com/i/api/graphql/SOyGmNGaEXcvk15s5bqDrA/EnrollCoupon",{},"SOyGmNGaEXcvk15s5bqDrA"],"TargetingCatalogSearch":["GET","https://x.com/i/api/graphql/z7Ij1OnFDsb1Is08hkBDKw/TargetingCatalogSearch",{},"z7Ij1OnFDsb1Is08hkBDKw"],"WriteEmailNotificationSettings":["POST","https://x.com/i/api/graphql/2qKKYFQift8p5-J1k6kqxQ/WriteEmailNotificationSettings",{},"2qKKYFQift8p5-J1k6kqxQ"],"ViewerEmailSettings":["GET","https://x.com/i/api/graphql/JpjlNgn4sLGvS6tgpTzYBg/ViewerEmailSettings",{},"JpjlNgn4sLGvS6tgpTzYBg"],"DisableUserAccountLabel":["POST","https://x.com/i/api/graphql/_ckHEj05gan2VfNHG6thBA/DisableUserAccountLabel",{},"_ckHEj05gan2VfNHG6thBA"],"UserAccountLabel":["GET","https://x.com/i/api/graphql/rD5gLxVmMvtdtYU1UHWlFQ/UserAccountLabel",{},"rD5gLxVmMvtdtYU1UHWlFQ"],"UniversalSearchFeedbackMutation":["POST","https://x.com/i/api/graphql/qaIzg304L134B5-NI43j2A/UniversalSearchFeedbackMutation",{},"qaIzg304L134B5-NI43j2A"],"ImmersiveMedia":["GET","https://x.com/i/api/graphql/3V3JGQky82Sf-RUPiR7ifA/ImmersiveMedia",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"3V3JGQky82Sf-RUPiR7ifA"],"ImmersiveProfile":["GET","https://x.com/i/api/graphql/cHGtvewlLpN-CNjoV5aEMw/ImmersiveProfile",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"cHGtvewlLpN-CNjoV5aEMw"],"Favoriters":["GET","https://x.com/i/api/graphql/oXXP-2dfybUgdp5iSp6dIg/Favoriters",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"oXXP-2dfybUgdp5iSp6dIg"],"Retweeters":["GET","https://x.com/i/api/graphql/tkd9_KXT2iXEshDFHrdfuw/Retweeters",{"rweb_video_screen_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"articles_preview_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_enhance_cards_enabled":true},"tkd9_KXT2iXEshDFHrdfuw"],"TweetEditHistory":["GET","https://x.com/i/api/graphql/upS9teTSG45aljmP9oTuXA/TweetEditHistory",{"premium_content_api_read_enabled":true,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":true,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"rweb_video_screen_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":true,"responsive_web_grok_show_grok_translated_post":true,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":true,"rweb_tipjar_consumption_enabled":true,"verified_phone_label_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":true,"articles_preview_enabled":true,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"creator_subscriptions_tweet_preview_api_enabled":true,"responsive_web_enhance_cards_enabled":true},"upS9teTSG45aljmP9oTuXA"]}; \ No newline at end of file diff --git a/src/emusks-local/static/v1.1.js b/src/emusks-local/static/v1.1.js new file mode 100644 index 0000000..3316e68 --- /dev/null +++ b/src/emusks-local/static/v1.1.js @@ -0,0 +1 @@ +export default {"account/multi/list":["get","https://api.x.com/1.1/account/multi/list.json"],"onboarding/sso_init":["post","https://api.x.com/1.1/onboarding/sso_init.json"],"account/logout":["post","https://api.x.com/1.1/account/logout.json"],"account/multi/clean":["post","https://api.x.com/1.1/account/multi/clean.json"],"account/multi/add":["post","https://api.x.com/1.1/account/multi/add.json"],"account/multi/switch":["post","https://api.x.com/1.1/account/multi/switch.json"],"account/multi/logout_all":["post","https://api.x.com/1.1/account/multi/logout_all.json"],"dm/welcome_messages/add_to_conversation":["post","https://api.x.com/1.1/dm/welcome_messages/add_to_conversation.json"],"dm/conversation/bulk_delete":["post","https://api.x.com/1.1/dm/conversation/bulk_delete.json"],"dm/edit":["post","https://api.x.com/1.1/dm/edit.json"],"dm/conversation":["get","https://api.x.com/1.1/dm/conversation.json"],"dm/inbox_initial_state":["get","https://api.x.com/1.1/dm/inbox_initial_state.json"],"dm/user_updates":["get","https://api.x.com/1.1/dm/user_updates.json"],"dm/search/query":["post","https://api.x.com/1.1/dm/search/query.json"],"dm/user/update_relationship_state":["post","https://api.x.com/1.1/dm/user/update_relationship_state.json"],"dm/permissions":["get","https://api.x.com/1.1/dm/permissions.json"],"dm/permissions/secret":["get","https://api.x.com/1.1/dm/permissions/secret.json"],"direct_messages/report_spam":["post","https://api.x.com/1.1/direct_messages/report_spam.json"],"dm/report":["post","https://api.x.com/1.1/dm/report.json"],"dm/update_last_seen_event_id":["post","https://api.x.com/1.1/dm/update_last_seen_event_id.json"],"friendships/incoming":["get","https://api.x.com/1.1/friendships/incoming.json"],"friends/list":["get","https://api.x.com/1.1/friends/list.json"],"friends/following/list":["get","https://api.x.com/1.1/friends/following/list.json"],"friendships/accept":["post","https://api.x.com/1.1/friendships/accept.json"],"friendships/deny":["post","https://api.x.com/1.1/friendships/deny.json"],"friendships/update":["post","https://api.x.com/1.1/friendships/update.json"],"friendships/create_all":["post","https://api.x.com/1.1/friendships/create_all.json"],"friendships/destroy_all":["post","https://api.x.com/1.1/friendships/destroy_all.json"],"jot/external_referer":["post","https://api.x.com/1.1/jot/external_referer.json"],"lists/memberships":["get","https://api.x.com/1.1/lists/memberships.json"],"onboarding/task":["post","https://api.x.com/1.1/onboarding/task.json"],"onboarding/contacts_authorize":["post","https://api.x.com/1.1/onboarding/contacts_authorize.json"],"onboarding/contacts_import_status":["get","https://api.x.com/1.1/onboarding/contacts_import_status.json"],"onboarding/verification_status":["get","https://api.x.com/1.1/onboarding/verification_status.json"],"onboarding/referrer":["post","https://api.x.com/1.1/onboarding/referrer.json"],"contacts/destroy/all":["post","https://api.x.com/1.1/contacts/destroy/all.json"],"onboarding/begin_verification":["post","https://api.x.com/1.1/onboarding/begin_verification.json"],"onboarding/verify":["post","https://api.x.com/1.1/onboarding/verify.json"],"onboarding/fetch_user_recommendations":["post","https://api.x.com/1.1/onboarding/fetch_user_recommendations.json"],"promoted_content/log":["post","https://api.x.com/1.1/promoted_content/log.json"],"get:account/settings":["get","https://api.x.com/1.1/account/settings.json"],"post:account/settings":["post","https://api.x.com/1.1/account/settings.json"],"sso/delete_connection":["post","https://api.x.com/1.1/sso/delete_connection.json"],"account/remove_profile_banner":["post","https://api.x.com/1.1/account/remove_profile_banner.json"],"account/update_profile_image":["post","https://api.x.com/1.1/account/update_profile_image.json"],"account/update_profile_banner":["post","https://api.x.com/1.1/account/update_profile_banner.json"],"account/deactivate":["post","https://api.x.com/1.1/account/deactivate.json"],"account/verify_password":["post","https://api.x.com/1.1/account/verify_password.json"],"application/rate_limit_status":["get","https://api.x.com/1.1/application/rate_limit_status.json"],"hashflags":["get","https://api.x.com/1.1/hashflags.json"],"geo/delete_location_data":["post","https://api.x.com/1.1/geo/delete_location_data.json"],"get:mutes/advanced_filters":["get","https://api.x.com/1.1/mutes/advanced_filters.json"],"post:mutes/advanced_filters":["post","https://api.x.com/1.1/mutes/advanced_filters.json"],"account/update_profile":["post","https://api.x.com/1.1/account/update_profile.json"],"oauth/list":["get","https://api.x.com/1.1/oauth/list.json"],"oauth/revoke":["post","https://api.x.com/1.1/oauth/revoke.json"],"account/change_password":["post","https://x.com/i/api/1.1/account/change_password.json"],"trends/available":["get","https://api.x.com/1.1/trends/available.json"],"get:account/backup_code":["get","https://api.x.com/1.1/account/backup_code.json"],"post:account/backup_code":["post","https://api.x.com/1.1/account/backup_code.json"],"account/login_verification/temporary_password":["post","https://api.x.com/1.1/account/login_verification/temporary_password.json"],"account/login_verification_enrollment":["delete","https://api.x.com/1.1/account/login_verification_enrollment.json"],"account/login_verification/remove_method":["post","https://api.x.com/1.1/account/login_verification/remove_method.json"],"account/login_verification/rename_security_key_method":["post","https://api.x.com/1.1/account/login_verification/rename_security_key_method.json"],"search/typeahead":["get","https://api.x.com/1.1/search/typeahead.json"],"friendships/create":["post","https://api.x.com/1.1/friendships/create.json"],"friendships/destroy":["post","https://api.x.com/1.1/friendships/destroy.json"],"friendships/cancel":["post","https://api.x.com/1.1/friendships/cancel.json"],"blocks/create":["post","https://api.x.com/1.1/blocks/create.json"],"blocks/destroy":["post","https://api.x.com/1.1/blocks/destroy.json"],"mutes/users/create":["post","https://api.x.com/1.1/mutes/users/create.json"],"mutes/users/destroy":["post","https://api.x.com/1.1/mutes/users/destroy.json"],"users/lookup":["get","https://api.x.com/1.1/users/lookup.json"],"users/email_phone_info":["get","https://api.x.com/1.1/users/email_phone_info.json"],"account/resend_confirmation_email":["post","https://api.x.com/1.1/account/resend_confirmation_email.json"],"device/unregister":["post","https://api.x.com/1.1/device/unregister.json"],"notifications/settings/save":["post","https://api.x.com/1.1/notifications/settings/save.json"],"notifications/settings/login":["post","https://api.x.com/1.1/notifications/settings/login.json"],"notifications/settings/checkin":["post","https://api.x.com/1.1/notifications/settings/checkin.json"],"notifications/settings/logout":["post","https://api.x.com/1.1/notifications/settings/logout.json"],"help/settings":["get","https://api.x.com/1.1/help/settings.json"],"media/metadata/create":["post","https://api.x.com/1.1/media/metadata/create.json"],"media/subtitles/create":["post","https://api.x.com/1.1/media/subtitles/create.json"],"account/personalization/twitter_interests":["get","https://api.x.com/1.1/account/personalization/twitter_interests.json"],"account/personalization/email_your_data":["post","https://api.x.com/1.1/account/personalization/email_your_data.json"],"account/personalization/set_optout_cookies":["get","https://api.x.com/1.1/account/personalization/set_optout_cookies.json"],"live_pipeline/update_subscriptions":["post","https://api.x.com/1.1/live_pipeline/update_subscriptions.json"],"geo/places":["get","https://api.x.com/1.1/geo/places.json"],"users/recommendations":["get","https://api.x.com/1.1/users/recommendations.json"],"saved_searches/list":["get","https://api.x.com/1.1/saved_searches/list.json"],"saved_searches/create":["post","https://api.x.com/1.1/saved_searches/create.json"],"keyregistry/register":["post","https://api.x.com/1.1/keyregistry/register.json"],"account/not_my_account/disassociate":["post","https://api.x.com/1.1/account/not_my_account/disassociate.json"],"account/not_my_account/get_masked_data":["get","https://api.x.com/1.1/account/not_my_account/get_masked_data.json"],"collections/entries":["get","https://api.x.com/1.1/collections/entries.json"],"foundmedia/categories":["get","https://api.x.com/1.1/foundmedia/categories.json"],"foundmedia/search":["get","https://api.x.com/1.1/foundmedia/search.json"],"get:account/user_twitter_data":["get","https://api.x.com/1.1/account/user_twitter_data.json"],"put:account/user_twitter_data":["put","https://api.x.com/1.1/account/user_twitter_data.json"],"contacts/addressbook":["get","https://api.x.com/1.1/contacts/addressbook.json"],"mutes/keywords/list":["get","https://api.x.com/1.1/mutes/keywords/list.json"],"mutes/keywords/destroy":["post","https://api.x.com/1.1/mutes/keywords/destroy.json"],"mutes/keywords/update":["post","https://api.x.com/1.1/mutes/keywords/update.json"],"onboarding/bounce":["post","https://api.x.com/1.1/onboarding/bounce.json"],"report/flow":["post","https://api.x.com/1.1/report/flow.json"],"account/password_strength":["post","https://api.x.com/1.1/account/password_strength.json"],"users/phone_number_available":["get","https://api.x.com/1.1/users/phone_number_available.json"],"users/email_available":["get","https://x.com/i/api/1.1/users/email_available.json"],"moments/create":["post","https://api.x.com/1.1/moments/create.json"]}; \ No newline at end of file diff --git a/src/emusks-local/static/v2.js b/src/emusks-local/static/v2.js new file mode 100644 index 0000000..c9b433f --- /dev/null +++ b/src/emusks-local/static/v2.js @@ -0,0 +1 @@ +export default {"badge_count/badge_count":["get","https://x.com/i/api/2/badge_count/badge_count.json"],"guide/get_explore_settings":["get","https://x.com/i/api/2/guide/get_explore_settings.json"],"guide/set_explore_settings":["post","https://x.com/i/api/2/guide/set_explore_settings.json"],"guide/explore_locations_with_auto_complete":["get","https://x.com/i/api/2/guide/explore_locations_with_auto_complete.json"],"timeline/reactive":["get","https://x.com/i/api/2/timeline/reactive.json"],"moments/list_user_moments":["get","https://x.com/i/api/2/moments/list_user_moments.json"],"guide":["get","https://x.com/i/api/2/guide.json"],"guide/topic":["get","https://x.com/i/api/2/guide/topic.json"],"onboarding/fetch_user_recommendations_urt":["get","https://x.com/i/api/2/onboarding/fetch_user_recommendations_urt.json"],"people_discovery/modules_urt":["get","https://x.com/i/api/2/people_discovery/modules_urt.json"],"search/adaptive":["get","https://x.com/i/api/2/search/adaptive.json"],"timeline/fixture":["get","https://x.com/i/api/2/timeline/fixture.json"]}; \ No newline at end of file diff --git a/src/emusks-local/v1.1.js b/src/emusks-local/v1.1.js new file mode 100644 index 0000000..773fbe6 --- /dev/null +++ b/src/emusks-local/v1.1.js @@ -0,0 +1,64 @@ +import getCycleTLS from "./cycletls.js"; +import v1_1Api from "./static/v1.1.js"; + +export default async function v1_1(queryName, { params, body, headers } = {}) { + let entry = v1_1Api[queryName]; + if (!entry) { + throw new Error(`v1.1 endpoint ${queryName} not found`); + } + + const [method, baseUrl] = entry; + + let finalUrl = baseUrl; + + if (params && Object.keys(params).length) { + const searchParams = new URLSearchParams(params); + const separator = baseUrl.includes("?") ? "&" : "?"; + finalUrl = `${baseUrl}${separator}${searchParams.toString()}`; + } + + const url = new URL(finalUrl); + const pathname = url.pathname; + + const requestHeaders = { + accept: "*/*", + "accept-language": "en-US,en;q=0.9", + authorization: `Bearer ${this.auth.client.bearer}`, + "content-type": "application/json", + "x-csrf-token": this.auth.csrfToken, + "x-twitter-active-user": "yes", + "x-twitter-auth-type": "OAuth2Session", + "x-twitter-client-language": "en", + "x-client-transaction-id": await this.auth.generateTransactionId( + method.toUpperCase(), + pathname, + ), + priority: "u=1, i", + "sec-ch-ua": '"Not(A:Brand";v="8", "Chromium";v="144"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"macOS"', + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-origin", + "sec-gpc": "1", + cookie: + this.auth.client.headers.cookie + (this.elevatedCookies ? `; ${this.elevatedCookies}` : ""), + ...headers, + }; + + const cycleTLS = await getCycleTLS(); + + return await cycleTLS( + finalUrl, + { + headers: requestHeaders, + userAgent: this.auth.client.fingerprints.userAgent, + ja3: this.auth.client.fingerprints.ja3, + ja4r: this.auth.client.fingerprints.ja4r, + body: body || undefined, + proxy: this.proxy || undefined, + referrer: "https://x.com/", + }, + method, + ); +} diff --git a/src/emusks-local/v2.js b/src/emusks-local/v2.js new file mode 100644 index 0000000..1f5890f --- /dev/null +++ b/src/emusks-local/v2.js @@ -0,0 +1,64 @@ +import getCycleTLS from "./cycletls.js"; +import v2Api from "./static/v2.js"; + +export default async function v2(queryName, { params, body, headers } = {}) { + let entry = v2Api[queryName]; + if (!entry) { + throw new Error(`v2 endpoint ${queryName} not found`); + } + + const [method, baseUrl] = entry; + + let finalUrl = baseUrl; + + if (params && Object.keys(params).length) { + const searchParams = new URLSearchParams(params); + const separator = baseUrl.includes("?") ? "&" : "?"; + finalUrl = `${baseUrl}${separator}${searchParams.toString()}`; + } + + const url = new URL(finalUrl); + const pathname = url.pathname; + + const requestHeaders = { + accept: "*/*", + "accept-language": "en-US,en;q=0.9", + authorization: `Bearer ${this.auth.client.bearer}`, + "content-type": "application/json", + "x-csrf-token": this.auth.csrfToken, + "x-twitter-active-user": "yes", + "x-twitter-auth-type": "OAuth2Session", + "x-twitter-client-language": "en", + "x-client-transaction-id": await this.auth.generateTransactionId( + method.toUpperCase(), + pathname, + ), + priority: "u=1, i", + "sec-ch-ua": '"Not(A:Brand";v="8", "Chromium";v="144"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"macOS"', + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-origin", + "sec-gpc": "1", + cookie: + this.auth.client.headers.cookie + (this.elevatedCookies ? `; ${this.elevatedCookies}` : ""), + ...headers, + }; + + const cycleTLS = await getCycleTLS(); + + return await cycleTLS( + finalUrl, + { + headers: requestHeaders, + userAgent: this.auth.client.fingerprints.userAgent, + ja3: this.auth.client.fingerprints.ja3, + ja4r: this.auth.client.fingerprints.ja4r, + body: body || undefined, + proxy: this.proxy || undefined, + referrer: "https://x.com/", + }, + method, + ); +}