Problem with Open method of MSXML2.ServerXMLHTTP.6.0 PATCH request - vba

I have been using MSXML2.XMLHTTP.6.0 successfully with my Excel VBA script for a couple years, for both GET and POST requests. The POST request looks like:
Dim zipService as Object
Dim Query As String
Dim Body As String
Set zipService = CreateObject("MSXML2.XMLHTTP.6.0")
Query = "https://10.xxx.xxx.xxx:443/api/rest/v1/bulk/thresholdRules/"
zipService.Open "POST", Query, False
zipService.setRequestHeader "Authorization", "Basic " & gsUserIDPW
zipService.setRequestHeader "Content-Type", "application/json"
zipService.setRequestHeader "Accept", "application/xml"
Body = "Body of the request"
zipService.send (sBody)
Now I need to need to make a PATCH request to a new REST call for the same API. I have tested the PATCH REST call in Postman, and it works successfully. Using PUT in Postman also works. However, in Excel, when I try to do the Open call using PATCH (or PUT), the Open call fails with a -2147012891 error.
Any suggestions? Are PATCH and PUT allowed with the Open method? Are there other parameters I have to specify? All the code examples I find online are always GET and POST requests.

Related

Updating stock on magento 2.1 using REST API - Error {"message": "Request does not match any route."}

I am trying to get a stock item quantity updated on a magento 2.1 site using REST API.
I am coding in VB.net but I get the error JSON response {"message": "Request does not match any route."}
Dim Access_Token = "XXXXXXXXXXXXX"
Try
Dim VATWebClient = New WebClient()
VATWebClient.Headers(HttpRequestHeader.Accept) = "application/json"
VATWebClient.Headers(HttpRequestHeader.ContentType) = "application/json"
VATWebClient.Headers(HttpRequestHeader.Authorization) = "Authorization Bearer " & Access_Token
Dim Response As String
Response = VATWebClient.UploadString("http://www.xxxxxx.com/rest/V1/products/xxxx/stockItems/1", "{""stockItem"":{""qty"":100}}")
Catch webEx As WebException
Dim errorMessage As String = webEx.Message
Dim errorStack As String = webEx.StackTrace
End Try
I have also tried to setup SoapUI just to test to make sure that I am calling it right and I get the same error.
I read somewhere that the webapi.xml must be updated with the API which is required I am really hoping that's not the case as the host/web developer is not very accessible!
UploadString will create a POST Request, as you can see form the API Docs, this API endpooint is PUT method only.
https://devdocs.magento.com/swagger/index_21.html#!/catalogInventoryStockRegistryV1/catalogInventoryStockRegistryV1UpdateStockItemBySkuPut
I'm not too sure how to change the method in visual basic, but I'm sure it's not too difficult.

Twilio SMS API call not recognizing mediaurls

My goal is to send a text message in VBA with Twilio's API by using WinHttpRequest and a POST call.
I put together a custom call using the WinHttpRequest for a basic SMS message and that worked. I can send text messages just fine.
But then I tried adding the MediaURL to the data, and it ignored the URL (no image attached to SMS). I confirmed the URL was valid by testing it in the Visual Studio project and it was able to send just fine.
I went back and tried sending a test image on twilio's servers and it works. I copied the same image to a server and it won't work.
WORKS
HTTPReq.send ("Body=Hi Brent, Hello From Me!&From=+1XXXXXXXXXX&To=+1XXXXXXXXX&MediaUrl=https://demo.twilio.com/owl.png")
DOESN'T WORK
HTTPReq.send ("Body=Hi Brent, Hello From ME!&From=+1XXXXXXXXXX&To=+1XXXXXXXXXX&MediaURL=https://smarttanktester.com/wp-content/uploads/2018/10/owl.png")
(Phone numbers removed).
I tested with a few more images from their site and they work.
So it appears that URLs external to their server are being ignored. My guess is that I have something configured wrong from my end.
Here is my code.
TargetURL = "https://api.twilio.com/2010-04-01/Accounts/XXX/Messages"
Set HTTPReq = CreateObject("WinHttp.WinHttpRequest.5.1")
HTTPReq.Open "POST", TargetURL, False
HTTPReq.setRequestHeader "Accept", "application/json"
temp = "Basic " & EncodeBase64
HTTPReq.setRequestHeader "Authorization", temp
HTTPReq.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
HTTPReq.send ("Body=Hi Brent, Hello From Me!&From=+1XXXXXXXXXX&To=+1XXXXXXXXXX&MediaURL=https://smarttanktester.com/wp-content/uploads/2018/10/owl.png")
Any help is greatly appreciated.

Can't replicate successful HTTP Request in VBA; Returns 403 Error when made in VBA, but not cURL

This curl request works and gives a 200 response code when made through the windows command line:
curl -v -u user:pass -X GET https://www.website.com/path
When I try to make the same request in VBA, though, I get a 403 error and the response appears empty. I'm using this code:
Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
objHTTP.Open "GET", "https://www.website.com/path", False
objHTTP.SetCredentials "user", "pass", 0
objHTTP.Send
I've made sure the reference to the WinHttpRequest 5.1 library was set via Tools>>References, but I'm no great shakes at VBA and don't know what else I might be doing wrong to recreate the successful curl request in VBA. C# WebRequest but not cURL Gives Error 403 seems to have a similar problem, but the answerer says curl also gives a 403, which isn't the case for me - and in any event, there doesn't seem to be a version of HttpClient for VBA, at least according to the documentation and this other question: VBA using HttpClient to connect to an external REST API.
I use an alternative in Access without any issues.
Dim WinHttp_ As Object
Set WinHttp_ = CreateObject("MSXML2.XMLHTTP")
WinHttp_.Open "GET", <url>, False, <user>, <password>
WinHttp_.Send
If WinHttp_.Status = 200 Then
'do whatever you need through WinHttp_.ResponseBody or WinHttp_.responseText
End If
Set WinHttp_ = Nothing
You may need to check the WinHttp_.ReadyState before checking the WinHttp_.Status.
https://msdn.microsoft.com/en-us/library/hh772834(v=vs.85).aspx
I was able to resolve my issue by switching to MSXML2 and encoding the authorization header in base 64. Not sure why this was necessary, but I'm leaving this here in case some other poor lost soul ends up with the same problem.
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
With objHTTP
.Open "GET", URL, False
.setRequestHeader "Authorization", "Basic " + Base64Encode("user:pass")
.setRequestHeader "Content-Type", "application/json"
.Send Body
End With

HTTP GET with my API

I have a current web site that captures data send via querystring
I would like to repost this data to a different API using HTTP GET and capture the response from that site. Response.Redirect works but can not read the results of that post.
This sample code should get you started. It requests the page from a url with querystring values passed, and stores the response in a variable then response.write's the contents.
Set objXML = Server.CreateObject("MSXML2.ServerXMLHTTP")
objXML.Open "GET", "http://www.test.com/test.asp?var1=val1", false
objXML.Send ""
strResponse = objXML.ResponseText
Response.Write strResponse

VBA XMLHTTP clear authentication?

I am writing a set of VBA macros in which it uses the XMLHTTP object to send asynchronous requests to a server. I am sending Basic Authentication with:
XMLHttpReq.setRequestHeader "Authorization","Basic " & Base64EncodedUserPass
This works great the first time.
But if the user changes their userid/password, even if the code creates a brand new XMLHttpReq object and sets this header to the new information, it logs in to the server as the first user, presumably from cached credentials.
How can I cause the code to "forget" that I have logged in before, and re-authorize?
Edit as requested, the relevant part of the code; it really isn't very complicated:
myURL = "http://my.domain.com/myscript.cgi"
Dim oHttp As New MSXML2.XMLHTTP
oHttp.Open "POST", myURL, False
oHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded'"
oHttp.setRequestHeader "Authorization","Basic " & Base64EncodedUsernamePassword
oHttp.send "PostArg1=PostArg1Value"
Result = oHttp.responseText
These questions have been discussed in many ways due to major browsers different implementations of caching methods.
I will give you what worked for me and then the sources I found on this feature.
The only solution I could came across was to force the browser to not cache the request.
myURL = "http://my.domain.com/myscript.cgi"
Dim oHttp As New MSXML2.XMLHTTP
oHttp.Open "POST", myURL, False
oHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded'"
oHttp.setRequestHeader("Cache-Control", "no-cache");
oHttp.setRequestHeader("Pragma", "no-cache");
oHttp.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
oHttp.setRequestHeader "Authorization","Basic " & Base64EncodedUsernamePassword
oHttp.send "PostArg1=PostArg1Value"
Result = oHttp.responseText
It seems that Cache-Control works on most browsers and Pragma only on Firefox and not IE (don't know why...)
If-Modified-Since is used for IE, since IE uses different settings in his own algorithm to determine whether or not the request should be cached. XMLHttpRequest seem to not be treated as the same as HTTP responses.
Careful : With this code you will need username and password each time a new object is created. Maybe you should create a new object, instantiate it once and then destroy it after use. In between you would have all your requests handled in different functions with only one authentication.
Sources
MSDN setRequestHeader Method
MSDN IXMLHTTPRequest
XMLHTTPREQUEST CACHING TESTS
XMLHttpRequest and Caching