fix headers so UserByRestId works
This commit is contained in:
parent
0e74c1e9bd
commit
ec019eef72
36
src/api.nim
36
src/api.nim
@ -6,23 +6,41 @@ import experimental/parser as newParser
|
|||||||
|
|
||||||
proc getGraphUser*(username: string): Future[User] {.async.} =
|
proc getGraphUser*(username: string): Future[User] {.async.} =
|
||||||
if username.len == 0: return
|
if username.len == 0: return
|
||||||
|
|
||||||
|
let
|
||||||
|
headers = newHttpHeaders()
|
||||||
|
headers.add("Referer", """https://x.com/$1""" % username)
|
||||||
|
|
||||||
let
|
let
|
||||||
variables = """{"screen_name":"$1"}""" % username
|
variables = """{"screen_name":"$1"}""" % username
|
||||||
fieldToggles = """{"withAuxiliaryUserLabels":true}"""
|
fieldToggles = """{"withAuxiliaryUserLabels":true}"""
|
||||||
params = {"variables": variables, "features": gqlFeatures, "fieldToggles": fieldToggles}
|
params = {"variables": variables, "features": gqlFeatures, "fieldToggles": fieldToggles}
|
||||||
js = await fetch(graphUser ? params, Api.userScreenName)
|
js = await fetch(graphUser ? params, Api.userScreenName, headers)
|
||||||
result = parseGraphUser(js)
|
result = parseGraphUser(js)
|
||||||
|
|
||||||
proc getGraphUserById*(id: string): Future[User] {.async.} =
|
proc getGraphUserById*(id: string): Future[User] {.async.} =
|
||||||
if id.len == 0 or id.any(c => not c.isDigit): return
|
if id.len == 0 or id.any(c => not c.isDigit): return
|
||||||
|
let
|
||||||
|
headers = newHttpHeaders()
|
||||||
|
headers.add("Referer", """https://x.com/i/user/$1""" % id)
|
||||||
|
|
||||||
let
|
let
|
||||||
variables = """{"userId":"$1"}""" % id
|
variables = """{"userId":"$1"}""" % id
|
||||||
params = {"variables": variables, "features": gqlFeatures}
|
params = {"variables": variables, "features": gqlFeatures}
|
||||||
js = await fetch(graphUserById ? params, Api.userRestId)
|
js = await fetch(graphUserById ? params, Api.userRestId, headers)
|
||||||
result = parseGraphUser(js)
|
result = parseGraphUser(js)
|
||||||
|
|
||||||
proc getGraphUserTweets*(id: string; kind: TimelineKind; after=""): Future[Profile] {.async.} =
|
proc getGraphUserTweets*(id: string; kind: TimelineKind; after=""): Future[Profile] {.async.} =
|
||||||
if id.len == 0: return
|
if id.len == 0: return
|
||||||
|
|
||||||
|
let endpoint = case kind
|
||||||
|
of TimelineKind.tweets: ""
|
||||||
|
of TimelineKind.replies: "/with_replies"
|
||||||
|
of TimelineKind.media: "/media"
|
||||||
|
let
|
||||||
|
headers = newHttpHeaders()
|
||||||
|
headers.add("Referer", """https://x.com/$1$2""" % [id, endpoint])
|
||||||
|
|
||||||
let
|
let
|
||||||
cursor = if after.len > 0: "\"cursor\":\"$1\"," % after else: ""
|
cursor = if after.len > 0: "\"cursor\":\"$1\"," % after else: ""
|
||||||
variables = if kind == TimelineKind.media: userMediaVariables % [id, cursor] else: userTweetsVariables % [id, cursor]
|
variables = if kind == TimelineKind.media: userMediaVariables % [id, cursor] else: userTweetsVariables % [id, cursor]
|
||||||
@ -32,7 +50,7 @@ proc getGraphUserTweets*(id: string; kind: TimelineKind; after=""): Future[Profi
|
|||||||
of TimelineKind.tweets: (graphUserTweets, Api.userTweets)
|
of TimelineKind.tweets: (graphUserTweets, Api.userTweets)
|
||||||
of TimelineKind.replies: (graphUserTweetsAndReplies, Api.userTweetsAndReplies)
|
of TimelineKind.replies: (graphUserTweetsAndReplies, Api.userTweetsAndReplies)
|
||||||
of TimelineKind.media: (graphUserMedia, Api.userMedia)
|
of TimelineKind.media: (graphUserMedia, Api.userMedia)
|
||||||
js = await fetch(url ? params, apiId)
|
js = await fetch(url ? params, apiId, headers)
|
||||||
result = parseGraphTimeline(js, if kind == TimelineKind.media: "" else: "user", after)
|
result = parseGraphTimeline(js, if kind == TimelineKind.media: "" else: "user", after)
|
||||||
|
|
||||||
proc getGraphListTweets*(id: string; after=""): Future[Timeline] {.async.} =
|
proc getGraphListTweets*(id: string; after=""): Future[Timeline] {.async.} =
|
||||||
@ -90,19 +108,27 @@ proc getFavorites*(id: string; cfg: Config; after=""): Future[Profile] {.async.}
|
|||||||
|
|
||||||
proc getGraphTweetResult*(id: string): Future[Tweet] {.async.} =
|
proc getGraphTweetResult*(id: string): Future[Tweet] {.async.} =
|
||||||
if id.len == 0: return
|
if id.len == 0: return
|
||||||
|
let
|
||||||
|
headers = newHttpHeaders()
|
||||||
|
headers.add("Referer", """https://x.com/i/status/$1""" % id)
|
||||||
|
|
||||||
let
|
let
|
||||||
variables = """{"rest_id":"$1"}""" % id
|
variables = """{"rest_id":"$1"}""" % id
|
||||||
params = {"variables": variables, "features": gqlFeatures}
|
params = {"variables": variables, "features": gqlFeatures}
|
||||||
js = await fetch(graphTweetResult ? params, Api.tweetResult)
|
js = await fetch(graphTweetResult ? params, Api.tweetResult, headers)
|
||||||
result = parseGraphTweetResult(js)
|
result = parseGraphTweetResult(js)
|
||||||
|
|
||||||
proc getGraphTweet*(id: string; after=""): Future[Conversation] {.async.} =
|
proc getGraphTweet*(id: string; after=""): Future[Conversation] {.async.} =
|
||||||
if id.len == 0: return
|
if id.len == 0: return
|
||||||
|
let
|
||||||
|
headers = newHttpHeaders()
|
||||||
|
headers.add("Referer", """https://x.com/i/status/$1""" % id)
|
||||||
|
|
||||||
let
|
let
|
||||||
cursor = if after.len > 0: "\"cursor\":\"$1\"," % after else: ""
|
cursor = if after.len > 0: "\"cursor\":\"$1\"," % after else: ""
|
||||||
variables = tweetVariables % [id, cursor]
|
variables = tweetVariables % [id, cursor]
|
||||||
params = {"variables": variables, "features": gqlFeatures, "fieldToggles": tweetFieldToggles}
|
params = {"variables": variables, "features": gqlFeatures, "fieldToggles": tweetFieldToggles}
|
||||||
js = await fetch(graphTweet ? params, Api.tweetDetail)
|
js = await fetch(graphTweet ? params, Api.tweetDetail, headers)
|
||||||
result = parseGraphConversation(js, id)
|
result = parseGraphConversation(js, id)
|
||||||
|
|
||||||
proc getGraphFavoriters*(id: string; after=""): Future[UsersTimeline] {.async.} =
|
proc getGraphFavoriters*(id: string; after=""): Future[UsersTimeline] {.async.} =
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
import httpclient, asyncdispatch, options, strutils, uri, times, tables
|
import httpclient, asyncdispatch, options, strutils, uri, times, tables, math
|
||||||
import jsony, packedjson, zippy
|
import jsony, packedjson, zippy
|
||||||
import types, tokens, consts, parserutils, http_pool
|
import types, tokens, consts, parserutils, http_pool
|
||||||
import experimental/types/common
|
import experimental/types/common
|
||||||
@ -32,6 +32,9 @@ proc genParams*(pars: openArray[(string, string)] = @[]; cursor="";
|
|||||||
|
|
||||||
#proc genHeaders*(token: Token = nil): HttpHeaders =
|
#proc genHeaders*(token: Token = nil): HttpHeaders =
|
||||||
proc genHeaders*(): HttpHeaders =
|
proc genHeaders*(): HttpHeaders =
|
||||||
|
let
|
||||||
|
t = getTime()
|
||||||
|
ffVersion = floor(124 + ((t.toUnix() / 1000) - 1710892800) / 2419200)
|
||||||
result = newHttpHeaders({
|
result = newHttpHeaders({
|
||||||
"connection": "keep-alive",
|
"connection": "keep-alive",
|
||||||
"authorization": auth,
|
"authorization": auth,
|
||||||
@ -45,8 +48,12 @@ proc genHeaders*(): HttpHeaders =
|
|||||||
"Sec-Fetch-Mode": "cors",
|
"Sec-Fetch-Mode": "cors",
|
||||||
"Sec-Fetch-Site": "same-origin",
|
"Sec-Fetch-Site": "same-origin",
|
||||||
"Sec-GPC": "1",
|
"Sec-GPC": "1",
|
||||||
"TE": "trailers"
|
"TE": "trailers",
|
||||||
})
|
"User-Agent": """Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:$1.0) Gecko/20100101 Firefox/$1.0""" % $ffVersion,
|
||||||
|
"x-twitter-active-user": "yes",
|
||||||
|
"x-twitter-auth-type": "OAuth2Session",
|
||||||
|
"x-twitter-client-language": "en"
|
||||||
|
}, true)
|
||||||
|
|
||||||
#template updateToken() =
|
#template updateToken() =
|
||||||
# if resp.headers.hasKey(rlRemaining):
|
# if resp.headers.hasKey(rlRemaining):
|
||||||
@ -66,21 +73,16 @@ template fetchImpl(result, additional_headers, fetchBody) {.dirty.} =
|
|||||||
if len(cfg.cookieHeader) != 0:
|
if len(cfg.cookieHeader) != 0:
|
||||||
additional_headers.add("Cookie", cfg.cookieHeader)
|
additional_headers.add("Cookie", cfg.cookieHeader)
|
||||||
|
|
||||||
additional_headers.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:145.0) Gecko/20100101 Firefox/145.0")
|
|
||||||
|
|
||||||
if len(cfg.xCsrfToken) != 0:
|
if len(cfg.xCsrfToken) != 0:
|
||||||
additional_headers.add("x-csrf-token", cfg.xCsrfToken)
|
additional_headers.add("x-csrf-token", cfg.xCsrfToken)
|
||||||
|
|
||||||
additional_headers.add("x-twitter-active-user", "yes")
|
|
||||||
additional_headers.add("x-twitter-auth-type", "OAuth2Session")
|
|
||||||
additional_headers.add("x-twitter-client-language", "en")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
var resp: AsyncResponse
|
var resp: AsyncResponse
|
||||||
#var headers = genHeaders(token)
|
#var headers = genHeaders(token)
|
||||||
var headers = genHeaders()
|
var headers = genHeaders()
|
||||||
for key, value in additional_headers.pairs():
|
for key, value in additional_headers.pairs():
|
||||||
headers.add(key, value)
|
headers.add(key, value)
|
||||||
|
|
||||||
pool.use(headers):
|
pool.use(headers):
|
||||||
template getContent =
|
template getContent =
|
||||||
resp = await c.get($url)
|
resp = await c.get($url)
|
||||||
|
|||||||
@ -151,7 +151,7 @@ proc getCachedUsername*(userId: string): Future[string] {.async.} =
|
|||||||
key = "i:" & userId
|
key = "i:" & userId
|
||||||
username = await get(key)
|
username = await get(key)
|
||||||
|
|
||||||
if username != redisNil:
|
if username != redisNil and username.len > 0:
|
||||||
result = username
|
result = username
|
||||||
else:
|
else:
|
||||||
let user = await getGraphUserById(userId)
|
let user = await getGraphUserById(userId)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user