Whisper
A client that wraps the API behind Twitter.
Features
- You can use endpoints not officially provided
- GraphQL endpoint (
UserByScreenName
,UserTweets
, etc...) - "i" endpoint (
/users/email_available.json
, etc...)
- GraphQL endpoint (
- You can use the hidden api without any tokens
- Whisper uses the official web client's token
Example
Full example code can be seen on /test/example.test.ts
User By Screen Name (GraphQL endpoint)
const client = new TwitterAPI(Bearer.Web);
const query = new RequestQuery({
variables: {
screen_name: "deno_land",
withSafetyModeUserFields: true,
withSuperFollowsUserFields: true,
},
});
const res = await client.request({
method: "GET",
urlType: "gql",
path: "UserByScreenName",
query: query,
});
const json = await res.json();
assertEquals(json.data.user.result.rest_id, "1108769816230293504");
Search Adaptive (v2 endpoint)
const client = new TwitterAPI(Bearer.Web);
const query = new RequestQuery({
q: "from:@deno_land",
count: 3,
});
const res = await client.request({
method: "GET",
urlType: "i/api/2",
path: "/search/adaptive.json",
query: query,
});
const json = await res.json();
assertExists(json.globalObjects.users["1108769816230293504"]);
User Tweets (GraphQL endpoint)
const client = new TwitterAPI(Bearer.Web);
const query = new RequestQuery({
variables: {
userId: "1108769816230293504",
count: 4,
includePromotedContent: false,
withVoice: false,
withDownvotePerspective: true,
withReactionsMetadata: false,
withReactionsPerspective: false,
withSuperFollowsTweetFields: false,
withSuperFollowsUserFields: false,
},
features: {
tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled:
false,
interactive_text_enabled: true,
standardized_nudges_misinfo: true,
responsive_web_edit_tweet_api_enabled: true,
responsive_web_enhance_cards_enabled: false,
vibe_api_enabled: true,
dont_mention_me_view_api_enabled: true,
responsive_web_uc_gql_enabled: true,
},
});
const res = await client.request({
method: "GET",
urlType: "gql",
path: "UserTweets",
query: query,
});
const json = await res.json();
const timeline = json.data.user.result.timeline;
console.dir(timeline, { depth: 10 });
// Output:
//
// {
// timeline: {
// instructions: [
// { type: "TimelineClearCache" },
// {
// type: "TimelineAddEntries",
// entries: [
// {
// entryId: "tweet-1558145641565474816",
// sortIndex: "1558145641565474816",
// content: {
// entryType: "TimelineTimelineItem",
// __typename: "TimelineTimelineItem",
// itemContent: {
// itemType: "TimelineTweet",
// __typename: "TimelineTweet",
// tweet_results: {
// result: {
// __typename: "Tweet",
// rest_id: "1558145641565474816",
// core: [Object],
// card: [Object],
// unmention_info: [Object],
// unified_card: [Object],
// edit_control: [Object],
// legacy: [Object]
// }
// },
// tweetDisplayType: "Tweet",
// ruxContext: "HHwWgMCqnZTN0p8rAAAA"
// ...
Email Available (i endpoint)
const client = new TwitterAPI(Bearer.Web);
const query = new RequestQuery({
email: "twitter@example.com",
});
const res = await client.request({
method: "GET",
urlType: "i/api/i",
path: "/users/email_available.json",
query: query,
});
const json = await res.json();
assertEquals(json.valid, false);
assertEquals(json.taken, false);
Note
Request parameters and response types are not supported in this module due to the rapidly changing unofficial API specifications. Beware that Twitter will change its API specification without notice.