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