Replace old pinned tweet endpoint with GraphQL

This commit is contained in:
Zed 2023-03-24 02:13:30 +01:00
parent bed060f052
commit 5676ecc1f2
6 changed files with 29 additions and 23 deletions

View File

@ -69,6 +69,14 @@ proc getGraphListMembers*(list: List; after=""): Future[Result[User]] {.async.}
let url = graphListMembers ? {"variables": $variables, "features": gqlFeatures}
result = parseGraphListMembers(await fetchRaw(url, Api.listMembers), after)
proc getGraphTweetResult*(id: string): Future[Tweet] {.async.} =
if id.len == 0: return
let
variables = tweetResultVariables % id
params = {"variables": variables, "features": gqlFeatures}
js = await fetch(graphTweetResult ? params, Api.tweetResult)
result = parseGraphTweetResult(js)
proc getGraphTweet(id: string; after=""): Future[Conversation] {.async.} =
if id.len == 0: return
let
@ -87,10 +95,6 @@ proc getTweet*(id: string; after=""): Future[Conversation] {.async.} =
if after.len > 0:
result.replies = await getReplies(id, after)
proc getStatus*(id: string): Future[Tweet] {.async.} =
let url = status / (id & ".json") ? genParams()
result = parseStatus(await fetch(url, Api.status))
proc getPhotoRail*(name: string): Future[PhotoRail] {.async.} =
if name.len == 0: return
let

View File

@ -12,12 +12,13 @@ const
search* = api / "2/search/adaptive.json"
graphql = api / "graphql"
graphUser* = graphql / "8mPfHBetXOg-EHAyeVxUoA/UserByScreenName"
graphUserById* = graphql / "nI8WydSd-X-lQIVo6bdktQ/UserByRestId"
graphUserTweets* = graphql / "9rys0A7w1EyqVd2ME0QCJg/UserTweets"
graphUserTweetsAndReplies* = graphql / "ehMCHF3Mkgjsfz_aImqOsg/UserTweetsAndReplies"
graphUserMedia* = graphql / "MA_EP2a21zpzNWKRkaPBMg/UserMedia"
graphTweet* = graphql / "6I7Hm635Q6ftv69L8VrSeQ/TweetDetail"
graphUser* = graphql / "8mPfHBetXOg-EHAyeVxUoA/UserByScreenName"
graphUserById* = graphql / "nI8WydSd-X-lQIVo6bdktQ/UserByRestId"
graphTweetResult* = graphql / "rt-rHeSJ-2H9O9gxWQcPcg/TweetResultByRestId"
graphListById* = graphql / "iTpgCtbdxrsJfyx0cFjHqg/ListByRestId"
graphListBySlug* = graphql / "-kmqNvm5Y-cVrfvBy6docg/ListBySlug"
graphListMembers* = graphql / "P4NpVZDqUD_7MEM84L-8nw/ListMembers"
@ -91,6 +92,16 @@ const
"withVoice": false
}"""
tweetResultVariables* = """{
"tweetId": "$1",
"includePromotedContent": false,
"withDownvotePerspective": false,
"withReactionsMetadata": false,
"withReactionsPerspective": false,
"withVoice": false,
"withCommunity": false
}"""
userTweetsVariables* = """{
"userId": "$1", $2
"count": 20,

View File

@ -317,19 +317,6 @@ proc parseGlobalObjects(js: JsonNode): GlobalObjects =
tweet.user = result.users[tweet.user.id]
result.tweets[k] = tweet
proc parseStatus*(js: JsonNode): Tweet =
with e, js{"errors"}:
if e.getError in {tweetNotFound, tweetUnavailable, tweetCensored, doesntExist,
tweetNotAuthorized, suspended}:
return
result = parseTweet(js, js{"card"})
if not result.isNil:
result.user = parseUser(js{"user"})
with quote, js{"quoted_status"}:
result.quote = some parseStatus(js{"quoted_status"})
proc parseInstructions[T](res: var Result[T]; global: GlobalObjects; js: JsonNode) =
if js.kind != JArray or js.len == 0:
return
@ -425,6 +412,10 @@ proc parseGraphThread(js: JsonNode): tuple[thread: Chain; self: bool] =
if t{"item", "itemContent", "tweetDisplayType"}.getStr == "SelfThread":
result.self = true
proc parseGraphTweetResult*(js: JsonNode): Tweet =
with tweet, js{"data", "tweetResult", "result"}:
result = parseGraphTweet(tweet)
proc parseGraphConversation*(js: JsonNode; tweetId: string): Conversation =
result = Conversation(replies: Result[Chain](beginning: true))

View File

@ -153,7 +153,7 @@ proc getCachedTweet*(id: int64): Future[Tweet] {.async.} =
if tweet != redisNil:
tweet.deserialize(Tweet)
else:
result = await getStatus($id)
result = await getGraphTweetResult($id)
if not result.isNil:
await cache(result)

View File

@ -41,12 +41,12 @@ proc getPoolJson*(): JsonNode =
let
maxReqs =
case api
of Api.status: 180
of Api.search: 250
of Api.timeline: 187
of Api.listMembers, Api.listBySlug, Api.list, Api.listTweets,
Api.userTweets, Api.userTweetsAndReplies, Api.userMedia,
Api.userRestId, Api.userScreenName, Api.tweetDetail: 500
Api.userRestId, Api.userScreenName,
Api.tweetDetail, Api.tweetResult: 500
reqs = maxReqs - token.apis[api].remaining
reqsPerApi[$api] = reqsPerApi.getOrDefault($api, 0) + reqs

View File

@ -15,6 +15,7 @@ type
Api* {.pure.} = enum
tweetDetail
tweetResult
timeline
search
list
@ -26,7 +27,6 @@ type
userTweets
userTweetsAndReplies
userMedia
status
RateLimit* = object
remaining*: int