Clickatell offer a few different ways to integrate your application with their services. Of all the options available, XML seemed to be the most useful, however it gave me a little bit of trouble when I tried to get it working. Namely, this 'fault response':
<?xml version="1.0" ?>
<clickAPI>
<fault>XML error: no element found at line 1</fault>
</clickAPI>
I took my input XML and pasted it into the Clickatell test form and it parsed fine. Some searching on the error revealed a lot of other people also had this issue, however most of the search results I found lead to threads where people had either given up, or simply not followed up with a reply posting once they've solved their issue, and so no solutions were forthcoming. Clickatell don't provide what they refer to as 'Developer Support' and basically shoot down anyone asking for code samples. There are a lot of people posting on the forums asking for help, and all of them are being referred to either useless Knowledge base articles, or being told to go and hire a development company.
The Clickatell API guide contains most of the information that you should need in order to get started, however it's missing a few useful pieces of information. What most people seem to really want (and what I wanted myself) was a small piece of working code to use as a reference point. And so now that I've got my problem fixed, here it is (in it's quick and messy but working state) in the hope that it helps any others out there who are having the same issue:
private void btnSendTestMessage_Click(object sender, EventArgs e)
{
string gatewayUrl = "http://api.clickatell.com/xml/xml";
HttpWebResponse resp = null;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(gatewayUrl);
string inputXml = GenerateXml();
// encode post data and set up the request
// Note: input xml is passed a a parameter named 'data'
string postData = "data=" + inputXml;
byte[] postDataBytes = ConvertStringToByteArray(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postDataBytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(postDataBytes, 0 ,postDataBytes.Length);
requestStream.Close();
// get response and write to console
resp = (HttpWebResponse)request.GetResponse();
StreamReader responseReader = new
StreamReader(resp.GetResponseStream(), Encoding.UTF8);
string theresponse = responseReader.ReadToEnd();
resp.Close();
}
catch(Exception ex)
{
// do something tidy with the exception here!
}
finally
{
if ( resp != null )
{
resp.Close();
}
}
}
// Simple method to convert a string to a Bytearray
public static byte[] ConvertStringToByteArray(string stringToConvert)
{
return (new ASCIIEncoding()).GetBytes(stringToConvert);
}
In my case, it was the encoding that was killing my request. The simple HTTP post example that I used as a starting point used UTF8 encoding. Clickatell doesn't like this, so I modified my example to use ASCII encoding and things started working. Also note that there should be no XML declaration, and that it should be sent through inside a paramater named 'data'. This would be information which might be useful in the API manual, but apparently it's more fun to work it out on your own.
Finally, it's not very complex, but here's the code that I used to Generate my test XML. Included really only for completeness:
// Generates Clickatell standard XML
public static string GenerateClickATellXml(string number, string fromdisplay, string bodytext)
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
XmlTextWriter writer = new XmlTextWriter(sw);
//Write the root element
writer.WriteStartElement("clickAPI");
// write the sendMsg element
writer.WriteStartElement("sendMsg");
//Write sub-elements
writer.WriteElementString("api_id", accountApiId);
writer.WriteElementString("user", accountLogin);
writer.WriteElementString("password", accountPassword);
writer.WriteElementString("to", number);
writer.WriteElementString("text", bodytext);
writer.WriteElementString("from", fromdisplay);
// end the sendMsg element
writer.WriteEndElement();
// end the root element
writer.WriteEndElement();
//Write the XML to file and close the writer
writer.Close();
return sb.ToString();
}
Obviously accountApiId, accountLogin, and accountPassword are all variables which are being populated elsewhere. The above example is the simplest to use for testing purposes, as it authenticates and sends a message all in one post, compared to the other methods which require to you authenticate in order to receive a session id which you then use to send subsequent messages.
So there you have it. Incredibly simple when you look back on it.
Some further links:
Link: Clickatell API guides
Link: TraderSystems: PHP XML Clickatell example
Link: Basic C# HTTP POST Client