Hi ,
I am trying to write a script that can pass API credentials.
As an example i want to get the available cash as in https://www.lendingclub.com/developers/available-cash (https://www.lendingclub.com/developers/available-cash)
This is my first time writing calls to JSON, so I am a little lost.
Here is what I wrote so far , but it returns a bad response.
Any help would be appreciated.
Invest_ID = "5166XXX"
cURL = 'https://api.lendingclub.com/api/investor/v1/accounts/%Invest_ID%/availablecash'
apikey = 'GVsZuDKATPRlsajFiBXXXXXXX'
GoSub UDFs
oHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
a = oHTTP.Open("GET", cURL, @FALSE)
;----------------------------------------------------------------------------
; Define Headers
;----------------------------------------------------------------------------
str_64=Base64StringFromClearString(B64GetCookie(),StrCat(":",apikey))
oHTTP.SetRequestHeader("Authorization",StrCat("Basic ", str_64))
oHTTP.SetRequestHeader("Content-Type", "application/json"); Content-Type
;----------------------------------------------------------------------------
; Send the request
;----------------------------------------------------------------------------
oHTTP.Send()
oHTTP.WaitForResponse()
If oHTTP.Status != 200
If oHTTP.Status == 302
Pause( "Server Attempted Redirect to: ", oHTTP.getResponseHeader("Location"))
EndIf
Status = oHTTP.Status
StatusText = oHTTP.StatusText
headers = oHTTP.GetAllResponseHeaders()
Pause(oHTTP.Status, headers)
EndIf
;----------------------------------------------------------------------------
; Get Response
;----------------------------------------------------------------------------
JSON_Data = oHTTP.ResponseText
exit
;----------------------------------------------------------------------------
:UDFs
#DefineFunction B64GetCookie()
B64Cookie=ArrDimension(256,2) ; ,0 is to B64 ,1 if from B64
ArrInitialize(B64Cookie,-1)
AUPPER=Char2Num("A")
alower=Char2Num("a")
ZEROChr=Char2Num("0")
For xx=0 To 25
B64Cookie[xx,0]=Num2Char(AUPPER+xx)
B64Cookie[xx+26,0]=Num2Char(alower+xx)
Next
For xx=52 To 61
B64Cookie[xx,0]=Num2Char(ZEROChr+xx-52)
Next
B64Cookie[62,0]="+"
B64Cookie[63,0]="/"
For xx=0 To 63
val=Char2Num(B64Cookie[xx,0])
B64Cookie[val,1]=xx
Next
b64Cookie[Char2Num("="),1]=9999 ; flag the = sign
Return(B64Cookie)
#EndFunction
#DefineFunction Base64StringFromClearString(B64Cookie,clearstring)
s=StrLen(clearstring)
bb=BinaryAlloc(s)
BinaryPokeStr(bb,0,clearstring)
b64bb=Base64BBFromClearBB(B64Cookie,bb)
s=BinaryPeekStr(b64bb,0,BinaryEodGet(b64bb))
BinaryFree(bb)
BinaryFree(b64bb)
Return(s)
#EndFunction
#DefineFunction Base64BBFromClearBB(B64Cookie,clearbb)
;clearbb contains bytes to be converted into base64 format
;how many triplets
clearbytes=BinaryEodGet(clearbb)
cleartriplets= clearbytes/3
clearremnants= clearbytes mod 3
;if clearremnants !=0 then cleartriplets=cleartriplets+1
b64quads=ClearTriplets
If clearremnants!=0 Then b64quads=b64quads+1
b64bytes= b64quads*4 + (b64quads/16)*2 + 6; 4bytes per quad + CRLF every 16 quads plus 6 in case I got the math wrong
;Only 16 quads per line allowed
quadlinecount=0
B64BB=BinaryAlloc(b64bytes)
For xx= 1 To cleartriplets
c1 = BinaryPeek(clearbb,(xx-1)*3+0)
c2 = BinaryPeek(clearbb,(xx-1)*3+1)
c3 = BinaryPeek(clearbb,(xx-1)*3+2)
d1 = c1 >> 2
d2 = ( (c1 & 3) << 4) | (c2 >> 4)
d3 = ( (c2 & 15) << 2) | (c3 >> 6)
d4 = ( (c3 & 63) )
quad=StrCat(B64Cookie[d1,0],B64Cookie[d2,0],B64Cookie[d3,0],B64Cookie[d4,0])
BinaryPokeStr(b64BB,BinaryEodGet(b64bb),quad)
quadlinecount=quadlinecount+1
If (quadlinecount mod 16)==0 Then BinaryPokeStr(b64BB,BinaryEodGet(b64bb),@CRLF)
Next xx
Switch clearremnants
Case 1
c1=BinaryPeek(clearbb,(cleartriplets)*3+0)
d1 = c1 >> 2
d2 = ( (c1 & 3) << 4)
quad=StrCat(B64Cookie[d1,0],B64Cookie[d2,0],"==")
Continue
Case 2
c1=BinaryPeek(clearbb,(cleartriplets)*3+0)
c2 = BinaryPeek(clearbb,(cleartriplets)*3+1)
d1 = c1 >> 2
d2 = ( (c1 & 3) << 4) | (c2 >> 4)
d3 = ( (c2 & 15) << 2)
quad=StrCat(B64Cookie[d1,0],B64Cookie[d2,0],B64Cookie[d3,0],"=")
Continue
Case 1
Case 2
BinaryPokeStr(b64BB,BinaryEodGet(b64bb),quad)
quadlinecount=quadlinecount+1
If (quadlinecount mod 16)==0 Then BinaryPokeStr(b64BB,BinaryEodGet(b64bb),@CRLF)
EndSwitch
Return(b64BB)
#EndFunction
Return
Having done several similar web queries with returned JSON, the code you posted looks like it should work, but you didn't post the error or return code that was invalid. I have never needed to use a base64 conversion: str_64=Base64StringFromClearString(B64GetCookie(),StrCat(":",apikey)) so I cannot be of any help there. Maybe if others and Tony pitch in things will become clearer. BTW: this is an SSL request and those get tricky./
Hi Stanl,
For :
"StatusText" I get "Bad Request"
"JSON_Data" I get "{"status":400,"error_code":"LARGE_PARAMETER","message":"Request parameter too large: credential-key","id":0}"
I dont know If I need base64 either. Is there a way around it. I am in the blind here.
Thanks
Hil
Why are you converting the key to base64? Did something indicate that should be done? Have you tried it without the base64 encoding?
Jim
Concur with Jim and Stan. Have never encountered a case where it was required to base-64 encode a web services app key. The JSON response indicates that the request parameter is to large which is what happens to a string when it is base-64 encoded, i.e., it becomes longer.
No harm in just trying
oHTTP.SetRequestHeader("Authorization",apikey)
can't find 'Basic' in any of the samples for access in their doscs.
[EDIT]
Found it in the tech database, it was specific to a particular URL.
Stanl, Did you mean like this....
I get an error on the last line "1298: COM: Error code not recognized"
Invest_ID = "5166xxxx"
cURL = 'https://api.lendingclub.com/api/investor/v1/accounts/%Invest_ID%/availablecash'
apikey = 'GVsZuDKATPRlsajFiBCxxxxx'
oHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
oHTTP.SetRequestHeader("Authorization",apikey)
exit
The exact requirements vary from vendor to vendor but here are a few lines from a working script used in a production environment.
;; Error handling removed for readability.
objHttp=ObjectCreate("WinHttp.WinHttpRequest.5.1")
objHttp.SetTimeouts(50000, 50000, 50000, 50000);
objHttp.open("POST",strSquUrl,"False")
strAuth='Bearer ':strAccTok
objHttp.SetRequestHeader("Authorization", strAuth )
objHttp.SetRequestHeader("Accept", "application/json")
objHttp.SetRequestHeader("Content-Type", "application/json")
objHttp.Send(body)
if objHttp.Status != 200
;Blah blah blah error blah blah blah
endif
strResponse=objHttp.responseText
You would need to check your site's documentation carefully to determine what exactly it is expecting.
Quote from: hdsouza on November 20, 2017, 05:45:43 PM
Stanl, Did you mean like this....
I get an error on the last line "1298: COM: Error code not recognized"
Invest_ID = "5166xxxx"
cURL = 'https://api.lendingclub.com/api/investor/v1/accounts/%Invest_ID%/availablecash'
apikey = 'GVsZuDKATPRlsajFiBCxxxxx'
oHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
oHTTP.SetRequestHeader("Authorization",apikey)
exit
I meant just re-write the line in your original script. What you posted [above] should fail. Since you received a Json return in the original script we were just suggesting you remove the base64 stuff.
Thanks TD.
I took your sample code and applied it to my script.
We may be a little closer. Now I get "StatusText" = "Unauthorized"
I believe strAuth has the incorrect format.
Verified that my api key is correct.
Any ideas?
Invest_ID = "5166XXXX"
cURL = 'https://api.lendingclub.com/api/investor/v1/accounts/%Invest_ID%/availablecash'
apikey = 'GVsZuDKATPRlsaXXXXXXXXXXX'
oHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
oHttp.SetTimeouts(50000, 50000, 50000, 50000);
oHttp.open("POST",cURL,"False")
strAuth='Bearer ':apikey
oHttp.SetRequestHeader("Authorization", strAuth )
oHttp.SetRequestHeader("Accept", "application/json")
oHttp.SetRequestHeader("Content-Type", "application/json")
oHttp.Send()
if oHttp.Status != 200
If oHTTP.Status == 302
Pause( "Server Attempted Redirect to: ", oHTTP.getResponseHeader("Location"))
EndIf
Status = oHTTP.Status
StatusText = oHTTP.StatusText
headers = oHTTP.GetAllResponseHeaders()
Pause(oHTTP.Status, headers)
endif
strResponse=oHttp.responseText
exit
Also if it will help here is the Equivalent WORKING PHP code:
<?php
$Invest_ID = "5166XXXX";
$apikey = 'GVsZuDKATPRlsaXXXXXXXXXXX';
define("DEBUG_LENDING_API", false);
$balance = get_balance($Invest_ID, $apikey);
echo $balance;
function get_balance($Invest_ID, $apikey){
$balance_url = "https://api.lendingclub.com/api/investor/v1/accounts/$Invest_ID/availablecash";
// to get balance call this
return call_curl($balance_url, $apikey);
}
function call_curl($url, $apikey, $post = "0"){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt ( $ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9) Gecko/2008052906 Firefox/3.0" );
if($post != "0"){
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, $post);
}
curl_setopt ( $ch, CURLOPT_AUTOREFERER, true );
curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, true );
$headers = array();
$headers[] = "Authorization: $apikey";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$server_output = curl_exec ($ch);
$info = curl_getinfo($ch);
curl_close ($ch);
if(DEBUG_LENDING_API == true){
return array("data" => $server_output, "response" => $info);
}else{
return json_decode($server_output);
}
}
?>
Just looking at your last post. There is no 'Bearer' in the PHP code and I don't believe the concatenation is necessary. Also, you probably should be using a GET not a POST (as was Tony's example - and the PHP code appears to use GET)
You were right about the GET and not needing the concatenation. That did the trick.
Thanks Stan and Tony !!!!
(This is just the first step and have several other things to do, so i may have a few more questions)