apiutils.nim 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import httpclient, asyncdispatch, options, times, strutils, uri
  2. import packedjson
  3. import types, tokens, consts, parserutils
  4. const rl = "x-rate-limit-"
  5. proc genParams*(pars: openarray[(string, string)] = @[];
  6. cursor=""): seq[(string, string)] =
  7. result = timelineParams
  8. for p in pars:
  9. result &= p
  10. if cursor.len > 0:
  11. result &= ("cursor", cursor)
  12. proc genHeaders*(token: Token = nil): HttpHeaders =
  13. result = newHttpHeaders({
  14. "authorization": auth,
  15. "content-type": "application/json",
  16. "x-guest-token": if token == nil: "" else: token.tok,
  17. "x-twitter-active-user": "yes",
  18. "authority": "api.twitter.com",
  19. "accept-language": "en-US,en;q=0.9",
  20. "accept": "*/*",
  21. "DNT": "1"
  22. })
  23. proc fetch*(url: Uri; oldApi=false): Future[JsonNode] {.async.} =
  24. var
  25. token = if oldApi: nil else: await getToken()
  26. client = newAsyncHttpClient(headers=genHeaders(token))
  27. try:
  28. let
  29. resp = await client.get($url)
  30. body = await resp.body
  31. if not body.startsWith('{'):
  32. echo resp.status, ": ", body
  33. result = newJNull()
  34. else:
  35. result = parseJson(body)
  36. if not oldApi and resp.headers.hasKey(rl & "limit"):
  37. token.remaining = parseInt(resp.headers[rl & "remaining"])
  38. token.reset = fromUnix(parseInt(resp.headers[rl & "reset"]))
  39. if result.getError notin {invalidToken, forbidden, badToken}:
  40. token.release()
  41. except Exception:
  42. echo "error: ", url
  43. result = newJNull()
  44. finally:
  45. try: client.close()
  46. except: discard