VBA httpWebRequest with Credentials - excel

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.

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

Calling an API from Excel Macro to POST data using WinHTTPRequest

I am trying to call an API for sending SMS from Excel Macro.
I tried sending using MSXML2.XMLHTTP it sends SMS successfully from my system, But in client's system it is giving error "An error occurred in the secure channel support".
Set httpObject = CreateObject("MSXML2.XMLHTTP")
sURL = "https://api.xxx.in/send/?apiKey=" & sAPIKey & "&sender=" & sSenderID & "&numbers=" & sMobileNo & "&message=" & sMsg
httpObject.Open "POST", sURL, False
httpObject.Send
sGetResult = httpObject.ResponseText
I tried second method like
Set winHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
myURL = "https://api.xxx.in/send/?"
postData = "apikey=" & sAPIKey & "&message=" & sMsg & "&numbers=" & sMobileNo & "&sender=" & sSenderID
winHttpReq.Open "POST", myURL, False
winHttpReq.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
winHttpReq.Send (postData)
SendSMS = winHttpReq.ResponseText
On line winHttpReq.SetRequestHeader it gives error "An error occured in the secure channel support" on my system. As per suggestions I enabled all TLS versions but still the same error. I am using Win 7 and excel 6.5.Somewhere i read to add the ciphers to the servers. I have no idea how to do that. I guess issue is somewhere else.
Can anyone pls help. I will prefer to use the 2nd method.
Thanks

Download .csv from an indirect Asana link

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"

Post Request to CoinFloor API in Excel VBA not working - Getting 415 Unsupported Media Type Error

I am trying to access CoinFloor BIST API through Excel VBA or Access VBA. I am able to make get requests (like ticker) successfully. But when I try a post request (like get balance) I get an error "415 Unsupported Media Type". I looked through many threads for this error and all are pointing to the content-type and accept headers, but I was not able to get it working.
The code is pasted below.
Function BalancePostRequest()
Dim auth, URL, data
Dim cred As Credentials
Dim Lib As New jsonlib
cred = getCredentials
auth = cred.userId & "/" & cred.API_Key & ":" & cred.passphrase
URL = "https://webapi.coinfloor.co.uk:8090/bist/XBT/GBP/balance/"
Dim xhr: Set xhr = CreateObject("MSXML2.XMLHTTP")
With xhr
.Open "POST", URL, False
.setRequestHeader "Content-Type", "application/json"
.setRequestHeader "Accept", "application/json"
.setRequestHeader "Authorization", "Basic " + Base64Encode(auth)
End With
xhr.send data
If xhr.Status <> 200 Then
Err.Raise vbObjectError + 1000, "Util.SendRequest", "Status code: " & xhr.Status & " " & xhr.statusText & ". Response was: " & xhr.responseText
End If
Set xhr = Nothing
End Function

DocuSign VBA Error 400 errorCode: ENVELOPE_IS_INCOMPLETE

You help would be greatly appreciated to understand what then .setRequestHeader setting should be for this error.
Public Sub SignatureReq()
Dim httpRequest As MSXML2.XMLHTTP60
' defined request and result variables
Set httpRequest = New XMLHTTP60
' define the new URL for the signature request using the Base URL returned aboved appended with '/envelopes'
Dim sigURL As String
sigURL = URLBase & "/envelopes"
' currently sig URL is 'https://demo.docusign.net/restapi/v2/accounts/[account number]'
Dim Body As String
Body = "<envelopeDefinition xmlns=\" & Chr(34) & "http://www.docusign.com/restapi\" & Chr(34) & ">" + _
"<accountId>MyAccountID</accountId>" + _
"<status>sent</status>" + _
"<emailSubject>DocuSign API Call - Signature request from template</emailSubject>" + _
"<templateId>MyTemplateID</templateId>" + _
"<templateRoles>" + _
"<templateRole>" + _
"<name>Ronco</name>" + _
"<email>rolsen#myemail.com</email>" + _
"<roleName>Rono</roleName>" + _
"</templateRole>" + _
"</templateRoles>" + _
"</envelopeDefinition>"
Debug.Print Body
httpRequest.Open "POST", sigURL, False
httpRequest.setRequestHeader Body, "application/xml"
httpRequest.setRequestHeader "X-DocuSign-Authentication", Author
'httpRequest.setRequestHeader "Accept", "application/xml"
httpRequest.setRequestHeader "Content-Type", "multipart/form-data"
'httpRequest.setRequestHeader "Content-Type", "application/xml"
httpRequest.send
Debug.Print httpRequest.Status, "A"
Debug.Print httpRequest.statusText, "B"
Debug.Print httpRequest.responseText, "C"
Exit Sub
The response message is below. I understand the error is coming from the .setRequestHeader not being set correctly. Where can I find how the header and values are needed to be set for each .setRequestHeader that DocuSign will accept?
400 Bad Request { "errorCode":
"ENVELOPE_IS_INCOMPLETE", "message": "The Envelope is not Complete.
A Complete Envelope Requires Documents, Recipients, Tabs, and a
Subject Line. Content-Type does not contain boundary parameter." }
When sending a signature request from a Template the Content-Type for the API call needs to be set to either application/json or application/xml. It looks like you've currently got that commented out and are sending a multipart/form-data request. Comment that line out and add back in:
httpRequest.setRequestHeader "Content-Type", "application/xml"
If that doesn't work or you've already tried that I recommend enabling Request Logging through your developer account Preferences and examining the raw request that's being set to make sure your code is generating what you expect.

Resources