PDA

View Full Version : Clickatell REST



DaveR
3-Sep-2020, 10:17 AM
Created a new thread with the product spelt correctly so I can find it next time... :cool:

All about sending SMS from Dataflex, but I think my issue is HTTP ignorance. Forgive me, WFH is distracting... especially WFH when I'm moving homes...

I send

GET http://platform.clickatell.com/messages/http/ HTTP/1.1
Accept: application/json
Content-Type: application/json, application/json
api-key: qofdET44RhCfmvP6WEtdUg==
User-Agent: DataFlex
Host: platform.clickatell.com
Content-Length: 52


{"to":"13459164339","message":"Your watch is ready"}



and get


<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
</body>
</html>


then a CONNECT to platform.clickatell.com:443 HTTP/1.0 happens automagically

followed by a 404.

I have peTransferflags set to IfIgnoreRedirectToHttps, as the code derived from Clickatell's CURL example fails with


<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
</body>
</html>


baffled. :confused:

starzen
3-Sep-2020, 11:12 AM
probably requires https. call it as https

have you tried calling it via curl or postman?

DaveR
3-Sep-2020, 11:51 AM
probably requires https. call it as https

have you tried calling it via curl or postman?

The code I'm cribbing from is


var xhr = new XMLHttpRequest();
xhr.open("GET", "https://platform.clickatell.com/messages/http/send?apiKey=qofdET44RhCfmvP6WEtdUg==&to=13459164339&content=Test+message+text", true);


Using a version of Mike P's Resttest I tried https many times and get the 400 error


<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
</body>
</html>

starzen
3-Sep-2020, 11:53 AM
400 is a bad request. looks like the resttest is sent via http not https. are you sure your code is actually sending HTTPS?

you can use fiddler to spy on your calls and compare good and bad calls to see what the difference is

DaveR
3-Sep-2020, 12:05 PM
400 is a bad request. looks like the resttest is sent via http not https. are you sure your code is actually sending HTTPS?

you can use fiddler to spy on your calls and compare good and bad calls to see what the difference is

Fiddler is where I got what I'm showing in this thread. I've been comparing the Clickatell stuff to Namescan which I have working nicely.

I'm going to reduce the code to the minimum, RESTtest is designed to demonstrate options and I need to pare it back to just what I need.

Michael Mullan
3-Sep-2020, 01:06 PM
Dave,

Do share the class you have for this pretty Please?

TIA,

MM

DaveR
3-Sep-2020, 01:44 PM
Dave,

Do share the class you have for this pretty Please?

TIA,

MM

Michael, not a class yet.

Just a butchered* version of Mike Peat's RESTtest.

*butchered ? Hah!

Will get back to this later.

DaveR
3-Sep-2020, 05:47 PM
Finally on the right track though not there yet and a gin & tonic in the pool has my name on it. :cool:

The examples you get when you ask for an API key are out of date and totally different from the text in the 'Developer Archive' where the REST stuff has separate pages, and additional headers. All their docs are a bit broken, with responses from the site giving URLs that give a 404 when selected. A bit of a worry.

Anyway REST docs are at https://archive.clickatell.com/developers/api-docs/rest-overview-of-api-features/ though they have to be read in conjunction with oither chapters I think.

starzen
3-Sep-2020, 07:12 PM
looks like it supports http or https

are you sure your auth header is sent properly? depending on the server and client this may not work if the client doesnt force a send on the first call.

thats why i generally use postman (or curl) test the call. if it works i test the call in DF. if it doesnt you run fiddler record both calls and look for the difference
Could be a header or an auth problem but if you get a call working in curl it shouldnt be hard to figure out whats incorrect

DaveR
4-Sep-2020, 10:11 AM
yes I will be trying that this morning, Postman anyway. As I said the sample code and the developer doc pages are different and I suspect the truth is somewhere in between.

DaveR
4-Sep-2020, 11:13 AM
I've tried every version of the Authorization header that I can think of and still get 401.
GET https://api.clickatell.com/rest/message/ HTTP/1.1
Accept: application/json
Content-Type: application/json
X-Version: 1
Authorization: qofdET44RhCfmvP6WEtdUg==
User-Agent: DataFlex
Host: api.clickatell.com
Content-Length: 73

apikey, bearer no change, using an X-API-Key header instead, no change

{"from":"13459267477","to":"13459164339","content":"Your watch is ready"}

Same for POST. The examples on their site are all over the place and it doesn't help that there seem to be two versions, platform.clickatell.com and api.clickatell.com, with different foldernames under those.

even that "content" item is "text" in some examples :mad:

DaveR
4-Sep-2020, 11:40 AM
I need a look at a working set of headers.

Mike Peat
4-Sep-2020, 11:45 AM
Dave

Does it work with Postman.

Mike

DaveR
4-Sep-2020, 12:06 PM
Nope. Same issue. Always a 401 with the apikey, though as I say I'm convinced I still have a bad header

Chris Spencer
4-Sep-2020, 09:09 PM
Sorry late to this.
Are you having an issue still, I have this working no issues.



The problem I was having was not actually related to http etc, it was a dumb coding issue.

The code in my end_construct is the only header stuff as below. The rest is pretty vanilla




Procedure End_Construct_Object
Integer iVal
String sKey
Reread sysinfo
Move (trim(SYSINFO.SMSKey)) to sKey
Unlock
Set psAuthKey to sKey
Forward Send End_Construct_Object
Get AddHeader 'Authorization' (psAuthKey(Self)) to iVal
End_Procedure

DaveR
5-Sep-2020, 08:41 AM
hmmm, just saw a reply from Clickatell. Have to investigate that. I'll get back to you later.

DaveR
5-Sep-2020, 12:25 PM
mea culpa.

using the HTTP api key with the REST URL. How infuriating. The Docs on the website are actually pretty clear if you can follow the somewhat circuitous route to the right pages.

Edgar H. Peņa C.
9-Sep-2020, 07:07 AM
Daver:

With this function I send messages, I have not tested it for wattsApp.

if you complete it, let me know




Function TestClickAtell Global String sKey String sCelularDestino String sMensaje Integer iCanal Returns Boolean // 0:SMS, 1:WATTAPSS
Handle hoHttp
Boolean iSuccess
Variant vJson
Handle hoJson
Variant vResp
Handle hoResp
Variant vSbResponseBody
Handle hoSbResponseBody
Handle hoJResp
Integer iRespStatusCode
String sErrorCode
String sError
String sErrorDescription
Integer i
Integer iCount_i
String sApiMessageId
Boolean iAccepted bChilKatUnlock
String sV_to
String sTemp1
Boolean bTemp1

// This example assumes the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.

Get ChilkatDesbloqueo to bChilKatUnlock

Get Create (RefClass(cComChilkatHttp)) To hoHttp
If (Not(IsComObjectCreated(hoHttp))) Begin
Send CreateComObject of hoHttp
End



Get Create (RefClass(cComChilkatJsonObject)) To hoJson
If (Not(IsComObjectCreated(hoJson))) Begin
Send CreateComObject of hoJson
End
If (iCanal=0) Begin
Get ComUpdateString of hoJson "content" sMensaje to iSuccess
Get ComUpdateString of hoJson "to[0]" sCelularDestino to iSuccess
END


Send ComSetRequestHeader to hoHttp "Authorization" sKey
Send ComSetRequestHeader To hoHttp "Accept" "application/json"
Send ComSetRequestHeader To hoHttp "Content-Type" "application/json"

Get pvComObject of hoJson to vJson
IF (iCanal=0) Get ComPostJson3 Of hoHttp "https://platform.clickatell.com/messages" "application/json" vJson To vResp
IF (iCanal=1) Get ComPostJson2 Of hoHttp "https://platform.clickatell.com/v1/message" "application/json" sMensaje To vResp
If (IsComObject(vResp)) Begin
Get Create (RefClass(cComChilkatHttpResponse)) To hoResp
Set pvComObject Of hoResp To vResp
End
Get ComLastMethodSuccess Of hoHttp To bTemp1
If (bTemp1 = False) Begin
Get ComLastErrorText Of hoHttp To sTemp1
Showln sTemp1
Procedure_Return
End

Get Create (RefClass(cComChilkatStringBuilder)) To hoSbResponseBody
If (Not(IsComObjectCreated(hoSbResponseBody))) Begin
Send CreateComObject of hoSbResponseBody
End
Get pvComObject of hoSbResponseBody to vSbResponseBody
Get ComGetBodySb Of hoResp vSbResponseBody To iSuccess
Get Create (RefClass(cComChilkatJsonObject)) To hoJResp
If (Not(IsComObjectCreated(hoJResp))) Begin
Send CreateComObject of hoJResp
End
Get pvComObject of hoSbResponseBody to vSbResponseBody
Get ComLoadSb Of hoJResp vSbResponseBody To iSuccess
Set ComEmitCompact Of hoJResp To False


Get ComEmit of hoJResp to sTemp1


Get ComStatusCode Of hoResp To iRespStatusCode

If (iRespStatusCode >= 400) Begin
Showln "Response Header:"
Get ComHeader Of hoResp To sTemp1
Showln sTemp1
Showln "Failed."
Send Destroy of hoResp
Function_Return False
End

Send Destroy of hoResp

Function_Return True



Get ComStringOf Of hoJResp "errorCode" To sErrorCode
Get ComStringOf Of hoJResp "error" To sError
Get ComStringOf Of hoJResp "errorDescription" To sErrorDescription
Move 0 To i
Get ComSizeOfArray Of hoJResp "messages" To iCount_i
While (i < iCount_i)
Set ComI Of hoJResp To i
Get ComStringOf Of hoJResp "messages[i].apiMessageId" To sApiMessageId
Get ComBoolOf Of hoJResp "messages[i].accepted" To iAccepted
Get ComStringOf Of hoJResp "messages[i].to" To sV_to
Get ComStringOf Of hoJResp "messages[i].errorCode" To sErrorCode
Get ComStringOf Of hoJResp "messages[i].error" To sError
Get ComStringOf Of hoJResp "messages[i].errorDescription" To sErrorDescription
Move (i + 1) to i
Loop


Function_Return False
End_Function



Edgar

DaveR
9-Sep-2020, 08:34 AM
Edgar,

As I said I cracked it, once I'd sorted out the difference between their old API and the new one it was pretty straightforward. The last (?) hurdle is getting a 'from' phone number working in Cayman as they claim they don't allow it so won't answer questions :cool:.

Not tested much yet with foreign numbers but Cayman ones are 95% of the target (99.999999% during COVID).

I didn't do a class (yet) as I have two services in the same program and am early days on the user side of both requirements.

DaveR
9-Sep-2020, 08:37 AM
Dave,

Do share the class you have for this pretty Please?

TIA,

MM

Didn't do a subclass class yet, do you want the code?