Find report by ID: Request method 'GET' not supported - excel

I'm trying to get data from one report with VBA in Excel.
I get this error message:
{"data":{"message":"Request method 'GET' not supported","code":3000}}
This is my code:
Dim strUrl As String
strUrl = "https://api.clockify.me/api/workspaces/{workspaceId}/reports/{reportId}/"
Set hReq = CreateObject("MSXML2.XMLHTTP")
With hReq
.Open "GET", strUrl, False
.SetRequestHeader "X-api-key", "{api-key}"
.SetRequestHeader "content-type", "application/json"
.Send
End With
'wrap the response in a JSON root tag "data" to count returned objects
Dim response As String
response = "{""data"":" & hReq.ResponseText & "}"
Debug.Print response
Why is the GET method not allowed here?

Looking at the documentation (https://clockify.github.io/clockify_api_docs/#tag-Report)... I don't see a "GET /workspaces/{workspaceId}/reports/{reportId}/" API call - the closes is either GET /reports/{reportId} or PUT/DELETE /workspaces/{workspaceId}/reports/{reportId}, which would explain why you are getting the "GET not allowed", because you can only PUT or DELETE to the /workspaces/{workspaceId}/reports/{reportId}/ endpoint. I'm guessing you want the "GET /reports/{reportId}". Try that.
And I'm guessing this GET /reports/{reportId} isn't under workspaces because reports can be made public... but that's just a guess.

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.

VBA- Unable to update SharePoint 2013 item via REST API

I am attempting to update a SharePoint item via REST API, though I am receiving the below error:
{"odata.error":{"code":"-1, System.InvalidOperationException","message":{"lang":"en-US","value":"The type of data at position 0 is different than the one expected."}}}
I'm not quite sure what is causing this- I have the request type set to JSON, but it does not seem to accept my input. Any help is appreciated :-)
My code:
Sub Work_Damn_You()
Dim oXMLHTTP As Object
Dim sListNameOrGuid As String
Dim sBatchXml As String
Dim sSoapBody As String
Dim sWTF as string
Set oXMLHTTP = CreateObject("MSXML2.XMLHTTP.6.0")
sListNameOrGuid = sListName
With oXMLHTTP
.Open "POST", "http://SPSITE.COM/_api/web/lists/GetByTitle('PAGE')/items(22)", True
.setRequestHeader "X-RequestDigest", testerino
.setRequestHeader "Accept", "application/json;odata=nometadata"
.setRequestHeader "Content-Type", "application/json;odata=verbose"
.setRequestHeader "__metadata", "(""type"":""SP.Data.QATrackerListItem"""
sWTF = """preTestComment""=""Hello"""
.send (sWTF)
Debug.Print (.responseText)
' Check response
If .Status = 200 Then
Debug.Print .Status & " [Happy Days!]"
Else
Debug.Print .Status & " [Sad Days :-(]"
End If
End With
Set oXMLHTTP = Nothing
End Sub
'''

Attempting to set HTML element object by using getElementsByID returns nothing; ID exists in HTML page [duplicate]

Thanks to the help and code from #QHarr I have got the tracking info from Fedex, DHL and Startrack working. I have been trying to use his code and the UPS tracking Web Service Developer Guide and Tracking JSON Developer Guides to get UPS to work as well within Excel. The JSON converter code is from here https://github.com/VBA-tools/VBA-JSON/blob/master/JsonConverter.bas
The code I have tried is as follows
Public Function GetUPSDeliveryDate(ByVal id As String) As String
Dim body As String, json As Object
body = "data={""TrackPackagesRequest"":{""appType"":""WTRK"",""appDeviceType"":""DESKTOP"",""supportHTML"":true,""supportCurrentLocation"":true,""uniqueKey"":"""",""processingParameters"":{},""trackingInfoList"":[{""trackNumberInfo"":{""trackingNumber"":" & Chr$(34) & id & Chr$(34) & ",""trackingQualifier"":"""",""trackingCarrier"":""""}}]}}"
body = body & "&action=trackpackages&locale=en_AU&version=1&format=json"
With CreateObject("MSXML2.XMLHTTP")
.Open "POST", "http://wwwapps.ups.com/WebTracking", False
.setRequestHeader "Referer", "https://www.ups.com/track?loc=en_AU&tracknum=" & id
.setRequestHeader "User-Agent", "Mozilla/5.0"
.setRequestHeader "X-Requested-With", "XMLHttpRequest"
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"
.send body
Set json = JSONConverter.ParseJson(.responseText)
End With
GetUPSDeliveryDate = Format$(json("ResponseStatus")("ShipmentType")(1)("DeliveryDate"), "dddd, mmm dd, yyyy")
End Function
I am not getting any errors in the code per-say, but when I use the =GetUPSDeliveryDate() function I am getting a #VALUE! response instead of the delivered date of 7th May 2019, so I am guessing I have got the following bit wrong
GetUPSDeliveryDate = Format$(json("ResponseStatus")("ShipmentType")(1)("DeliveryDate"), "dddd, mmm dd, yyyy")
I have also tried the following, but no luck.
If json("results")(1)("delivery")("status") = "delivered" Then
GetUPSDeliveryDate = json("results")(1)("checkpoints")(1)("date")
Else
GetUPSDeliveryDate = vbNullString
End If
A sample UPS tracking number is 1Z740YX80140148107
Any help would be greatly appreciated.
Thanks
The following is by mimicking of this UPS tracking site. The json parser used is jsonconverter.bas: Download raw code from here and add to standard module called jsonConverter . You then need to go VBE > Tools > References > Add reference to Microsoft Scripting Runtime.
Option Explicit
Public Sub test()
Debug.Print GetUPSDeliveryDate("1Z740YX80140148107")
End Sub
Public Function GetUPSDeliveryDate(ByVal id As String) As String
Dim body As String, json As Object
body = "{""Locale"":""en_US"",""TrackingNumber"":[""" & id & """]}"
With CreateObject("MSXML2.XMLHTTP")
.Open "POST", "https://www.ups.com/track/api/Track/GetStatus?loc=en_US", False
.setRequestHeader "Referer", "https://www.ups.com/track?loc=en_US&requester=ST/"
.setRequestHeader "User-Agent", "Mozilla/5.0"
.setRequestHeader "DNT", "1"
.setRequestHeader "Content-Type", "application/json"
.setRequestHeader "Accept", "application/json, text/plain, */*"
.send body
Set json = JsonConverter.ParseJson(.responseText)
End With
If json("trackDetails")(1)("packageStatus") = "Delivered" Then
GetUPSDeliveryDate = json("trackDetails")(1)("deliveredDate")
Else
GetUPSDeliveryDate = "Not yet delivered"
End If
End Function
The Tracking Web Service Developer Guide.pdf contains all you need to know to set up using the official tracking API.

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

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