Download .csv from an indirect Asana link - excel

This code creates a download but not of the linked file as it is not direct. When I open the .csv file it downloads, it appears to be the data from the redirect, not the file linked to the redirect.
This is the code:
Sub Asana()
Dim myURL As String
myURL = "https://app.asana.com/-/csv?id=955497629707333"
Dim HttpReq As Object
Set HttpReq = CreateObject("Microsoft.XMLHTTP")
HttpReq.Open "GET", myURL, False, "username", "password"
HttpReq.send
myURL = HttpReq.responseBody
If HttpReq.Status = 200 Then
Set oStrm = CreateObject("ADODB.Stream")
oStrm.Open
oStrm.Type = 1
oStrm.Write HttpReq.responseBody
oStrm.SaveToFile ThisWorkbook.Path & "\" & "SER_Backlog_BRCC.csv", 2 ' 1 = no overwrite, 2 = overwrite
oStrm.Close
End If
End Sub
It should be a spreadsheet copy of the data on the page, but it comes out with data in a spreadsheet of the website and not the linked .csv file you would get, if done manually.
Should be this:
.

I guess, you have an authorization problem, as user/password is not supported by Asana.
You need a Personal Access Token, which has to be set in your request header.
Please replace this line
'Set HttpReq = CreateObject("Microsoft.XMLHTTP")
Set HttpReq = CreateObject("MSXML2.XMLHTTP")
and that line:
'HttpReq.Open "GET", myURL, False, "username", "password"
HttpReq.Open "GET", myURL, False
HttpReq.setRequestHeader "Authorization", "Bearer " & "your Asana token here"

Related

VBA upload of file to SharePoint using REST API (download already implemented in example)

I have implemented a Sharepoint API connect/authorize/download functionality in an Excel workbook using VBA - see my implementation snippet below:
base_url = "SP URL/_api/web/"
end_url = "GetFileByServerRelativeUrl('" & endpoint_url
url = base_url & end_url & filepath & "')/$value"
HttpRequest.Open "GET", url
HttpRequest.setRequestHeader "Authorization", "Bearer " & auth_token
HttpRequest.Send
sresult = HttpRequest.responseText
sObject = HttpRequest.responseBody
filepath = Replace(filepath, "%20", " ")
filestring = Replace(filestring, "%20", " ")
'MsgBox HttpRequest.Status
If HttpRequest.Status = 200 Then
'MsgBox HttpRequest.responseBody
Set MyStream = CreateObject("ADODB.Stream")
MyStream.Open
MyStream.Type = 1
MyStream.Write HttpRequest.responseBody
MyStream.SaveToFile filestring, 2
MyStream.Close
Else
MsgBox HttpRequest.Status
MsgBox "Error - Connection to server failed"
End If
I am struggling with how to adapt this for an upload use case.
From reading the SP API docs I can see that I need to adjust the url endpoint to /GetFolderByServerRelativeUrl('/Library Name/Folder Name')/Files/add(url='example.txt',overwrite=true)
I am however unsure on the adaptation of the HttpRequest part, is it as simple as changing the `HttpRequest.Open "GET", url' to 'HttpRequest.Open "SEND", url' and then alterating the below part?
Set MyStream = CreateObject("ADODB.Stream")
MyStream.Open
MyStream.Type = 1
MyStream.Write HttpRequest.responseBody
MyStream.SaveToFile filestring, 2
MyStream.Close
I've been at this for a few hours now, have tried to rewrite the MyStream part of the script but I am really unfamiliar with constructing this type of upload request.
Have attempted to write a SEND version of the function but am unclear on the full scope of changes I need to make.
For upload use .LoadFromFile and then .read on the ADO stream.
' read file as binary
Dim ado As Object
Set ado = CreateObject("ADODB.Stream")
With ado
.Type = 1 'binary
.Open
.LoadFromFile filepath & filename
.Position = 0
End With
' request
Dim client As Object
Set client = CreateObject("MSXML2.XMLHTTP.6.0")
With client
.Open "POST", Url, False
.setRequestHeader "Authorization", "Bearer " & AUTH_TOKEN
.send ado.read
ado.Close
Debug.Print .responseText
If .Status = 200 Then '200 = OK
MsgBox ("Upload completed successfully")
Else
MsgBox .Status & ": " & .statusText
End If
End With

POST request error 403 Microsoft graph from Excel VBA

I am trying to create folder on sharepoint site with Microsoft graph from Excel VBA, code working on some endpoints but on some it return response error 403. On App permission side, everything looks fine and all permissions are granted. Please look at code below:
Sub create_folder()
Dim http As New MSXML2.XMLHTTP60
Dim url As String
access_token = "tokentokentoken"
url = "https://graph.microsoft.com/v1.0/drives/{drive-id}/items/"
http.Open "POST", url, False
http.setRequestHeader "application", "x-www-form-urlencoded"
http.setRequestHeader "Content-Type", "application/json;odata=verbose"
http.setRequestHeader "Authorization", "Bearer " & access_token
http.send "{""name"": ""New Folder"", ""folder"": {}}"
If http.Status = 200 Then
MsgBox ("OK")
End If
Set XMLHTTP = Nothing
End Sub

VBA httpWebRequest with Credentials

I need to get some data from a cloud service.
This is my code so far:
Option Explicit
Sub Test()
Call GetHTTPResult("https://venice.unit4.com/WebConnect/api/ZZKlesserRob/2017/Balance/GetBalance?AccountNumber=604&BeginMonth=1&EndMonth=1", "username", "password")
End Sub
Function GetHTTPResult(sURL As String, Optional username As String, Optional password As String) As String
Dim XMLHTTP As Object, sResult As String
Set XMLHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
username = "dummy"
password = "dummypass"
XMLHTTP.Open "GET", sURL, False
XMLHTTP.setRequestHeader "Authorization", "Basic" & Base64Encode("username" & ":" & "password")
XMLHTTP.Send
Debug.Print "Status: " & XMLHTTP.Status & " - " & XMLHTTP.StatusText
sResult = XMLHTTP.ResponseText
GetHTTPResult = sResult
Set XMLHTTP = Nothing
End Function
Without the credentials it gives me the "401 - Unauthorized" -response, which is good, I suppose.
However I do have the necessary credentials at my disposal but I can't seem to fix the problem posed by the Base64 encoding.
What should I do?
Thanks in advance!
From inspecting the docs I believe your are missing a space in your Authorization header:
var request = new XMLHttpRequest();
...
request.setRequestHeader("Accept","application/xml");
request.setRequestHeader("Authorization","Basic " + Base64.encode ("User:Password"));
So your should read:
XMLHTTP.setRequestHeader "Authorization", "Basic " & Base64Encode(username & ":" & password)
Also, you should add an Accept header to the request with application/xml or application/json to specify the format of the requested data.

Not able to open downloaded Excel file from Sharepoint 2013 using Excel VBA

i have tried the following code to download a single Excel file from Sharepoint 2013.
Option Explicit
Sub TxtStream()
Dim myURL As String, DestFile As String, myHeader As String
Dim Usr as string, Pwd as string
Dim oStream As Object
Usr="": Pwd=""
myURL = "https://Server.Name/teams/Forms/AllItems.aspx/MasterFile.xlsx"
DestFile = "C:\Test.xlsx"
Dim WinHttpReq As Object
Set WinHttpReq = CreateObject("MSXML2.XMLHTTP")
'WinHttpReq.Open "HEAD", myURL, False, Usr, Pwd
'WinHttpReq.Send
'myHeader = WinHttpReq.getAllResponseHeaders()
'Debug.Print myHeader
'myHeader = WinHttpReq.getResponseHeader("Content-Disposition")
'Debug.Print myHeader
'myHeader = WinHttpReq.getResponseHeader("Content-Type")
'Debug.Print myHeader
WinHttpReq.Open "GET", myURL, False, Usr, Pwd
WinHttpReq.setRequestHeader "content-type", "application/octet-stream"
WinHttpReq.Send
myURL = WinHttpReq.responsebody
If WinHttpReq.Status = 200 Then
Set oStream = CreateObject("ADODB.Stream")
oStream.Type = 1
oStream.Open
oStream.Position = 0
oStream.Write WinHttpReq.responsebody
oStream.SaveToFile DestFile, 2
oStream.Close
End If
End Sub
It downloads ok, but when i try to open it in Excel 2010, it shoots an error:
Excel cannot open the file Test.xlsx because the file format or file extension is not valid. Verify the file has not been corrupted and the file extension matches the format of the file.
I have checked the Content-Type and it shows as Text/Html;UTF-8. It doesn't show Content-Disposition.
Can someone help as to why the file is not opening?
This is not a full fledged answer, but more like a comment / suggestion as I do not have enough reputation to post comments.
Setting a content-type header in your GET query does not seems to make any difference. We need to check the WinHttpReq.getResponseHeader("Content-Type") sent by the server which in this case seems to be Text/Html;UTF-8.
If you copy paste the URL used in myURL variable to your browser, do you get the "file save as" dialog box?
Better analysis of your requests and responses can be done if you use Fiddler Web Debugger where you can create requests in teh composer and check the responses to finetune your requirements and to see whether any other headers (like cookies, authentications etc) are also required for the file to be downloaded. In this case, you might be getting back a login page (html) because of some authentication issues and not the excel file.
Open the DestFile saved with Notepad.exe to see whether it is actualy an XLSX file (starting with characters PK) or an HTML or other text file.

VBA WinHTTP to download file from password proteced https website

I'm trying to save a file from https password protected site using WinHTTP. Here's the code:
Sub SaveFileFromURL()
Dim FileNum As Long
Dim FileData() As Byte
Dim WHTTP As Object
fileUrl = "https://www.website.com/dir1/dir2/file.xls"
filePath = "C:\myfile.xls"
myuser = "username"
mypass = "password"
Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5.1")
WHTTP.Open "GET", fileUrl, False
WHTTP.SetCredentials myuser, mypass, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
WHTTP.Send
FileData = WHTTP.ResponseBody
Set WHTTP = Nothing
FileNum = FreeFile
Open filePath For Binary Access Write As #FileNum
Put #FileNum, 1, FileData
Close #FileNum
MsgBox "File has been saved!", vbInformation, "Success"
End Sub
The problem is with authentication. The file is being saved but when I open it in Excel it's just the html logon page instead of the actual file. If I copy direct file url and paste it into browser addressbar and I'm not logged in to the webpage the effect is the same. I'm presented with the logon page. Then if I enter my login and password the download window will show up allowing me to save the file.
So I think that SetCredentials part of the code is not working properly cause if I debug.print WHTTP.ResponseBody it's html code instead of the acutal file data.
Is there a way to pass userid and password to the WinHTTP so I could be able to properly save the file?
Here's the page address:
https://sst.msde.state.md.us/
=======================EDIT:========================
So I've played a little bit with it today and I think I'm moving forward. Here's what I got. I Modyfied the code like this:
Sub SaveFileFromURL()
Dim FileNum As Long
Dim FileData() As Byte
Dim WHTTP As Object
fileUrl = "https://www.website.com/dir1/dir2/file.xls"
filePath = "C:\myfile.xls"
myuser = "username"
mypass = "password"
strAuthenticate = "start-url=%2F&user=" & myuser & "&password=" & mypass & "&switch=Log+In"
Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5.1")
WHTTP.Open "POST", fileUrl, False
WHTTP.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
WHTTP.Send strAuthenticate
WHTTP.Open "GET", fileUrl, False
WHTTP.Send
Debug.Print WHTTP.GetAllResponseHeaders()
FileData = WHTTP.ResponseBody
Set WHTTP = Nothing
FileNum = FreeFile
Open filePath For Binary Access Write As #FileNum
Put #FileNum, 1, FileData
Close #FileNum
MsgBox "File has been saved!", vbInformation, "Success"
End Sub
When I Debug.Print WHTTP.GetAllResponseHeaders() I get e.g.:
Accept-Ranges: bytes
Content-Disposition: attachement; filename="xxx"
Content-Length: xxxxxx
Content-Type: application/octet-stream
So I think that authentication worked but I still cannot save the file. When I continue with:
FileData = WHTTP.ResponseBody
Set WHTTP = Nothing
FileNum = FreeFile
Open filePath For Binary Access Write As #FileNum
Put #FileNum, 1, FileData
Close #FileNum
The content of the saved file is the html webpage itself, but not the file.
Did I do the authentication rigth and the problem is with saving the file to the disk or still is there a problem with authentication and that's why I cannot save it? Any clues?
Ok, I did it. Here the code:
Sub SaveFileFromURL()
Dim FileNum As Long
Dim FileData() As Byte
Dim WHTTP As Object
mainUrl = "https://www.website.com/"
fileUrl = "https://www.website.com/dir1/dir2/file.xls"
filePath = "C:\myfile.xls"
myuser = "username"
mypass = "password"
'#David Zemens, I got this by examining webpage code using Chrome, thanks!
strAuthenticate = "start-url=%2F&user=" & myuser & "&password=" & mypass & "&switch=Log+In"
Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5.1")
'I figured out that you have to POST authentication string to the main website address not to the direct file address
WHTTP.Open "POST", mainUrl, False 'WHTTP.Open "POST", fileUrl, False
WHTTP.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
WHTTP.Send strAuthenticate
'Then you have to GET direct file url
WHTTP.Open "GET", fileUrl, False
WHTTP.Send
FileData = WHTTP.ResponseBody
Set WHTTP = Nothing
'Save the file
FileNum = FreeFile
Open filePath For Binary Access Write As #FileNum
Put #FileNum, 1, FileData
Close #FileNum
MsgBox "File has been saved!", vbInformation, "Success"
End Sub
Thanks for all your help.
BTW I've found this posts very useful:
http://www.mrexcel.com/forum/excel-questions/353006-download-file-excel.html
Not understanding why WinHTTP does NOT authenticate certain HTTPS resource
How to parse line by line WinHTTP response: UTF-8 encoded CSV?

Resources