mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Jul 2014
Posts: 48
A
Ameglian cow
OP Offline
Ameglian cow
A
Joined: Jul 2014
Posts: 48
Hello,
Been awhile since I've been around here, but just came across a new API I was waiting for to come out, and have been trying to figure out implementation into IRC script.


Basically just simple GET/POST requests. I have everything working correctly, the requests are successful, but I can't seem to get any needed information.

This is the code to GET information, API pertains to points for being in the server gained per minute.
Code:
  var %sw sockwrite -n points
  %sw GET /1/fans/aeonpsych/points HTTP/1.1
  %sw x-api-key: <api-key-removed>
  %sw Content-Type: application/x-www-form-urlencoded
  %sw Accept: application/json
  %sw Host: <host-removed>:443
  %sw Connection: close
  %sw $crlf




When I use a web based request for the api call, the response is:
Code:
HTTP/1.1 200 OK
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,x-api-key
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Content-Type: application/json
Date: Thu, 12 Jan 2017 09:00:45 GMT
Server: nginx/1.4.6 (Ubuntu)
X-Content-Type-Options: nosniff
Content-Length: 108
Connection: Close

{"loyalty":{"fan":"aeon","total_points":64,"current_points":64,"updated_at":"2017-01-12T09:00:00.000Z"}}




but when I make the request within irc client, the response is only the headers of the response (not any of the body), and I can't get the points data from such:
Code:
HTTP/1.1 200 OK
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,x-api-key
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Content-Type: application/json
Date: Thu, 12 Jan 2017 09:57:35 GMT
Server: nginx/1.4.6 (Ubuntu)
X-Content-Type-Options: nosniff
Content-Length: 115
Connection: Close





The POST request I use to add/subtract points works from both within the irc client and web client. The amount:3 is the total to add or subtract):
Code:
var %sw sockwrite -n addpoints
  %sw POST /1/fans/aeon/points/bonus HTTP/1.1
  %sw x-api-key: <api-key-removed>
  %sw Content-Length: 14
  %sw Content-Type: application/x-www-form-urlencoded
  %sw Accept: application/json
  %sw Host: <host-removed>:443
  %sw Connection: close
  %sw $crlf

  %sw {"amount": 3}


The assistance I am looking for is how can I get the points data from the socket/request? It comes out great when I make the call from a web client, but not from within irc.



Joined: Jul 2006
Posts: 4,149
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,149
Hello, you forgot to include the most important part of what is needed to help you: the on sockread event.
An easy guess is that you are only reading a line with /sockread %var (which does not read anything if there's no line ending sequence) and the JSON data is on one big line with no line ending sequence.
More about how to deal with this and how to properly read from on sockread in general here.
If you are dealing with JSON, you may want to look for a JSON parser


#mircscripting @ irc.swiftirc.net == the best mIRC help channel
Joined: Jul 2014
Posts: 48
A
Ameglian cow
OP Offline
Ameglian cow
A
Joined: Jul 2014
Posts: 48
this is the code I am using for reading from the socket:
Code:
if ($sockerr) { sockclose $sockname }
  var %streamodata
  sockread %streamodata

  tokenize 32 %streamodata

  echo -a %streamodata



Using this, only prints out the response headers, exactly as posted, originally. I'll take a look at that, thanks.




Edit:
I did a quick test by adding the -f switch to force read... It did end up reading in the full body this time, so that does seem to be my issue.

I do have a json parser, but when I use it, it also does not return any value from the data. It's been awhile since I used the json parser, so maybe I am just drawing blanks and forgetting how to use it, but I've tried running this code through the parser:

Code:
JSONOpen -uw points https://<url-removed>
  JSONURLMethod points GET
  JSONUrlHeader points Accept application/json
  JSONUrlHeader points Host <host-removed>:443
  JSONUrlHeader points Connection close
  JSONUrlHeader points x-api-key <api-key-removed>
  JSONUrlHeader points Content-Type application/x-www-form-urlencoded 

echo -a Result1: $json(points, current_points)


The output is just "Result1: "

Last edited by AeonPsych; 12/01/17 06:53 PM.
Joined: Apr 2010
Posts: 969
F
Hoopy frood
Offline
Hoopy frood
F
Joined: Apr 2010
Posts: 969
Dependant on which version of my json parser you are using -- you can check with: //echo -a $JSONVersion -- the JSON request should look like one of the following, assume the returned body is similar to the following(line breaks added for readability):
Code:
{
  "loyalty":{
    "fan":"aeon",
    "total_points":64,
    "current_points":64,
    "updated_at":"2017-01-12T09:00:00.000Z"
  }
}



v0.2.4x
Code:
alias example {
  JSONOpen -duw points <url>
  JSONUrlMethod points GET
  JSONUrlHeader points x-api-key <api-key-removed>
  ;; These headers are auto-set by the json parser
  ;;   Host: <host-removed>:443
  ;;   Connection: close
  ;; This header isn't needed as you aren't sending any data
  ;;   Content-Type application/x-www-form-urlencoded
  JSONUrlGet points

  echo -a Fan: $JSON(points, loyalty, fan)
  echo -a Total: $JSON(points, loyalty, total_points)
  echo -a Current: $JSON(points, loyalty, current_points)
  echo -a Updated: $JSON(points, loyalty, updated_at)
}


v1.0.x - (Recommended)
Code:
alias example {
  JSONOpen -duw points <url>
  JSONHttpMethod points GET
  JSONHttpHeader points x-api-key <api-key-removed>
  ;; These headers are auto-set by the json parser
  ;;   Host: <host-removed>:443
  ;;   Connection: close
  ;; This header isn't needed as you aren't sending any data
  ;;   Content-Type application/x-www-form-urlencoded
  JSONHttpFetch points

  echo -a Fan: $JSON(points, loyalty, fan).value
  echo -a Total: $JSON(points, loyalty, total_points).value
  echo -a Current: $JSON(points, loyalty, current_points).value
  echo -a Updated: $JSON(points, loyalty, updated_at).value
}



Last edited by FroggieDaFrog; 12/01/17 09:19 PM.

I am SReject
My Stuff
Joined: Jul 2014
Posts: 48
A
Ameglian cow
OP Offline
Ameglian cow
A
Joined: Jul 2014
Posts: 48
EDIT: Alright, so with FroggieDaFrog's assistance, I was able to finally narrow, and find the problem. It was an open JSON handler that was not closing, and it had a name of the new handler I was trying to use... /jsonlist /jsonclose and now it works like it should.



just check version. Appears I am using the older version: "JSONForMirc v.0.2.4"

I also updated my code to better match what you gave:
Code:
  JSONOpen -duw points <url>
  JSONURLMethod points GET
  JSONUrlHeader points x-api-key <key-removed>
  JSONUrlGet points

  echo -a fan: $json(points, loyalty, fan)
  echo -a Total: $JSON(points, loyalty, total_points)
  echo -a Current: $JSON(points, loyalty, current_points)
  echo -a Updated: $JSON(points, loyalty, updated_at)



output is still nothing for each of the values. I thought I was going in the right direction, seeing as how I was missing the "JSONUrlGet points" but it did not seem to change anything.


Note: I was able to get the data I needed through normal sockets using the suggested tips without using json parser, but it was a pain having to tokenize sections of the response, and then even substring. Would be nice to have the json parser working!

Last edited by AeonPsych; 12/01/17 10:36 PM. Reason: I'm dumb for trying to shorten and make code ambiguous... Learn from my mistake
Joined: Jul 2006
Posts: 4,149
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,149
Using /sockread -f inside on sockread isn't what you need. Please read the whole tutorial about how to properly read from a socket, you must not use -f inside on sockread, you should rather use it from on sockclose.


#mircscripting @ irc.swiftirc.net == the best mIRC help channel
Joined: Feb 2015
Posts: 243
O
Fjord artisan
Offline
Fjord artisan
O
Joined: Feb 2015
Posts: 243
In my humble opinion an easy solution to get the body would be to include the Connection: Close header in the sockopen event
Code:
sockwrite -nt $sockname Connection: Close

And use, as said by Wims, the sockread -f in the sockclose event..

Joined: Apr 2010
Posts: 969
F
Hoopy frood
Offline
Hoopy frood
F
Joined: Apr 2010
Posts: 969
This has been fixed; He forgot to close the json handler in his original test which caused subsequent testing to fail. We troubleshot it and have his script working.


I am SReject
My Stuff
Joined: Jul 2014
Posts: 48
A
Ameglian cow
OP Offline
Ameglian cow
A
Joined: Jul 2014
Posts: 48
while yes, I shouldn't be using the -f switch in the manner I did, I did say I put it in as a quick fix/test to force read the entire buffer. After the headers, in the response, there is a line break. The reader assumes that is the end of the response, and stops reading. That was the initial problem, why I wasn't getting the body of the response, and using the -f switch as a quick test worked in that manner.


As for the JSON part, Froggie was correct, as I also mentioned in my previous post edit. The JSON wasn't returning any information due to an unclosed handler with the same name.

Both JSON and using sockets works correctly now.


Link Copied to Clipboard