mirror of
https://github.com/zedeus/nitter.git
synced 2024-06-01 19:33:49 +00:00
Update GraphQL endpoint versions
This commit is contained in:
parent
8fc3c3dec5
commit
061694a571
19
src/api.nim
19
src/api.nim
|
@ -24,9 +24,10 @@ proc getGraphUserTweets*(id: string; after=""; replies=false): Future[Timeline]
|
|||
let
|
||||
cursor = if after.len > 0: "\"cursor\":\"$1\"," % after else: ""
|
||||
variables = userTweetsVariables % [id, cursor]
|
||||
params = {"variables": variables, "features": userTweetsFeatures}
|
||||
url = if replies: graphUserTweetsAndReplies else: graphUserTweets
|
||||
js = await fetch(url ? params, Api.tweetDetail)
|
||||
params = {"variables": variables, "features": tweetFeatures}
|
||||
(url, apiId) = if replies: (graphUserTweetsAndReplies, Api.userTweetsAndReplies)
|
||||
else: (graphUserTweets, Api.userTweets)
|
||||
js = await fetch(url ? params, apiId)
|
||||
result = parseGraphTimeline(js, after)
|
||||
|
||||
proc getGraphListBySlug*(name, list: string): Future[List] {.async.} =
|
||||
|
@ -65,18 +66,6 @@ proc getListTimeline*(id: string; after=""): Future[Timeline] {.async.} =
|
|||
url = listTimeline ? ps
|
||||
result = parseTimeline(await fetch(url, Api.timeline), after)
|
||||
|
||||
proc getTimeline*(id: string; after=""; replies=false): Future[Timeline] {.async.} =
|
||||
if id.len == 0: return
|
||||
let
|
||||
ps = genParams({"userId": id, "include_tweet_replies": $replies}, after)
|
||||
url = timeline / (id & ".json") ? ps
|
||||
result = parseTimeline(await fetch(url, Api.timeline), after)
|
||||
|
||||
proc getMediaTimeline*(id: string; after=""): Future[Timeline] {.async.} =
|
||||
if id.len == 0: return
|
||||
let url = mediaTimeline / (id & ".json") ? genParams(cursor=after)
|
||||
result = parseTimeline(await fetch(url, Api.timeline), after)
|
||||
|
||||
proc getPhotoRail*(name: string): Future[PhotoRail] {.async.} =
|
||||
if name.len == 0: return
|
||||
let
|
||||
|
|
|
@ -7,23 +7,20 @@ const
|
|||
api = parseUri("https://api.twitter.com")
|
||||
activate* = $(api / "1.1/guest/activate.json")
|
||||
|
||||
userShow* = api / "1.1/users/show.json"
|
||||
photoRail* = api / "1.1/statuses/media_timeline.json"
|
||||
status* = api / "1.1/statuses/show"
|
||||
search* = api / "2/search/adaptive.json"
|
||||
|
||||
timelineApi = api / "2/timeline"
|
||||
timeline* = timelineApi / "profile"
|
||||
mediaTimeline* = timelineApi / "media"
|
||||
listTimeline* = timelineApi / "list.json"
|
||||
tweet* = timelineApi / "conversation"
|
||||
|
||||
graphql = api / "graphql"
|
||||
graphUserTweets* = graphql / "9rys0A7w1EyqVd2ME0QCJg/UserTweets"
|
||||
graphUserTweetsAndReplies* = graphql / "ehMCHF3Mkgjsfz_aImqOsg/UserTweetsAndReplies"
|
||||
graphTweet* = graphql / "6lWNh96EXDJCXl05SAtn_g/TweetDetail"
|
||||
graphUser* = graphql / "nZjSkpOpSL5rWyIVdsKeLA/UserByScreenName"
|
||||
graphUserById* = graphql / "I5nvpI91ljifos1Y3Lltyg/UserByRestId"
|
||||
graphTweet* = graphql / "6I7Hm635Q6ftv69L8VrSeQ/TweetDetail"
|
||||
graphUser* = graphql / "8mPfHBetXOg-EHAyeVxUoA/UserByScreenName"
|
||||
graphUserById* = graphql / "nI8WydSd-X-lQIVo6bdktQ/UserByRestId"
|
||||
graphList* = graphql / "JADTh6cjebfgetzvF3tQvQ/List"
|
||||
graphListBySlug* = graphql / "ErWsz9cObLel1BF-HjuBlA/ListBySlug"
|
||||
graphListMembers* = graphql / "Ke6urWMeCV2UlKXGRy4sow/ListMembers"
|
||||
|
@ -63,75 +60,53 @@ const
|
|||
## photos: "result_filter: photos"
|
||||
## videos: "result_filter: videos"
|
||||
|
||||
userTweetsVariables* = """{
|
||||
"userId": "$1",
|
||||
$2
|
||||
"count": 20,
|
||||
"includePromotedContent": false,
|
||||
"withDownvotePerspective": false,
|
||||
"withReactionsMetadata": false,
|
||||
"withReactionsPerspective": false,
|
||||
"withVoice": false,
|
||||
"withV2Timeline": true
|
||||
userFeatures* = """{
|
||||
"responsive_web_twitter_blue_verified_badge_is_enabled": true,
|
||||
"responsive_web_graphql_exclude_directive_enabled": true,
|
||||
"responsive_web_graphql_skip_user_profile_image_extensions_enabled": true,
|
||||
"responsive_web_graphql_timeline_navigation_enabled": false,
|
||||
"verified_phone_label_enabled": false
|
||||
}"""
|
||||
|
||||
userTweetsFeatures* = """{
|
||||
"responsive_web_twitter_blue_verified_badge_is_enabled": true,
|
||||
"responsive_web_graphql_exclude_directive_enabled": false,
|
||||
"verified_phone_label_enabled": false,
|
||||
"responsive_web_graphql_timeline_navigation_enabled": false,
|
||||
"responsive_web_graphql_skip_user_profile_image_extensions_enabled": false,
|
||||
"tweetypie_unmention_optimization_enabled": false,
|
||||
"vibe_api_enabled": false,
|
||||
"responsive_web_edit_tweet_api_enabled": false,
|
||||
"graphql_is_translatable_rweb_tweet_is_translatable_enabled": false,
|
||||
"view_counts_everywhere_api_enabled": false,
|
||||
tweetFeatures* = """{
|
||||
"longform_notetweets_consumption_enabled": true,
|
||||
"tweet_awards_web_tipping_enabled": false,
|
||||
"longform_notetweets_richtext_consumption_enabled": true,
|
||||
"responsive_web_twitter_blue_verified_badge_is_enabled": true,
|
||||
"freedom_of_speech_not_reach_fetch_enabled": false,
|
||||
"standardized_nudges_misinfo": false,
|
||||
"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": false,
|
||||
"graphql_is_translatable_rweb_tweet_is_translatable_enabled": false,
|
||||
"interactive_text_enabled": false,
|
||||
"responsive_web_edit_tweet_api_enabled": false,
|
||||
"responsive_web_enhance_cards_enabled": false,
|
||||
"responsive_web_graphql_exclude_directive_enabled": false,
|
||||
"responsive_web_graphql_skip_user_profile_image_extensions_enabled": false,
|
||||
"responsive_web_graphql_timeline_navigation_enabled": false,
|
||||
"responsive_web_text_conversations_enabled": false,
|
||||
"longform_notetweets_richtext_consumption_enabled": false,
|
||||
"responsive_web_enhance_cards_enabled": false
|
||||
"standardized_nudges_misinfo": false,
|
||||
"tweet_awards_web_tipping_enabled": false,
|
||||
"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": false,
|
||||
"tweetypie_unmention_optimization_enabled": false,
|
||||
"view_counts_everywhere_api_enabled": false,
|
||||
"vibe_api_enabled": false,
|
||||
"verified_phone_label_enabled": false
|
||||
}"""
|
||||
|
||||
tweetVariables* = """{
|
||||
"focalTweetId": "$1",
|
||||
$2
|
||||
"includePromotedContent": false,
|
||||
"withBirdwatchNotes": false,
|
||||
"includePromotedContent": false,
|
||||
"withDownvotePerspective": false,
|
||||
"withReactionsMetadata": false,
|
||||
"withReactionsPerspective": false,
|
||||
"withSuperFollowsTweetFields": false,
|
||||
"withSuperFollowsUserFields": false,
|
||||
"withVoice": false,
|
||||
"withV2Timeline": true
|
||||
"withVoice": false
|
||||
}"""
|
||||
|
||||
tweetFeatures* = """{
|
||||
"graphql_is_translatable_rweb_tweet_is_translatable_enabled": false,
|
||||
"responsive_web_graphql_timeline_navigation_enabled": false,
|
||||
"standardized_nudges_misinfo": false,
|
||||
"verified_phone_label_enabled": false,
|
||||
"responsive_web_twitter_blue_verified_badge_is_enabled": true,
|
||||
"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": false,
|
||||
"view_counts_everywhere_api_enabled": false,
|
||||
"responsive_web_edit_tweet_api_enabled": false,
|
||||
"tweetypie_unmention_optimization_enabled": false,
|
||||
"vibe_api_enabled": false,
|
||||
"longform_notetweets_consumption_enabled": true,
|
||||
"responsive_web_text_conversations_enabled": false,
|
||||
"responsive_web_enhance_cards_enabled": false,
|
||||
"interactive_text_enabled": false
|
||||
}"""
|
||||
|
||||
userFeatures* = """{
|
||||
"responsive_web_twitter_blue_verified_badge_is_enabled": true,
|
||||
"verified_phone_label_enabled": false,
|
||||
"responsive_web_graphql_timeline_navigation_enabled": false,
|
||||
"responsive_web_graphql_exclude_directive_enabled": true,
|
||||
"responsive_web_graphql_skip_user_profile_image_extensions_enabled": true
|
||||
userTweetsVariables* = """{
|
||||
"userId": "$1", $2
|
||||
"count": 20,
|
||||
"includePromotedContent": false,
|
||||
"withDownvotePerspective": false,
|
||||
"withReactionsMetadata": false,
|
||||
"withReactionsPerspective": false,
|
||||
"withVoice": false
|
||||
}"""
|
||||
|
|
|
@ -428,7 +428,7 @@ proc parseGraphThread(js: JsonNode): tuple[thread: Chain; self: bool] =
|
|||
proc parseGraphConversation*(js: JsonNode; tweetId: string): Conversation =
|
||||
result = Conversation(replies: Result[Chain](beginning: true))
|
||||
|
||||
let instructions = ? js{"data", "threaded_conversation_with_injections_v2", "instructions"}
|
||||
let instructions = ? js{"data", "threaded_conversation_with_injections", "instructions"}
|
||||
if instructions.len == 0:
|
||||
return
|
||||
|
||||
|
@ -436,15 +436,16 @@ proc parseGraphConversation*(js: JsonNode; tweetId: string): Conversation =
|
|||
let entryId = e{"entryId"}.getStr
|
||||
# echo entryId
|
||||
if entryId.startsWith("tweet"):
|
||||
let tweet = parseGraphTweet(e{"content", "itemContent", "tweet_results", "result"})
|
||||
with tweetResult, e{"content", "itemContent", "tweet_results", "result"}:
|
||||
let tweet = parseGraphTweet(tweetResult)
|
||||
|
||||
if not tweet.available:
|
||||
tweet.id = parseBiggestInt(entryId.getId())
|
||||
if not tweet.available:
|
||||
tweet.id = parseBiggestInt(entryId.getId())
|
||||
|
||||
if $tweet.id == tweetId:
|
||||
result.tweet = tweet
|
||||
else:
|
||||
result.before.content.add tweet
|
||||
if $tweet.id == tweetId:
|
||||
result.tweet = tweet
|
||||
else:
|
||||
result.before.content.add tweet
|
||||
elif entryId.startsWith("conversationthread"):
|
||||
let (thread, self) = parseGraphThread(e)
|
||||
if self:
|
||||
|
@ -457,17 +458,18 @@ proc parseGraphConversation*(js: JsonNode; tweetId: string): Conversation =
|
|||
proc parseGraphTimeline*(js: JsonNode; after=""): Timeline =
|
||||
result = Timeline(beginning: after.len == 0)
|
||||
|
||||
let instructions = ? js{"data", "user", "result", "timeline_v2", "timeline", "instructions"}
|
||||
let instructions = ? js{"data", "user", "result", "timeline", "timeline", "instructions"}
|
||||
if instructions.len == 0:
|
||||
return
|
||||
|
||||
for e in instructions[instructions.len - 1]{"entries"}:
|
||||
let entryId = e{"entryId"}.getStr
|
||||
if entryId.startsWith("tweet"):
|
||||
let tweet = parseGraphTweet(e{"content", "itemContent", "tweet_results", "result"})
|
||||
if not tweet.available:
|
||||
tweet.id = parseBiggestInt(entryId.getId())
|
||||
result.content.add tweet
|
||||
with tweetResult, e{"content", "itemContent", "tweet_results", "result"}:
|
||||
let tweet = parseGraphTweet(tweetResult)
|
||||
if not tweet.available:
|
||||
tweet.id = parseBiggestInt(entryId.getId())
|
||||
result.content.add tweet
|
||||
elif entryId.startsWith("cursor-bottom"):
|
||||
result.bottom = e{"content", "value"}.getStr
|
||||
elif "cursor-top" notin entryId:
|
||||
|
|
|
@ -10,16 +10,16 @@ type
|
|||
|
||||
Api* {.pure.} = enum
|
||||
tweetDetail
|
||||
userShow
|
||||
timeline
|
||||
search
|
||||
tweet
|
||||
list
|
||||
listBySlug
|
||||
listMembers
|
||||
userRestId
|
||||
userScreenName
|
||||
userTweets
|
||||
userTweetsAndReplies
|
||||
userMedia
|
||||
status
|
||||
|
||||
RateLimit* = object
|
||||
|
|
Loading…
Reference in a new issue