HTTP request to sharepoint site - excel

I'm trying to see if a file exists on sharepoint. For this is use below code. If I use "MSXML2.XMLHTTP.6.0" then I get an access denied error.
With "MSXML2.ServerXMLHTTP.6.0" the oHttpRequest.Status returns always 200 even if the file is not there. The URL gets passsed with URLStr and looks something like this:
"https://company.sharepoint.com/sites/abc/def/xyz.xlsx"
If I open the file with other VBA code the first example runs fine (maybe because authentication was done somehow?). Online many posts said to add "s" to "http" -> "https", but it changed nothing.
The idea is that the workbook checks online if it is the latest version and if not informs the user. Maybe there is a better way to do this?
Public Function checkversionmethod2(URLStr As String) As Boolean
Dim oHttpRequest As Object
'Set oHttpRequest = CreateObject("MSXML2.XMLHTTP.6.0") 'authentication issue
Set oHttpRequest = CreateObject("MSXML2.ServerXMLHTTP.6.0") 'always return 200
With oHttpRequest
.Open "HEAD", URLStr, False ', [UserName], [Password]
.setRequestHeader "Cache-Control", "no-cache"
.setRequestHeader "Pragma", "no-cache"
.send
End With
If oHttpRequest.Status = 200 Then
fileexists = 1
Else
fileexists = 3
End If
Set oHttpRequest = Nothing
End Function

Related

The waitForResponse method doesn't work with XMLHTTP

I have a code in which I declared a variable like that
Dim http As New XMLHTTP60
then in the code, I used this line
http.Open "POST", urlexample, False
http.Send strArg
How can I use the waitForResponse to wait for the server to respond to the request. I tried looping like that after the .Send statement
While http.ReadyState <> 4: DoEvents: Wend
But this works sometimes well and sometimes doesn't return anything.
Looking through object model seems that this method is not available through MSXML2.XMLHTTP60 but is with WinHttp.WinHttpRequest. The latter does not have a ReadyState property however.
You'll need to investigate the default timeout and see if you need SetTimeOuts on WinHttp object to obtain longer times.
Option Explicit
Public Sub testing()
Dim http As winHttp.WinHttpRequest
Set http = New winHttp.WinHttpRequest
With http
'.SetTimeouts ........
.Open "GET", "http://books.toscrape.com/", True
.setRequestHeader "User-Agent", "Mozilla/5.0"
.send
.waitForResponse 1000
End With
Stop
End Sub
N.B. Your request will not be async if the async arg is set to FALSE in the .Open
Interesting reading: https://github.com/VBA-tools/VBA-Web/issues/337
Seems Tim Hall's VBA-Web would be a nice pre-packaged way to go about this.
WinHTTP

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.

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

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.

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.

CreateObject("MSXML2.ServerXMLHTTP.6.0")

I'm currently facing some issues with creation of CreateObject("MSXML2.ServerXMLHTTP.6.0") object.
Public Function PrepareHttpRequest(Request As RestRequest, TimeoutMS As Long, _
Optional UseAsync As Boolean = False) As Object
Dim Http As Object
**Set Http = CreateObject("MSXML2.ServerXMLHTTP.6.0")**
' Set timeouts
Http.setTimeouts TimeoutMS, TimeoutMS, TimeoutMS, TimeoutMS
' Add general headers to request
Request.AddHeader "User-Agent", UserAgent
Request.AddHeader "Content-Type", Request.ContentType
If Request.IncludeContentLength Then
Request.AddHeader "Content-Length", Request.ContentLength
Else
If Request.Headers.Exists("Content-Length") Then
Request.Headers.Remove "Content-Length"
End If
End If
' Pass http to request and setup onreadystatechange
If UseAsync Then
Set Request.HttpRequest = Http
Http.onreadystatechange = Request
End If
Set PrepareHttpRequest = Http
End Function
The above code is working fine for some users but its failing in some users machine. Can anyone please provide necessary changes to fix issue.
Try:
Set objXML = Server.CreateObject("MSXML2.ServerXMLHTTP")
Otherwise put an On Error Goto ln and tell us what the Err.Description is and google it
Run ProcessMonitor to see where its trying to find the DLL and regsvr32 the msxml6.dll

Resources