Professional Applications Programmers/Consultants برمجة واستشارات تطبيقات الإنترنت
Skip Navigation LinksHome » Code Library » Sms

Public general use code classes and xml files that we've compiled and used over the years:

SMS API service support class. Handles sending and recieving SMS messages through the ClickATell.com SMS API Service gateway. Requires subscription.

   1:  using System;
   2:  using System.IO;
   3:  using System.Xml;
   4:  using System.Data;
   5:  using System.Collections;
   6:  using System.Globalization;
   7:  using System.Configuration;
   8:  using System.Net;
   9:  using System.Text;
  10:  using System.Text.RegularExpressions;
  11:  using System.Web;
  12:   
  13:  namespace Ia.Cl.Model
  14:  {
  15:      ////////////////////////////////////////////////////////////////////////////
  16:   
  17:      /// <summary publish="true">
  18:      /// SMS API service support class. Handles sending and recieving SMS messages through the ClickATell.com SMS API Service gateway. Requires subscription.
  19:      /// </summary>
  20:      /// 
  21:      /// <value> 
  22:      /// I have updated the code to use "Send SMS with C#" see http://www.clickatell.com/developers/c.php 2010-02
  23:      /// </value>
  24:      /// 
  25:      /// <remarks> 
  26:      /// Copyright © 2001-2015 Jasem Y. Al-Shamlan (info@ia.com.kw), Internet Applications - Kuwait. All Rights Reserved.
  27:      ///
  28:      /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
  29:      /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
  30:      ///
  31:      /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  32:      /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  33:      /// 
  34:      /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
  35:      /// 
  36:      /// Copyright notice: This notice may not be removed or altered from any source distribution.
  37:      /// </remarks>
  38:      public class Sms
  39:      {
  40:          private static string url;
  41:          private static string apiId, user, password;
  42:   
  43:          ////////////////////////////////////////////////////////////////////////////
  44:   
  45:          /// <summary>
  46:          ///
  47:          /// </summary>
  48:          public Sms() { }
  49:   
  50:          ////////////////////////////////////////////////////////////////////////////
  51:   
  52:          /// <summary>
  53:          ///
  54:          /// </summary>
  55:          public static int Send(string to, string from, string text, out string result)
  56:          {
  57:              // for non-unicode sending on letter is about 160 chars. You need concat value that is at least (chars/160) + 1
  58:              int op;
  59:   
  60:              op = 0;
  61:              result = "";
  62:   
  63:              // unicode = 0, concat = 2;
  64:              op = Send(to, from, text, 0, 2, out result);
  65:   
  66:              return op;
  67:          }
  68:   
  69:          ////////////////////////////////////////////////////////////////////////////
  70:   
  71:          /// <summary>
  72:          ///
  73:          /// </summary>
  74:          public static int SendUtf8(string to, string from, string text, out string result)
  75:          {
  76:              int op;
  77:   
  78:              op = 0;
  79:              result = "";
  80:   
  81:              // unicode = 1 (for Arabic), concat = 2;
  82:              op = Send(to, from, ConvertUtf8ToUnicodeHex(text), 1, 2, out result);
  83:   
  84:              return op;
  85:          }
  86:   
  87:          ////////////////////////////////////////////////////////////////////////////
  88:   
  89:          /// <summary>
  90:          ///
  91:          /// </summary>
  92:          private static int Send(string to, string from, string text, int unicode, int concat, out string result)
  93:          {
  94:              int op;
  95:              string u;
  96:   
  97:              op = 0;
  98:              result = "";
  99:   
 100:              apiId = ConfigurationManager.AppSettings["clickatellHttpApiId"].ToString();
 101:              user = ConfigurationManager.AppSettings["clickatellUser"].ToString();
 102:              password = ConfigurationManager.AppSettings["clickatellPassword"].ToString();
 103:   
 104:              url = "http://api.clickatell.com/http/sendmsg";
 105:   
 106:              // remove all space chars
 107:              to = Regex.Replace(to, @"\s", "");
 108:   
 109:              using (WebClient wc = new WebClient())
 110:              {
 111:                  // check that to is all digits
 112:                  if (Regex.IsMatch(to, @"^\d{8,15}$"))
 113:                  {
 114:                      // remove the leading "00" if they existed
 115:                      to = Regex.Replace(to, "^00", "");
 116:   
 117:                      if (to.Length == 8) // if number is 8 digits we will assume it is from Kuwait and add the country code
 118:                      {
 119:                          // check if number is SMSable
 120:                          to = "965" + to; // this adds the country code to the number
 121:                      }
 122:   
 123:                      wc.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
 124:                      wc.QueryString.Add("user", user);
 125:                      wc.QueryString.Add("password", password);
 126:                      wc.QueryString.Add("api_id", apiId);
 127:                      wc.QueryString.Add("to", to);
 128:                      wc.QueryString.Add("concat", concat.ToString());
 129:                      wc.QueryString.Add("unicode", unicode.ToString());
 130:                      wc.QueryString.Add("text", text);
 131:   
 132:                      using (Stream s = wc.OpenRead(url))
 133:                      {
 134:                          using (StreamReader sr = new StreamReader(s))
 135:                          {
 136:                              u = sr.ReadToEnd();
 137:   
 138:                              if (u.Contains("ERR"))
 139:                              {
 140:                                  result = "SMS could not be sent (" + u + "). ";
 141:                                  op = -1;
 142:                              }
 143:                              else
 144:                              {
 145:                                  result = u;
 146:                                  op = 1;
 147:                              }
 148:   
 149:                              //sr.Close();
 150:                          }
 151:   
 152:                          //s.Close();
 153:                      }
 154:                  }
 155:                  else
 156:                  {
 157:                      result = "Number has non-digit characters or number of characters is not within range. ";
 158:                      op = -1;
 159:                  }
 160:              }
 161:   
 162:              return op;
 163:          }
 164:   
 165:          /*
 166:          ////////////////////////////////////////////////////////////////////////////
 167:  
 168:          /// <summary>
 169:          ///
 170:          /// </summary>
 171:          private static int send_old(string to, string from, string text, out string result)
 172:          {
 173:              int op;
 174:              string response, r1;
 175:  
 176:              op = 0;
 177:              result = r1 = "";
 178:  
 179:              api_id = ConfigurationManager.AppSettings["clickatell_xml_api_id"].ToString();
 180:              user = ConfigurationManager.AppSettings["clickatell_user"].ToString();
 181:              password = ConfigurationManager.AppSettings["clickatell_password"].ToString();
 182:  
 183:              XmlDataDocument d = new XmlDataDocument();
 184:  
 185:              // remove all space chars
 186:              to = Regex.Replace(to, @"\s", "");
 187:  
 188:              // check that to is all digits
 189:              if (Regex.IsMatch(to, @"^\d{8,15}$"))
 190:              {
 191:                  // remove the leading "00" if they existed
 192:                  to = Regex.Replace(to, "^00", "");
 193:  
 194:                  if (to.Length <= 8) // if number is 8 or less digits we will assume it is from Kuwait and add the country code
 195:                  {
 196:                      // check if number is SMSable
 197:  
 198:                      to = "965" + to; // this adds the country code to the number
 199:                  }
 200:  
 201:                  url = "http://api.clickatell.com/xml/xml?data=<clickAPI><sendMsg><api_id>" + api_id + "</api_id><user>" + user + "</user><password>" + password + "</password><concat>" + concat + "</concat><unicode>" + unicode + "</unicode><to>" + to + "</to><text>" + HttpUtility.UrlEncode(text) + "</text><from>" + from + "</from></sendMsg></clickAPI>";
 202:  
 203:                  op = get_page(url, out response, out r1);
 204:  
 205:                  if (op > 0)
 206:                  {
 207:                      try { d.LoadXml(response); }
 208:                      catch (Exception) { result = "SMS could not be sent. Response is not in recognized XML format. "; }
 209:                  }
 210:                  else { result = r1; }
 211:              }
 212:              else { result = "Number has non-digit characters or number of characters is not within range"; op = -1; }
 213:  
 214:              return op;
 215:          }
 216:          */
 217:   
 218:          ////////////////////////////////////////////////////////////////////////////
 219:   
 220:          /// <summary>
 221:          ///
 222:          /// </summary>
 223:          private static string ConvertUtf8ToUnicodeHex(string line)
 224:          {
 225:              // convert a utf8 string to a hex representation of unicode
 226:              UTF8Encoding utf8 = new UTF8Encoding();
 227:   
 228:              // encode the string
 229:              byte[] bytes = utf8.GetBytes(line);
 230:              int count = utf8.GetCharCount(bytes);
 231:   
 232:              Decoder d = Encoding.UTF8.GetDecoder();
 233:              int charCount = d.GetCharCount(bytes, 0, bytes.Length);
 234:              char[] chars = new char[charCount];
 235:              int charsDecodedCount = d.GetChars(bytes, 0, bytes.Length, chars, 0);
 236:   
 237:              line = "";
 238:              foreach (char c in chars) line += ((ushort)c).ToString("X").PadLeft(4, '0');
 239:   
 240:              //result_l.Text += "\n<br><br>ΩΨΘ:03A903A80398";
 241:              return line;
 242:          }
 243:   
 244:          /*
 245:          ////////////////////////////////////////////////////////////////////////////
 246:  
 247:          /// <summary>
 248:          ///
 249:          /// </summary>
 250:          private static int get_page(string url, out string text, out string result)
 251:          {
 252:              int op;
 253:  
 254:              op = 0;
 255:              result = "";
 256:              text = "";
 257:  
 258:              try
 259:              {
 260:                  Uri ourUri = new Uri(url);
 261:                  // Creates an HttpWebRequest for the specified URL. 
 262:                  HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(ourUri);
 263:                  HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
 264:  
 265:                  Stream receiveStream = myHttpWebResponse.GetResponseStream();
 266:                  Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
 267:  
 268:                  // Pipes the stream to a higher level stream reader with the required encoding format. 
 269:                  StreamReader readStream = new StreamReader(receiveStream, encode);
 270:  
 271:                  Char[] read = new Char[256];
 272:                  // Reads 256 characters at a time.    
 273:                  int count = readStream.Read(read, 0, 256);
 274:  
 275:                  while (count > 0)
 276:                  {
 277:                      // Dumps the 256 characters on a string and displays the string to the console.
 278:                      String str = new String(read, 0, count);
 279:                      text += str;
 280:                      count = readStream.Read(read, 0, 256);
 281:                  }
 282:  
 283:                  // Releases the resources of the response.
 284:                  myHttpWebResponse.Close();
 285:  
 286:                  op = 1;
 287:              }
 288:              catch (WebException e)
 289:              {
 290:                  HttpWebResponse response = (HttpWebResponse)e.Response;
 291:                  if (response != null)
 292:                  {
 293:                      if (response.StatusCode == HttpStatusCode.Unauthorized)
 294:                      {
 295:                          string challenge = null;
 296:                          challenge = response.GetResponseHeader("WWW-Authenticate");
 297:                          if (challenge != null) result = "The following challenge was raised by the server: " + challenge;
 298:                      }
 299:                      else result = "The following WebException was raised : " + e.Message;
 300:                  }
 301:                  else result = "Response Received from server was null";
 302:  
 303:                  op = -1;
 304:              }
 305:              catch (Exception e)
 306:              {
 307:                  result = "The following Exception was raised : " + e.Message;
 308:                  op = -1;
 309:              }
 310:  
 311:              return op;
 312:          }
 313:          */
 314:   
 315:          ////////////////////////////////////////////////////////////////////////////
 316:          ////////////////////////////////////////////////////////////////////////////
 317:      }
 318:  }