0

I want to use twitter api with Nim. But, I can't solve error.

{"errors":[{"code":85,"message":"The list failed validation: A list's name can't be blank."}]}

I success authentication.

Which I make a mistake using twitter API or using Nim library oauth1, sending Post method body?

import tables, oauth1, strutils, httpclient, json
proc parseResponseBody(body: string): Table[string, string] =
  let responses = body.split("&")
  result = initTable[string, string]()
  for res in responses:
    let r = res.split("=")
    result[r[0]] = r[1]

proc getRequestToken(consumerKey, consumerKeySecret: string): Table[string, string] =
  let response = getOAuth1RequestToken(
                      "https://api.twitter.com/oauth/request_token",
                      consumerKey,
                      consumerKeySecret,
                      isIncludeVersionToHeader = true)
  if response.status == "200 OK":
    return parseResponseBody(response.body)
  else:
    assert(false, response.body)

proc getAccessToken(consumerKey, consumerKeySecret, requestToken, requestTokenSecret, verifier: string): Table[string, string] =
  let response = getOAuth1AccessToken(
            "https://api.twitter.com/oauth/access_token",
            consumerKey,
            consumerKeySecret,
            requestToken,
            requestTokenSecret,
            verifier,
            isIncludeVersionToHeader = true)
  if response.status == "200 OK":
    return parseResponseBody(response.body)
  else:
    assert(false, response.body)

let
  consumerKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  consumerKeySecret  = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

let requestToken = getRequestToken(consumerKey, consumerKeySecret)
echo getAuthorizeUrl("https://api.twitter.com/oauth/authorize", requestToken["oauth_token"])
let verifier = readLine(stdin)
let accessTokens = getAccessToken(
                          consumerKey,
                          consumerKeySecret,
                          requestToken["oauth_token"],
                          requestToken["oauth_token_secret"],
                          verifier)
let param = %*{"name": "chage","mode": "private","description": "description"}
let response = oauth1Request(
  "https://api.twitter.com/1.1/lists/create.json",
  consumerKey,
  consumerKeySecret,
  accessTokens["oauth_token"],
  accessTokens["oauth_token_secret"],
  httpMethod = HttpPost,
  body = $param
)
echo response.body
leaf_chage
  • 11
  • 2

1 Answers1

3

Looking at the documentation for the Twitter API it seems like it takes it's input in the form of query parameters and not a JSON body. This means that you need to not create a param JSON object but rather a parameter string. This can be done by simple concatenation, but make sure to escape URI characters with something like: https://nim-lang.org/docs/uri.html#encodeUrl,string

PMunch
  • 1,525
  • 11
  • 20
  • I know. I tried to send it. `let param = "name=chage&mode=private&description=description".encodeUrl` It was same error. – leaf_chage Apr 27 '18 at 02:14
  • Well that URL encodes the entire params list, basically turning it into a single key. What you need to do is use encodeUrl on only the arguments. If you plan to use it with hard-coded strings like your example you could of course just drop it and use `https://api.twitter.com/1.1/lists/create.json?name=chage&mode=private&description=description` – PMunch Apr 27 '18 at 09:41
  • Thank you! I success it. I changed code ` let param = "name=" & "chage".encodeUrl & "&mode=" & "private".encodeUrl & "&description=" & "description".encodeUrl` and didn't send body parameter. – leaf_chage Apr 27 '18 at 10:04
  • It has example. Why don't you use it? https://github.com/CORDEA/oauth/blob/develop/examples/twitter.nim – shinriyo Jun 26 '18 at 01:12