How to call an API in visual basic? - excel

I am trying to call an API service in visual basic, and then the idea is to use the jsonparser to pull specific data from this.
I get "empty" response here. When I use Postman it works.
Sub getdata()
Dim ws As Worksheet: Set ws = Worksheets("Datalastcall")
Dim http As Object
Set http = CreateObject("WinHttp.WinHttprequest.5.1")
Url = "https://api.teamtailor.com/v1/jobs?include=user,team-memberships.user,stages&filter%5Bstatus%5D=unlisted"
http.Open "Get", Url, False
http.SetRequestHeader "X-Api-Version", "20161108"
http.SetRequestHeader "Authorization", "Token Token=xxx"
http.Send
httpGET = http.ResponseText
Cells(1, 1) = http.ResponseText

As discussed in the comments it should say token = instead of Token =.

Related

POST api authentication in vba

I am trying to connect excel (through vba) to the "teamleader" api v1, via post calls.
api docs here
I tried some solutions which I have found, regarding post calls in vba, but seem to be getting nowhere.
This is what I have so far:
Sub test2()
Dim url As String
Dim objhttp As Object
Set objhttp = CreateObject("MSXML2.ServerXMLHTTP")
url = "https://app.teamleader.eu/api/helloWorld.php"
With objhttp
.Open "POST", url, False
.setRequestHeader "api_group", "xxx"
.setRequestHeader "api_secret", "xxx"
.send
Debug.Print .responseText
End With
End Sub
This however gives me this response:
{"status":"failed","reason":"Please set api_group."}
Does anyone have any idea how to get this to work?
Turns out I needed the put all the authentication in the url itself, this question can be closed.

How to Send Variables on .SetRequestData on Excel VBA

I'm working on a API integration on my Excel WorkSheet using VBA and I'm trying to send user input on a cell sent to a RequestHeader in order to find a product on the server
I've tried importing the data directly from the sheet onto a string and then sending that string as the value for the header but I can't seem to get it to work. I'm new to this whole VBA stuff so I don't honestly know if that's possible. Here's what I've tried:
Sub GetCompanyInformation()
Dim hReq As Object, JSON As Dictionary
Dim i As Long
Dim var As Variant
Dim ws As Worksheet
Set ws = Sheet1
'create our URL string and pass the user entered information to it
Dim strUrl As String
strUrl = "My API URL Goes Here"
Dim cod As String
cod = ws.[MYCELL]
Set hReq = CreateObject("MSXML2.XMLHTTP")
With hReq
.Open "GET", strUrl, False
.SetRequestHeader "cache-control", "no-cache"
.SetRequestHeader "data_filter", ""
.SetRequestHeader "data", "products"
.SetRequestHeader "data_id", cod
.Send
End With
[...]
It returns me an empty string. However if I send the request with the same number I add on my cell as such:
[...]
Set hReq = CreateObject("MSXML2.XMLHTTP")
With hReq
.Open "GET", strUrl, False
.SetRequestHeader "cache-control", "no-cache"
.SetRequestHeader "data_filter", ""
.SetRequestHeader "data", "products"
.SetRequestHeader "data_id", "1234"
.Send
End With
It Works, and it returns me the data I need. Am I doing something wrong? Can I get the variable data on a Request Header?

VBA HTTP request to API with JSON body returns empty array (MSXML2.XMLHTTP in Excel)

Update: SOLVED --> Look below for answer.
Update:
At the Microsoft docs i can see that when open method is called with Async=false, the response might not return if "the protocol stack times out", however I have not been able to read up on the timeout timers.
https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms931177%28v%3dmsdn.10%29
Not really sure if it's related or not.
I'm trying to retrieve a JSON response object through VersionOne query API.
When i try to read the responseText in VBA I receive an empty array, however the exact same request returns correct data from PostMan. I get an HTTP 200 code response, but no data in the response body.
The reason for doing it in VBA and Excel is that the data needs to be analalyzed in a pre-existing Excel model.
I've tried different auth possibilities, both OAUTH and Basic.
This is the VBA code
Option Explicit
Sub Test_LateBinding()
Dim objRequest As Object
Dim strUrl As String
Dim strResponse As String
Dim body As String
Dim strResponseHeaders As String
Dim allResponseHeader As String
Set objRequest = CreateObject("MSXML2.XMLHTTP")
strUrl = "https://endpoint"
body = " { ""from"": ""Epic"",""select"": []}"
'with basic'
With objRequest
.Open "GET", strUrl, False, "XXXX", "XXXX"
.SetRequestHeader "Content-Type", "application/json"
.Send body
strResponseHeaders = .StatusText
strResponse = .ResponseText
allResponseHeader = .GetAllResponseHeaders
End With
Debug.Print body
Debug.Print allResponseHeader
Debug.Print strResponse
End Sub
This is my console output:
OK
Content-Type: application/json; charset=utf-8
Content-Length: 2
X-Content-Type-Options: nosniff
V1-MemberID: skatteministeriet/120267
Strict-Transport-Security: max-age=31536000; includeSubdomains
X-Robots-Tag: noindex
VersionOne: Ultimate/19.0.3.29; 0
X-Instart-Request-ID: 3912039762705832388:SEN01-NPPRY25:1553377406:0
[]
This is the PostMan response headers:
PostMan response headers
This is the URL and request JSON body:
URL and request body
SOLVED Finally...
So i found the answer.
After re-analyzing the Postman response i found that the JSON response was actually handed as a gzip encoded response. Which is simply not compatible with the MSXML2.XMLHTTP lib.
So to solve the problem all I did was to use the WinHttp.WinHttpRequest.5.1 lib instead, which is basicly newer. No other changes to the code was needed.
So to others out there using MSXML2.XMLHTTP or the WinHTTPserver.6.0 lib, change to the newer library :)
Option Explicit
Sub Test_LateBinding()
Dim objRequest As Object
Dim strUrl As String
Dim strResponse As String
Dim body As String
Dim strResponseHeaders As String
Dim allResponseHeader As String
Set objRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
strUrl = "https://endpoint"
body = " { ""from"": ""Epic"",""select"": []}"
'with basic'
With objRequest
.Open "GET", strUrl, False, "XXXX", "XXXX"
.SetRequestHeader "Content-Type", "application/json"
.Send body
strResponseHeaders = .StatusText
strResponse = .ResponseText
allResponseHeader = .GetAllResponseHeaders
End With
Debug.Print body
Debug.Print allResponseHeader
Debug.Print strResponse
End Sub

Which format of the url is correct while using an api with xml

When I try to access common/example api url with vba (excel), there is no problem.
The required URL is as follows: "hppts://user:password#www.site.com/events/"
When I copy the url in web-browser there is no problem.
But when using VBA is returning an error: "Method of Open object IServerXMLHTTPRequest2 has failed"
Code:
Dim http As Object, str As Variant
Set http = CreateObject("MSXML2.XMLHTTP")
With http
.Open "GET", "https://user:password#www.site.com/events/", False
.send
str = .responseText
End With
x = UBound(str)

Establishing an API session with xmlHttp in VBA

I apologize if my question's title is incorrect - I'm used to the idea of PHP sessions with APIs.
I'm trying to accomplish the same feat in VBA with the following code:
'Login
strLogin = "https://URL.COM/authenticateUser?login=username&apiKey=password"
Set xmlHttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")
xmlHttp.Open "GET", strLogin
xmlHttp.setRequestHeader "Content-Type", "text/xml"
xmlHttp.send
'Save the response to a string
strReturn = xmlHttp.responseText
'Open URL and get JSON data
strUrl = "https://URL.COM/Search/search?searchTerm=" & Keyword & "&mode=beginwith"
Set xmlHttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")
xmlHttp.Open "GET", strUrl
xmlHttp.setRequestHeader "Content-Type", "text/xml"
xmlHttp.send
'Save the response to a string
strReturn = xmlHttp.responseText
Sheets(1).Cells(20, 2).Value = strReturn
With this API, I need to login first prior to executing any calls that will return data.
My problem is that I cannot determine how to "stay logged in" so that my second call works.
after I login, strReturn is populated with the following string:
{"Status":{"Code":"2","Message":"Authentication Succeeded","Success":"true"}}
However, when I go to utilize strUrl, I get the following message:
{"Status":{"Code":"1","Message":"Invalid User Name Or Password","Success":"false"}}
I have used this code in prior projects where I needed to supply an API key along with the URL for each request to the server - so this obviously worked fine. I'm not sure how to achieve the concept of "establishing a session" though with xmlHttp.
So, to anyone else who runs across this, the simple solution was to remove the following line from the second call:
Set xmlHttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")
By not creating a new object, vba is able to keep and use the cookie from the first login call.
The final code looks like this:
'Login
strLogin = "https://URL.COM/authenticateUser?login=username&apiKey=password"
Set xmlHttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")
xmlHttp.Open "GET", strLogin
xmlHttp.setRequestHeader "Content-Type", "text/xml"
xmlHttp.send
'Save the response to a string
strReturn = xmlHttp.responseText
'Open URL and get JSON data
strUrl = "https://URL.COM/Search/search?searchTerm=" & Keyword & "&mode=beginwith"
xmlHttp.Open "GET", strUrl
xmlHttp.setRequestHeader "Content-Type", "text/xml"
xmlHttp.send
'Save the response to a string
strReturn = xmlHttp.responseText
Sheets(1).Cells(20, 2).Value = strReturn
And the API which requires a login is able to keep the session established.

Resources