diff --git a/debug/requests_sample.py b/debug/requests_sample.py new file mode 100644 index 0000000..234fbfe --- /dev/null +++ b/debug/requests_sample.py @@ -0,0 +1,60 @@ +import json +from pathlib import Path + +import requests + +if Path("cookie.json").exists(): + with open("cookie.json", "r") as f: + cookies = json.load(f) + cookies_dict = {k["name"]: k["value"] for k in cookies} + + +data = requests.get( + "https://twitter.com/i/api/graphql/BQ6xjFU6Mgm-WhEP3OiT9w/UserByScreenName", + cookies=cookies_dict, + headers={ + "accept": "*/*", + "accept-encoding": "identity", + "accept-language": "en-US,en;q=0.9", + "authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA", + "content-type": "application/json", + "referer": "https://twitter.com", + "sec-ch-ua": '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"Windows"', + "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/Chrome/130.0.0.0 Safari/537.36", + "x-csrf-token": cookies_dict["ct0"], + "x-twitter-active-user": "yes", + "x-twitter-auth-type": "OAuth2Session", + "x-twitter-client-language": "en", + }, + params={ + "variables": json.dumps( + { + "screen_name": "5unsetpowerln", + }, + ), + "features": json.dumps( + { + "hidden_profile_subscriptions_enabled": True, + "rweb_tipjar_consumption_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": False, + "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": False, + "responsive_web_graphql_timeline_navigation_enabled": True, + } + ), + "fieldToggles": json.dumps( + { + "withAuxiliaryUserLabels": False, + }, + ), + }, +) +print(data.json()) diff --git a/dist/compatible/openapi-3.0.yaml b/dist/compatible/openapi-3.0.yaml index 1c5df0d..009e890 100644 --- a/dist/compatible/openapi-3.0.yaml +++ b/dist/compatible/openapi-3.0.yaml @@ -151,6 +151,7 @@ components: role: enum: - Member + - Moderator type: string user_results: $ref: '#/components/schemas/UserResults' @@ -400,7 +401,6 @@ components: - id_str - name - description - - question - search_tags - actions - admin_results @@ -628,6 +628,7 @@ components: - ShowMore - ShowMoreThreads - Gap + - ShowMoreThreadsPrompt type: string DeleteBookmarkResponse: properties: @@ -689,6 +690,8 @@ components: properties: actionText: type: string + labelText: + type: string required: - actionText type: object @@ -3120,7 +3123,7 @@ components: name: Accept type: apiKey AcceptEncoding: - description: gzip, deflate, br + description: gzip, deflate, br, zstd in: header name: Accept-Encoding type: apiKey @@ -3148,6 +3151,15 @@ components: in: header name: x-twitter-client-language type: apiKey + ClientTransactionId: + in: header + name: x-client-transaction-id + type: apiKey + ClientUuid: + description: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + in: header + name: x-client-uuid + type: apiKey CookieAuthToken: description: HttpOnly cookie in: cookie @@ -3158,8 +3170,13 @@ components: in: cookie name: ct0 type: apiKey + CookieGt0: + description: document.cookie.split('; ').find(row => row.startsWith('gt0=')); + in: cookie + name: gt0 + type: apiKey CsrfToken: - description: '' + description: document.cookie.split('; ').find(row => row.startsWith('ct0=')); in: header name: x-csrf-token type: apiKey @@ -3168,11 +3185,6 @@ components: in: header name: x-guest-token type: apiKey - Priority: - description: u=1, i - in: header - name: Priority - type: apiKey Referer: description: https://x.com/home in: header @@ -3209,8 +3221,8 @@ components: name: Sec-Fetch-Site type: apiKey UserAgent: - description: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like - Gecko) Chrome/130.0.0.0 Safari/537.36 + description: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, + like Gecko) Chrome/130.0.0.0 Safari/537.36 in: header name: user-agent type: apiKey @@ -3354,27 +3366,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -3470,27 +3479,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -3586,27 +3592,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -3666,27 +3669,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -3963,27 +3963,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -6645,26 +6642,28 @@ paths: tags: - other security: -- CsrfToken: [] -- CookieCt0: [] -- GuestToken: [] -- CookieAuthToken: [] -- AuthType: [] -- UserAgent: [] -- BearerAuth: [] -- ActiveUser: [] -- ClientLanguage: [] - Accept: [] - AcceptEncoding: [] - AcceptLanguage: [] +- Referer: [] - SecChUa: [] - SecChUaMobile: [] - SecChUaPlatform: [] - SecFetchDest: [] - SecFetchMode: [] - SecFetchSite: [] -- Referer: [] -- Priority: [] +- UserAgent: [] +- BearerAuth: [] +- ClientTransactionId: [] +- ClientUuid: [] +- CsrfToken: [] +- GuestToken: [] +- ActiveUser: [] +- AuthType: [] +- ClientLanguage: [] +- CookieCt0: [] +- CookieAuthToken: [] +- CookieGt0: [] servers: - url: https://x.com/i/api - url: https://twitter.com/i/api diff --git a/dist/compatible_discriminator/openapi-3.0.yaml b/dist/compatible_discriminator/openapi-3.0.yaml index 6609c42..cb0f8a1 100644 --- a/dist/compatible_discriminator/openapi-3.0.yaml +++ b/dist/compatible_discriminator/openapi-3.0.yaml @@ -151,6 +151,7 @@ components: role: enum: - Member + - Moderator type: string user_results: $ref: '#/components/schemas/UserResults' @@ -400,7 +401,6 @@ components: - id_str - name - description - - question - search_tags - actions - admin_results @@ -628,6 +628,7 @@ components: - ShowMore - ShowMoreThreads - Gap + - ShowMoreThreadsPrompt type: string DeleteBookmarkResponse: properties: @@ -689,6 +690,8 @@ components: properties: actionText: type: string + labelText: + type: string required: - actionText type: object @@ -3120,7 +3123,7 @@ components: name: Accept type: apiKey AcceptEncoding: - description: gzip, deflate, br + description: gzip, deflate, br, zstd in: header name: Accept-Encoding type: apiKey @@ -3148,6 +3151,15 @@ components: in: header name: x-twitter-client-language type: apiKey + ClientTransactionId: + in: header + name: x-client-transaction-id + type: apiKey + ClientUuid: + description: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + in: header + name: x-client-uuid + type: apiKey CookieAuthToken: description: HttpOnly cookie in: cookie @@ -3158,8 +3170,13 @@ components: in: cookie name: ct0 type: apiKey + CookieGt0: + description: document.cookie.split('; ').find(row => row.startsWith('gt0=')); + in: cookie + name: gt0 + type: apiKey CsrfToken: - description: '' + description: document.cookie.split('; ').find(row => row.startsWith('ct0=')); in: header name: x-csrf-token type: apiKey @@ -3168,11 +3185,6 @@ components: in: header name: x-guest-token type: apiKey - Priority: - description: u=1, i - in: header - name: Priority - type: apiKey Referer: description: https://x.com/home in: header @@ -3209,8 +3221,8 @@ components: name: Sec-Fetch-Site type: apiKey UserAgent: - description: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like - Gecko) Chrome/130.0.0.0 Safari/537.36 + description: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, + like Gecko) Chrome/130.0.0.0 Safari/537.36 in: header name: user-agent type: apiKey @@ -3354,27 +3366,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -3470,27 +3479,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -3586,27 +3592,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -3666,27 +3669,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -3963,27 +3963,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -6587,26 +6584,28 @@ paths: tags: - other security: -- CsrfToken: [] -- CookieCt0: [] -- GuestToken: [] -- CookieAuthToken: [] -- AuthType: [] -- UserAgent: [] -- BearerAuth: [] -- ActiveUser: [] -- ClientLanguage: [] - Accept: [] - AcceptEncoding: [] - AcceptLanguage: [] +- Referer: [] - SecChUa: [] - SecChUaMobile: [] - SecChUaPlatform: [] - SecFetchDest: [] - SecFetchMode: [] - SecFetchSite: [] -- Referer: [] -- Priority: [] +- UserAgent: [] +- BearerAuth: [] +- ClientTransactionId: [] +- ClientUuid: [] +- CsrfToken: [] +- GuestToken: [] +- ActiveUser: [] +- AuthType: [] +- ClientLanguage: [] +- CookieCt0: [] +- CookieAuthToken: [] +- CookieGt0: [] servers: - url: https://x.com/i/api - url: https://twitter.com/i/api diff --git a/dist/docs/openapi-3.0.yaml b/dist/docs/openapi-3.0.yaml index 442cae6..a791a54 100644 --- a/dist/docs/openapi-3.0.yaml +++ b/dist/docs/openapi-3.0.yaml @@ -151,6 +151,7 @@ components: role: enum: - Member + - Moderator type: string user_results: $ref: '#/components/schemas/UserResults' @@ -400,7 +401,6 @@ components: - id_str - name - description - - question - search_tags - actions - admin_results @@ -628,6 +628,7 @@ components: - ShowMore - ShowMoreThreads - Gap + - ShowMoreThreadsPrompt type: string DeleteBookmarkResponse: properties: @@ -689,6 +690,8 @@ components: properties: actionText: type: string + labelText: + type: string required: - actionText type: object @@ -3120,7 +3123,7 @@ components: name: Accept type: apiKey AcceptEncoding: - description: gzip, deflate, br + description: gzip, deflate, br, zstd in: header name: Accept-Encoding type: apiKey @@ -3148,6 +3151,15 @@ components: in: header name: x-twitter-client-language type: apiKey + ClientTransactionId: + in: header + name: x-client-transaction-id + type: apiKey + ClientUuid: + description: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + in: header + name: x-client-uuid + type: apiKey CookieAuthToken: description: HttpOnly cookie in: cookie @@ -3158,8 +3170,13 @@ components: in: cookie name: ct0 type: apiKey + CookieGt0: + description: document.cookie.split('; ').find(row => row.startsWith('gt0=')); + in: cookie + name: gt0 + type: apiKey CsrfToken: - description: '' + description: document.cookie.split('; ').find(row => row.startsWith('ct0=')); in: header name: x-csrf-token type: apiKey @@ -3168,11 +3185,6 @@ components: in: header name: x-guest-token type: apiKey - Priority: - description: u=1, i - in: header - name: Priority - type: apiKey Referer: description: https://x.com/home in: header @@ -3209,8 +3221,8 @@ components: name: Sec-Fetch-Site type: apiKey UserAgent: - description: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like - Gecko) Chrome/130.0.0.0 Safari/537.36 + description: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, + like Gecko) Chrome/130.0.0.0 Safari/537.36 in: header name: user-agent type: apiKey @@ -3354,27 +3366,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -3470,27 +3479,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -3586,27 +3592,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -3666,27 +3669,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -3963,27 +3963,24 @@ paths: '200': description: Successful operation headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean x-connection-hash: schema: type: string - x-content-type-options: + x-rate-limit-limit: schema: - type: string + type: integer + x-rate-limit-remaining: + schema: + type: integer + x-rate-limit-reset: + schema: + type: integer x-response-time: schema: type: integer - x-transaction: + x-tfe-preserve-body: schema: - type: string + type: boolean x-transaction-id: schema: type: string @@ -8793,26 +8790,28 @@ paths: tags: - other security: -- CsrfToken: [] -- CookieCt0: [] -- GuestToken: [] -- CookieAuthToken: [] -- AuthType: [] -- UserAgent: [] -- BearerAuth: [] -- ActiveUser: [] -- ClientLanguage: [] - Accept: [] - AcceptEncoding: [] - AcceptLanguage: [] +- Referer: [] - SecChUa: [] - SecChUaMobile: [] - SecChUaPlatform: [] - SecFetchDest: [] - SecFetchMode: [] - SecFetchSite: [] -- Referer: [] -- Priority: [] +- UserAgent: [] +- BearerAuth: [] +- ClientTransactionId: [] +- ClientUuid: [] +- CsrfToken: [] +- GuestToken: [] +- ActiveUser: [] +- AuthType: [] +- ClientLanguage: [] +- CookieCt0: [] +- CookieAuthToken: [] +- CookieGt0: [] servers: - url: https://x.com/i/api - url: https://twitter.com/i/api diff --git a/src/config/component/response_header_legacy.yaml b/src/config/component/response_header_legacy.yaml deleted file mode 100644 index b2fc658..0000000 --- a/src/config/component/response_header_legacy.yaml +++ /dev/null @@ -1,35 +0,0 @@ -openapi: 3.0.3 -info: - title: Twitter OpenAPI - version: 0.0.1 -paths: {} - -components: - headers: - status: - schema: - type: string - x-access-level: - schema: - type: string - x-client-event-enabled: - schema: - type: boolean - x-connection-hash: - schema: - type: string - x-content-type-options: - schema: - type: string - x-response-time: - schema: - type: integer - x-transaction: - schema: - type: string - x-transaction-id: - schema: - type: string - x-twitter-response-tags: - schema: - type: string diff --git a/src/config/component/security_schemes.yaml b/src/config/component/security_schemes.yaml deleted file mode 100644 index c56938d..0000000 --- a/src/config/component/security_schemes.yaml +++ /dev/null @@ -1,241 +0,0 @@ -openapi: 3.0.3 -info: - title: Twitter OpenAPI - version: 0.0.1 -paths: - /parameters: - get: - parameters: - - name: user-agent - in: header - required: true - schema: - type: string - default: "Not Implemented" - description: "UserAgent, some APIs may be rejected if changed." - - name: authorization - in: header - required: true - schema: - type: string - default: "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA" - description: "It is a constant value and does not need to be changed." - - name: x-twitter-active-user - in: header - required: true - schema: - type: string - default: "yes" - description: "Unknown what this value means." - - name: x-twitter-client-language - in: header - required: true - schema: - type: string - default: "en" - description: "language code." - - # Browser Schemes - - name: Accept - in: header - required: true - schema: - type: string - default: "*/*" - description: "*/*" - - name: Accept-Encoding - in: header - required: true - schema: - type: string - default: "gzip, deflate, br" - description: "gzip, deflate, br" - - name: Accept-Language - in: header - required: true - schema: - type: string - default: "en-US,en;q=0.9" - description: "en-US,en;q=0.9" - # - name: Cache-Control - # in: header - # required: true - # schema: - # type: string - # default: "no-cache" - # description: "no-cache" - # - name: Pragma - # in: header - # required: true - # schema: - # type: string - # default: "no-cache" - # description: "no-cache" - - name: Sec-Ch-Ua - in: header - required: true - schema: - type: string - default: '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"' - description: '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"' - - name: Sec-Ch-Ua-Mobile - in: header - required: true - schema: - type: string - default: "?0" - description: "?0" - - name: Sec-Ch-Ua-Platform - in: header - required: true - schema: - type: string - default: '"Windows"' - description: '"Windows"' - - name: Sec-Fetch-Dest - in: header - required: true - schema: - type: string - default: "empty" - description: "empty" - - name: Sec-Fetch-Mode - in: header - required: true - schema: - type: string - default: "cors" - description: "cors" - - name: Sec-Fetch-Site - in: header - required: true - schema: - type: string - default: "same-origin" - description: "same-origin" - - name: Referer - in: header - required: true - schema: - type: string - default: "https://x.com/home" - description: "https://x.com/home" - - name: Priority - in: header - required: true - schema: - type: string - default: "u=1, i" - description: "u=1, i" - - responses: - "200": - description: "" - -components: - securitySchemes: - UserAgent: - description: "Not Implemented" - in: header - name: user-agent - type: apiKey - BearerAuth: - description: AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA - scheme: bearer - type: http - ActiveUser: - description: "yes" - in: header - name: x-twitter-active-user - type: apiKey - ClientLanguage: - description: en - in: header - name: x-twitter-client-language - type: apiKey - - # Browser Schemes - Accept: - description: "*/*" - in: header - name: Accept - type: apiKey - AcceptEncoding: - description: "gzip, deflate, br" - in: header - name: Accept-Encoding - type: apiKey - AcceptLanguage: - description: "en-US,en;q=0.9" - in: header - name: Accept-Language - type: apiKey - # CacheControl: - # description: "no-cache" - # in: header - # name: Cache-Control - # type: apiKey - # Pragma: - # description: "no-cache" - # in: header - # name: Pragma - # type: apiKey - SecChUa: - description: '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"' - in: header - name: Sec-Ch-Ua - type: apiKey - SecChUaMobile: - description: "?0" - in: header - name: Sec-Ch-Ua-Mobile - type: apiKey - SecChUaPlatform: - description: '"Windows"' - in: header - name: Sec-Ch-Ua-Platform - type: apiKey - SecFetchDest: - description: "empty" - in: header - name: Sec-Fetch-Dest - type: apiKey - SecFetchMode: - description: "cors" - in: header - name: Sec-Fetch-Mode - type: apiKey - SecFetchSite: - description: "same-origin" - in: header - name: Sec-Fetch-Site - type: apiKey - Referer: - description: "https://x.com/home" - in: header - name: Referer - type: apiKey - Priority: - description: "u=1, i" - in: header - name: Priority - type: apiKey - -security: - - UserAgent: [] - - BearerAuth: [] - - ActiveUser: [] - - ClientLanguage: [] - - Accept: [] - - AcceptEncoding: [] - - AcceptLanguage: [] - # - CacheControl: [] - # - Pragma: [] - - SecChUa: [] - - SecChUaMobile: [] - - SecChUaPlatform: [] - - SecFetchDest: [] - - SecFetchMode: [] - - SecFetchSite: [] - - Referer: [] - - Priority: [] diff --git a/src/config/placeholder.json b/src/config/placeholder.json index bd3e3b0..31ac8a6 100644 --- a/src/config/placeholder.json +++ b/src/config/placeholder.json @@ -910,7 +910,7 @@ "queryId": "xF6sXnKJfS2AOylzxRjf6A" }, "PinnedTimelines": { - "queryId": "xUjP0kS7EE05CLp3KUD-Eg", + "queryId": "C-IBapfouIWLa8v6GcGATQ", "features": { "rweb_tipjar_consumption_enabled": true, "responsive_web_graphql_exclude_directive_enabled": true, @@ -923,7 +923,7 @@ "queryId": "PFIxTk8owMoZgiMccP0r4g" }, "ExploreSidebar": { - "queryId": "rqiZoeu9EBUhOqZdKY139g", + "queryId": "SQF2aB791cUu02BkZk1HcA", "features": { "rweb_tipjar_consumption_enabled": true, "responsive_web_graphql_exclude_directive_enabled": true, @@ -1097,5 +1097,78 @@ "features": { "responsive_web_tweet_analytics_m3_enabled": false } + }, + "DMPinnedInboxQuery": { + "queryId": "_gBQBgClVuMQb8efxWkbbQ" + }, + "GenericTimelineById": { + "queryId": "eob7MfQ-OPla82tbCSxZUA", + "features": { + "rweb_tipjar_consumption_enabled": true, + "responsive_web_graphql_exclude_directive_enabled": true, + "verified_phone_label_enabled": false, + "creator_subscriptions_tweet_preview_api_enabled": true, + "responsive_web_graphql_timeline_navigation_enabled": true, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": false, + "communities_web_enable_tweet_community_results_fetch": true, + "c9s_tweet_anatomy_moderator_badge_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": false, + "creator_subscriptions_quote_tweet_preview_enabled": false, + "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_timestamps_enabled": true, + "longform_notetweets_rich_text_read_enabled": true, + "longform_notetweets_inline_media_enabled": true, + "responsive_web_enhance_cards_enabled": false + } + }, + "BirdwatchFetchAliasSelfSelectStatus": { + "queryId": "LUEdtkcpBlGktUtms4BvwA" + }, + "BirdwatchFetchContributorNotesSlice": { + "queryId": "VyycAPcXi0XvKoLqdhNpOg", + "features": { + "responsive_web_birdwatch_media_notes_enabled": true, + "responsive_web_birdwatch_fast_notes_badge_enabled": true, + "creator_subscriptions_tweet_preview_api_enabled": true, + "communities_web_enable_tweet_community_results_fetch": true, + "c9s_tweet_anatomy_moderator_badge_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": false, + "creator_subscriptions_quote_tweet_preview_enabled": false, + "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_timestamps_enabled": true, + "longform_notetweets_rich_text_read_enabled": true, + "longform_notetweets_inline_media_enabled": true, + "rweb_tipjar_consumption_enabled": true, + "responsive_web_graphql_exclude_directive_enabled": true, + "verified_phone_label_enabled": false, + "responsive_web_graphql_timeline_navigation_enabled": true, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": false, + "responsive_web_enhance_cards_enabled": false + } + }, + "BirdwatchFetchBirdwatchProfile": { + "queryId": "iL_0nGf1nelAd9Kz-pZJlA", + "features": { + "responsive_web_birdwatch_top_contributor_enabled": true + } + }, + "BirdwatchFetchPublicData": { + "queryId": "9bDdJ6AL26RLkcUShEcF-A" } } diff --git a/src/openapi/openapi-3.0.yaml b/src/openapi/openapi-3.0.yaml index 10c73a8..9c77116 100644 --- a/src/openapi/openapi-3.0.yaml +++ b/src/openapi/openapi-3.0.yaml @@ -19,42 +19,144 @@ components: schemas: {} securitySchemes: + Accept: + description: "*/*" + in: header + name: Accept + type: apiKey + AcceptEncoding: + description: "gzip, deflate, br, zstd" + in: header + name: Accept-Encoding + type: apiKey + AcceptLanguage: + description: "en-US,en;q=0.9" + in: header + name: Accept-Language + type: apiKey + Referer: + description: "https://x.com/home" + in: header + name: Referer + type: apiKey + SecChUa: + description: '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"' + in: header + name: Sec-Ch-Ua + type: apiKey + SecChUaMobile: + description: "?0" + in: header + name: Sec-Ch-Ua-Mobile + type: apiKey + SecChUaPlatform: + description: '"Windows"' + in: header + name: Sec-Ch-Ua-Platform + type: apiKey + SecFetchDest: + description: "empty" + in: header + name: Sec-Fetch-Dest + type: apiKey + SecFetchMode: + description: "cors" + in: header + name: Sec-Fetch-Mode + type: apiKey + SecFetchSite: + description: "same-origin" + in: header + name: Sec-Fetch-Site + type: apiKey + UserAgent: + description: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" + in: header + name: user-agent + type: apiKey + BearerAuth: + description: AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA + scheme: bearer + type: http + ClientTransactionId: + type: apiKey + in: header + name: x-client-transaction-id + ClientUuid: + type: apiKey + in: header + name: x-client-uuid + description: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" CsrfToken: type: apiKey in: header name: x-csrf-token - description: "" - - CookieCt0: - type: apiKey - in: cookie - name: ct0 description: "document.cookie.split('; ').find(row => row.startsWith('ct0='));" - GuestToken: type: apiKey in: header name: x-guest-token description: "document.cookie.split('; ').find(row => row.startsWith('gt='));" - - CookieAuthToken: + ActiveUser: + description: "yes" + in: header + name: x-twitter-active-user type: apiKey - in: cookie - name: auth_token - description: "HttpOnly cookie" - AuthType: type: apiKey in: header name: x-twitter-auth-type description: "OAuth2Session if you are logged in" + ClientLanguage: + description: en + in: header + name: x-twitter-client-language + type: apiKey + CookieAuthToken: + type: apiKey + in: cookie + name: auth_token + description: "HttpOnly cookie" + CookieCt0: + type: apiKey + in: cookie + name: ct0 + description: "document.cookie.split('; ').find(row => row.startsWith('ct0='));" + CookieGt0: + type: apiKey + in: cookie + name: gt0 + description: "document.cookie.split('; ').find(row => row.startsWith('gt0='));" security: + # Browser Schemes + - Accept: [] + - AcceptEncoding: [] + - AcceptLanguage: [] + - Referer: [] + - SecChUa: [] + - SecChUaMobile: [] + - SecChUaPlatform: [] + - SecFetchDest: [] + - SecFetchMode: [] + - SecFetchSite: [] + # Other Auth Schemes + - UserAgent: [] + - BearerAuth: [] + # X Schemes + - ClientTransactionId: [] + - ClientUuid: [] - CsrfToken: [] - - CookieCt0: [] - GuestToken: [] - - CookieAuthToken: [] + # Twitter Schemes + - ActiveUser: [] - AuthType: [] + - ClientLanguage: [] + # Cookie Schemes + - CookieCt0: [] + - CookieAuthToken: [] + - CookieGt0: [] + tags: - name: user description: Responses containing User objects. diff --git a/src/openapi/schemas/content.yaml b/src/openapi/schemas/content.yaml index fb968d0..e172add 100644 --- a/src/openapi/schemas/content.yaml +++ b/src/openapi/schemas/content.yaml @@ -25,7 +25,7 @@ components: CursorType: type: string - enum: [Top, Bottom, ShowMore, ShowMoreThreads, Gap] # Gap??? + enum: [Top, Bottom, ShowMore, ShowMoreThreads, Gap, ShowMoreThreadsPrompt] # Gap??? TimelineTimelineItem: required: @@ -107,6 +107,8 @@ components: properties: actionText: type: string + labelText: + type: string # ================= Module ================= diff --git a/src/openapi/schemas/tweet.yaml b/src/openapi/schemas/tweet.yaml index d5211b0..d31b161 100644 --- a/src/openapi/schemas/tweet.yaml +++ b/src/openapi/schemas/tweet.yaml @@ -405,7 +405,7 @@ components: $ref: "#/components/schemas/Community" role: type: string - enum: [Member] + enum: [Member, Moderator] user_results: $ref: "user.yaml#/components/schemas/UserResults" @@ -422,7 +422,6 @@ components: - "id_str" - "name" - "description" - - "question" - "search_tags" - "actions" - "admin_results" diff --git a/test/python/test_serialize.py b/test/python/test_serialize.py index 5f31b82..69f5b93 100644 --- a/test/python/test_serialize.py +++ b/test/python/test_serialize.py @@ -10,6 +10,7 @@ import traceback import warnings from enum import Enum from pathlib import Path +from typing import Any import openapi_client as pt import urllib3 @@ -158,6 +159,27 @@ def task_callback(file, thread=True): raise +def kebab_to_upper_camel(text: dict[str, Any]) -> dict[str, Any]: + res = {} + for key, value in text.items(): + new_key = "".join([x.capitalize() for x in remove_prefix(key).split("-")]) + res[new_key] = value + return res + + +def get_header(data: dict, name: str): + ignore = ["host", "connection"] + return {key: value for key, value in data[name].items() if key not in ignore} + + +def remove_prefix(text: str) -> str: + if text.startswith("x-twitter-"): + return text[10:] + if text.startswith("x-"): + return text[2:] + return text + + def error_dump(e): if ERROR_UNCATCHED: raise @@ -219,27 +241,31 @@ if __name__ == "__main__": _ = pt.Errors.from_dict(data) except Exception as e: error_dump(e) - - api_conf = pt.Configuration( - api_key={ - "ClientLanguage": "en", - "ActiveUser": "yes", - "AuthType": "OAuth2Session", - "CsrfToken": cookies["ct0"], - }, - ) - + access_token = "AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA" + twitter_url = "https://x.com/home" latest_user_agent_res = urllib3.PoolManager().request( "GET", - "https://raw.githubusercontent.com/fa0311/latest-user-agent/main/output.json", + "https://raw.githubusercontent.com/fa0311/latest-user-agent/refs/heads/main/header.json", ) - latest_user_agent = json.loads(latest_user_agent_res.data.decode("utf-8")) - - api_conf.access_token = "AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA" - + api_conf = pt.Configuration( + api_key=kebab_to_upper_camel( + { + **get_header(latest_user_agent, "chrome-fetch"), + "sec-ch-ua-platform": '"Windows"', + "accept-encoding": "identity", + "referer": twitter_url, + "authorization": f"Bearer {access_token}", + "x-twitter-auth-type": "OAuth2Session", + "x-twitter-client-language": "en", + "x-twitter-active-user": "yes", + "x-csrf-token": cookies["ct0"], + }, + ), + ) + api_conf.access_token = access_token api_client = pt.ApiClient(configuration=api_conf, cookie=cookies_str) - api_client.user_agent = latest_user_agent["chrome"] + api_client.user_agent = get_header(latest_user_agent, "chrome-fetch")["user-agent"] error_count = 0 for x in [pt.DefaultApi, pt.TweetApi, pt.UserApi, pt.UsersApi, pt.UserListApi]: @@ -348,6 +374,7 @@ if __name__ == "__main__": "1759056048764469303", "1349129669258448897", "1810188416812019999", + "1851981523207299417", ] for id in ids: try: diff --git a/tools/build_config.py b/tools/build_config.py index 1142062..12d9a84 100644 --- a/tools/build_config.py +++ b/tools/build_config.py @@ -3,10 +3,8 @@ from hooks import ( AddParametersOnContent, AddParametersOnParameters, AddPathQueryIdOnParameters, - AddSecuritySchemesOnSecuritySchemes, RemoveErrorHandle, SetResponsesHeader, - SetUserAgentOnSecuritySchemes, ) @@ -41,15 +39,12 @@ class Config: additionalHooks.append(RemoveErrorHandle()) return { - "openapi": [ - AddSecuritySchemesOnSecuritySchemes(), - SetUserAgentOnSecuritySchemes(), - ], + "openapi": [], "schemas": [], "other": [], "request": { key: [ - SetResponsesHeader(suffix=None), + SetResponsesHeader(), AddPathQueryIdOnParameters(split=-1), getParamHook, *additionalHooks, @@ -58,7 +53,7 @@ class Config: } | { key: [ - SetResponsesHeader(suffix=None), + SetResponsesHeader(), AddPathQueryIdOnParameters(split=-1), AddParametersOnBody( split=-1, @@ -71,14 +66,14 @@ class Config: } | { key: [ - SetResponsesHeader(suffix="legacy"), + SetResponsesHeader(), AddParametersOnParameters(split=2, schemaType=None), ] for key in ["v1.1-get", "v2.0-get"] } | { key: [ - SetResponsesHeader(suffix="legacy"), + SetResponsesHeader(), AddParametersOnBody( split=2, schemaType=None, diff --git a/tools/hooks.py b/tools/hooks.py index 40d0e47..ae05cc7 100644 --- a/tools/hooks.py +++ b/tools/hooks.py @@ -1,6 +1,5 @@ import json -import urllib3 import yaml @@ -61,12 +60,12 @@ class HookBase: with open("src/config/placeholder.json", mode="r", encoding="utf-8") as f: return yaml.safe_load(f) - def load_user_agent(self) -> str: - user_agent = urllib3.PoolManager().request( - "GET", - "https://raw.githubusercontent.com/fa0311/latest-user-agent/main/output.json", - ) - return json.loads(user_agent.data)["chrome-fetch"] + # def load_user_agent(self) -> str: + # user_agent = urllib3.PoolManager().request( + # "GET", + # "https://raw.githubusercontent.com/fa0311/latest-user-agent/main/output.json", + # ) + # return json.loads(user_agent.data)["chrome-fetch"] # HookBase extends @@ -104,22 +103,22 @@ class RequestHookBase(HookBase): # OpenapiHookBase extends -class AddSecuritySchemesOnSecuritySchemes(OpenapiHookBase): - def hook(self, value: dict): - value = super().hook(value) - component = self.load_component("security_schemes") - param = component["components"]["securitySchemes"] - value["components"]["securitySchemes"].update(param) - value["security"].extend(component["security"]) - return value +# class AddSecuritySchemesOnSecuritySchemes(OpenapiHookBase): +# def hook(self, value: dict): +# value = super().hook(value) +# component = self.load_component("security_schemes") +# param = component["components"]["securitySchemes"] +# value["components"]["securitySchemes"].update(param) +# value["security"].extend(component["security"]) +# return value -class SetUserAgentOnSecuritySchemes(OpenapiHookBase): - def hook(self, value: dict): - value = super().hook(value) - param = value["components"]["securitySchemes"] - param["UserAgent"]["description"] = self.load_user_agent() - return value +# class SetUserAgentOnSecuritySchemes(OpenapiHookBase): +# def hook(self, value: dict): +# value = super().hook(value) +# param = value["components"]["securitySchemes"] +# param["UserAgent"]["description"] = self.load_user_agent() +# return value # SchemasHookBase extends @@ -158,22 +157,22 @@ class RequiredCheck(SchemasHookBase): # RequestHookBase extends -class AddSecuritySchemesOnHeader(RequestHookBase): - def hook(self, path: str, value: dict): - path, value = super().hook(path, value) - component = self.load_component("security_schemes") - param = component["paths"]["/parameters"]["get"]["parameters"] - value["parameters"].extend(param) - return path, value +# class AddSecuritySchemesOnHeader(RequestHookBase): +# def hook(self, path: str, value: dict): +# path, value = super().hook(path, value) +# component = self.load_component("security_schemes") +# param = component["paths"]["/parameters"]["get"]["parameters"] +# value["parameters"].extend(param) +# return path, value -class SetUserAgentOnHeader(RequestHookBase): - def hook(self, path: str, value: dict): - path, value = super().hook(path, value) - component = self.load_component("security_schemes") - param = component["paths"]["/parameters"]["get"]["parameters"] - value["parameters"].extend(param) - return path, value +# class SetUserAgentOnHeader(RequestHookBase): +# def hook(self, path: str, value: dict): +# path, value = super().hook(path, value) +# component = self.load_component("security_schemes") +# param = component["paths"]["/parameters"]["get"]["parameters"] +# value["parameters"].extend(param) +# return path, value class ReplaceQueryIdPlaceholder(RequestHookBase): @@ -186,13 +185,12 @@ class ReplaceQueryIdPlaceholder(RequestHookBase): class SetResponsesHeader(RequestHookBase): suffix: str - def __init__(self, suffix: str | None = None): + def __init__(self): super().__init__() - self.suffix = "" if suffix is None else "_" + suffix def hook(self, path: str, value: dict): path, value = super().hook(path, value) - component = self.load_component("response_header" + self.suffix) + component = self.load_component("response_header") value["responses"]["200"]["headers"] = component["components"]["headers"] return path, value