{"id":23739743,"url":"https://github.com/p1atdev/whisper","last_synced_at":"2025-09-04T15:31:40.945Z","repository":{"id":56732612,"uuid":"524291978","full_name":"p1atdev/whisper","owner":"p1atdev","description":"A client that wraps the API behind Twitter.","archived":false,"fork":false,"pushed_at":"2023-05-10T21:09:32.000Z","size":41,"stargazers_count":27,"open_issues_count":2,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-12-17T02:38:46.826Z","etag":null,"topics":["api-client","deno","twitter","typescript"],"latest_commit_sha":null,"homepage":"https://deno.land/x/whisper","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/p1atdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-08-13T03:42:43.000Z","updated_at":"2023-10-21T22:19:08.000Z","dependencies_parsed_at":"2022-08-16T00:40:51.927Z","dependency_job_id":null,"html_url":"https://github.com/p1atdev/whisper","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":"p1atdev/deno_template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p1atdev%2Fwhisper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p1atdev%2Fwhisper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p1atdev%2Fwhisper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p1atdev%2Fwhisper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/p1atdev","download_url":"https://codeload.github.com/p1atdev/whisper/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231970931,"owners_count":18453925,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-client","deno","twitter","typescript"],"created_at":"2024-12-31T09:39:04.100Z","updated_at":"2024-12-31T09:39:13.063Z","avatar_url":"https://github.com/p1atdev.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Whisper\n\nA client that wraps the API behind Twitter.\n\n[![deno module](https://shield.deno.dev/x/whisper)](https://deno.land/x/whisper)\n![deno compatibility](https://shield.deno.dev/deno/^1.24)\n[![vr scripts](https://badges.velociraptor.run/flat.svg)](https://velociraptor.run)\n[![codecov](https://codecov.io/gh/p1atdev/whisper/branch/main/graph/badge.svg?token=S37OD55SBF)](https://codecov.io/gh/p1atdev/whisper)\n![Testing](https://github.com/p1atdev/whisper/actions/workflows/test.yaml/badge.svg)\n![Lint](https://github.com/p1atdev/whisper/actions/workflows/lint.yaml/badge.svg)\n\n## Features\n\n- You can use endpoints not officially provided\n  - GraphQL endpoint (`UserByScreenName`, `UserTweets`, etc...)\n  - \"i\" endpoint (`/users/email_available.json`, etc...)\n- You can use the hidden api without any tokens\n  - Whisper uses the official web client's token\n\n## Example\n\nFull example code can be seen on `/test/example.test.ts`\n\n### User By Screen Name (GraphQL endpoint)\n\n```ts\nconst client = new TwitterAPI(Bearer.Web);\n\nconst query = new RequestQuery({\n  variables: {\n    screen_name: \"deno_land\",\n    withSafetyModeUserFields: true,\n    withSuperFollowsUserFields: true,\n  },\n});\n\nconst res = await client.request({\n  method: \"GET\",\n  urlType: \"gql\",\n  path: \"UserByScreenName\",\n  query: query,\n});\n\nconst json = await res.json();\n\nassertEquals(json.data.user.result.rest_id, \"1108769816230293504\");\n```\n\n### Search Adaptive (v2 endpoint)\n\n```ts\nconst client = new TwitterAPI(Bearer.Web);\n\nconst query = new RequestQuery({\n  q: \"from:@deno_land\",\n  count: 3,\n});\n\nconst res = await client.request({\n  method: \"GET\",\n  urlType: \"i/api/2\",\n  path: \"/search/adaptive.json\",\n  query: query,\n});\n\nconst json = await res.json();\n\nassertExists(json.globalObjects.users[\"1108769816230293504\"]);\n```\n\n### User Tweets (GraphQL endpoint)\n\n```ts\nconst client = new TwitterAPI(Bearer.Web);\n\nconst query = new RequestQuery({\n  variables: {\n    userId: \"1108769816230293504\",\n    count: 4,\n    includePromotedContent: false,\n    withVoice: false,\n    withDownvotePerspective: true,\n    withReactionsMetadata: false,\n    withReactionsPerspective: false,\n    withSuperFollowsTweetFields: false,\n    withSuperFollowsUserFields: false,\n  },\n  features: {\n    tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled:\n      false,\n    interactive_text_enabled: true,\n    standardized_nudges_misinfo: true,\n    responsive_web_edit_tweet_api_enabled: true,\n    responsive_web_enhance_cards_enabled: false,\n    vibe_api_enabled: true,\n    dont_mention_me_view_api_enabled: true,\n    responsive_web_uc_gql_enabled: true,\n  },\n});\n\nconst res = await client.request({\n  method: \"GET\",\n  urlType: \"gql\",\n  path: \"UserTweets\",\n  query: query,\n});\n\nconst json = await res.json();\n\nconst timeline = json.data.user.result.timeline;\n\nconsole.dir(timeline, { depth: 10 });\n\n// Output:\n//\n// {\n//   timeline: {\n//     instructions: [\n//       { type: \"TimelineClearCache\" },\n//       {\n//         type: \"TimelineAddEntries\",\n//         entries: [\n//           {\n//             entryId: \"tweet-1558145641565474816\",\n//             sortIndex: \"1558145641565474816\",\n//             content: {\n//               entryType: \"TimelineTimelineItem\",\n//               __typename: \"TimelineTimelineItem\",\n//               itemContent: {\n//                 itemType: \"TimelineTweet\",\n//                 __typename: \"TimelineTweet\",\n//                 tweet_results: {\n//                   result: {\n//                     __typename: \"Tweet\",\n//                     rest_id: \"1558145641565474816\",\n//                     core: [Object],\n//                     card: [Object],\n//                     unmention_info: [Object],\n//                     unified_card: [Object],\n//                     edit_control: [Object],\n//                     legacy: [Object]\n//                   }\n//                 },\n//                 tweetDisplayType: \"Tweet\",\n//                 ruxContext: \"HHwWgMCqnZTN0p8rAAAA\"\n//  ...\n```\n\n### Email Available (i endpoint)\n\n```ts\nconst client = new TwitterAPI(Bearer.Web);\n\nconst query = new RequestQuery({\n  email: \"twitter@example.com\",\n});\n\nconst res = await client.request({\n  method: \"GET\",\n  urlType: \"i/api/i\",\n  path: \"/users/email_available.json\",\n  query: query,\n});\n\nconst json = await res.json();\n\nassertEquals(json.valid, false);\nassertEquals(json.taken, false);\n```\n\n## Note\n\nRequest parameters and response types are not supported in this module due to\nthe rapidly changing unofficial API specifications. Beware that Twitter will\nchange its API specification without notice.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp1atdev%2Fwhisper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fp1atdev%2Fwhisper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp1atdev%2Fwhisper/lists"}