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