Closed matmasr closed 5 years ago
Your request is not a FormUrlEncoded. Note the lack of a form field in the example:
-d '{"content": "Hello world this is a message", "to": ["123456789"]}'
Forms POST like: field1=value&field2=value
You either want WebFormat.PlainText
or WebFormat.Json
for your Request.Format. I don't use the client bits enough to know which will dump the string into the body off-hand.
Thanks for the comment and your help. When I used Webformat.Json
I get so many parsing issues. I will change a send back results. Question though, am I formatting the Phone number(s) key and value correctly ?
So I tested the same code but with Webformat.PlainText
and got the following error
{"error":"HTTP 415 Unsupported Media Type"} {"error":"HTTP 415 Unsupported Media Type"}
So with the Webformat.Json
and having to change Request.Body = ConvertToJson(SmsBody)
to just Set Request.Body = SmsBody
I get the following error
ERROR - WebHelpers.ParseByFormat: 11000, An error occurred during parsing 10001: Error parsing JSON: Can not des ^ Expecting '{' or '[' ERROR - WebHelpers.ParseByFormat: 11000, An error occurred during parsing 10001: Error parsing JSON: Can not des ^ Expecting '{' or '[' Can not deserialize instance of java.lang.String out of START_ARRAY token at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@49b5e7fc; line: 1, column: 32] (through reference chain: com.clickatell.mc2.rs.request.SendMessageRequest["to"]->java.util.HashSet[0])
which was my original error
Try Request.Body = SmsBody
because the client should be doing all the encoding for you based on your Format.
Thanks again .. the errors I got above are with me setting Request.Body = SmsBody
having to use Set Request.Body = SmsBody
to avoid a Run Time error 449 "Argument not optional". I agree with you that the client should be doing all the encoding but then I have that 11000 error
"That 11000 error" is because the server is not returning a JSON object, it is returning an error message:
Can not deserialize instance of java.lang.String out of START_ARRAY token
at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@49b5e7fc; line: 1, column: 32] (through reference chain: com.clickatell.mc2.rs.request.SendMessageRequest["to"]->java.util.HashSet[0])
You can set your response to PlainText (I think) so you can just deal with the raw HTTP bodies while troubleshooting.
Hey that worked ! At least for understanding the error which is now down to
{"error":"HTTP 406 Not Acceptable"} .. so something is not being encoded correctly. Is there something in my code that is obviously wrong ?
To log what is being sent, try WebHelpers.EnableLogging = True
before the request is sent and viewing the logged request in the Immediate Window (ctrl+g or View > Immediate Window). Also, you can view just the formatted request body by setting a breakpoint before the request is sent and running Debug.Print Request.Body
or ? Request.Body
in the Immediate Window to view the body value that will be sent.
Apparently the API is smart enough to know that you're asking for PlainText and it doesn't want to give it to you:
The HyperText Transfer Protocol (HTTP) 406 Not Acceptable client error response code indicates that the server cannot produce a response matching the list of acceptable values defined in the request's proactive content negotiation headers, and that the server is unwilling to supply a default representation.
So you'll have to stick with Request.ResponseFormat = WebFormat.Json
and then write them a nasty letter to support that they aren't returning JSON error messages. :)
Your best bet probably seems to be to set a breakpoint in WebClient class, Execute method on the web_Http.send Request.Body
line and make sure it's writing what you think it should be writing. Using a tool like PostMan can also cut down on all the curl transcribing from command line to code.
Thank you guys so much for your help ... I will try these and see where the gap is ...
So I turned on the debugging and saw the .Body
result and the server response below. The only discrepancy I can see in the parsed JSON code is the double [[ instead of just the single [ where the phone numbers Array. Could this be the reason why the server is rejecting the submission and if so how would I apply the Array to the Body ?
--> Request - 3:02:24 PM POST https://platform.clickatell.com/messages Content-Type: application/json Accept: text/plain Authorization: mysecretttoken I replaced this but it was encoded correctly User-Agent: VBA-Web v4.1.5 (https://github.com/VBA-tools/VBA-Web) Content-Length: 79
{"content":"This is a Test","to":[["123456789","1324567892","13087458852"]]}
<-- Response - 3:02:25 PM 500 Internal Server Error Connection: keep-alive Date: Wed, 19 Dec 2018 21:02:27 GMT Content-Length: 35 Server: nginx Strict-Transport-Security: max-age=31536000; includeSubDomains
{"error":"HTTP 406 Not Acceptable"}
{"error":"HTTP 406 Not Acceptable"}
{"error":"HTTP 406 Not Acceptable"}
{"error":"HTTP 406 Not Acceptable"}
This is the result withRequest.ResponseFormat = WebFormat.Json
which seems to indicate that the double [[ maybe the culprit
--> Request - 3:13:45 PM POST https://platform.clickatell.com/messages Content-Type: application/json Accept: application/json Authorization: mysecrettoken User-Agent: VBA-Web v4.1.5 (https://github.com/VBA-tools/VBA-Web) Content-Length: 79
{"content":"This is a Test","to":[["123456789","1324567892","13087458852"]]}
ERROR - WebHelpers.ParseByFormat: 11000, An error occurred during parsing 10001: Error parsing JSON: Can not des ^ Expecting '{' or '[' ERROR - WebHelpers.ParseByFormat: 11000, An error occurred during parsing 10001: Error parsing JSON: Can not des ^ Expecting '{' or '[' <-- Response - 3:13:46 PM 400 Bad Request Connection: keep-alive Date: Wed, 19 Dec 2018 21:13:47 GMT Content-Length: 308 Content-Type: text/plain Server: nginx Strict-Transport-Security: max-age=31536000; includeSubDomains
Can not deserialize instance of java.lang.String out of START_ARRAY token at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@52955f9f; line: 1, column: 35] (through reference chain: com.clickatell.mc2.rs.request.SendMessageRequest["to"]->java.util.HashSet[0])
Can not deserialize instance of java.lang.String out of START_ARRAY token at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@52955f9f; line: 1,
to":[["123456789","1324567892","13087458852"]]}
This isn't correct.
instead of:
Dim SmsPhones As New Collection
SmsPhones.Add Array("123456789", "1567898793", "52021250215")
...
SmsBody.Add "to", SmsPhones
do this
Dim SmsPhones As New Collection
SmsPhones.Add "123456789"
SmsPhones.Add "1567898793"
SmsPhones.Add "52021250215"
...
SmsBody.Add "to", SmsPhones
You were creating a 2D array.
That was it ! I got the first text messages sent from excel to multiple numbers with one click. knew something simple was causing this .. turns out to be my VBA skills : ) ... Thank you so much for your help ... at least now I know I can parse and communicate with the server ... Both of you are awesome !
I am trying to implement a simple API call to Clickatell REST service to send SMS messages to a group of phone numbers. I tried multiple ways but this is the code that seems to me the closest to what I need but still with errors.
Public Sub SendClickatell()
Dim ClickUrl As String
ClickUrl = "https://platform.clickatell.com/messages"
Dim AlertMessage As String
AlertMessage = "This is a Test"
Dim Client As New WebClient
Client.BaseUrl = ClickUrl
Dim Request As New WebRequest
Request.Method = WebMethod.HttpPost
Request.AddHeader "Content-Type", "application/json"
Request.AddHeader "Accept", "application/json"
Request.AddHeader "Authorization", "mysecerttoken"
Request.Format = WebFormat.FormUrlEncoded
Request.ResponseFormat = WebFormat.Json
Dim SmsPhones As New Collection
SmsPhones.Add Array("123456789", "1567898793", "52021250215")
Dim SmsBody As New Dictionary
SmsBody.Add "content", "Hello World"
SmsBody.Add "to", SmsPhones
Request.Body = ConvertToJson(SmsBody)
Dim Response As WebResponse
Set Response = Client.Execute(Request)
Debug.Print Response.Content
If Not Response.Data Is Nothing Then
Debug.Print ConvertToJson(Response.Data)
End If
End Sub
This is how the REST API should be formatted based on Clickatell API
curl -i \
-X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: mysecerettoken" \
-d '{"content": "Hello world this is a message", "to": ["123456789"]}' \
-s https://platform.clickatell.com/messages
` The error I get seems to be that I am sending something is going to the server but in the wrong format. Here is the error