wtorek, 5 listopada 2013

Send SMS message by Mobitex API (HttpWebRequest)

Jedną z podstawowych funkcjonalności niemal każdej aplikacji jest możliwość wysyłania powiadomień mailowych. Coraz częściej zdarza się jednak, że klient chce mieć również możliwość wysyłania krótkich powiadomień tekstowych (tzw. SMS) na telefon komórkowy. Usługę taką w praktyce realizuje się poprzez zewnętrznych partnerów, którzy, w zamian za stosowną opłatę wystawiają nam API, z którym możemy się połączyć. W przeszłości widziałem rozwiązania kilku producentów i... każdy miał na to "swój" sposób (od wystawienia web service, poprzez web request z parametrami wiadomości przesłanymi poprzez URL, na wysyłaniu specjalnie skonstruowanego maila na podaną skrzynkę email ;)).
W takich chwilach jak ta, gdy o tym wspominam zaczynam żałować, że tak późno zacząłem prowadzić mojego bloga ;)

Ale do rzeczy. W tym konkretnym poście opiszę sposób integrowania się z API dostarczonym przez firmę Mobitex. Firma mobitex, wystawia publicznie dostępną specyfikację swojego API (specyfikacja_mt.pdf). Specyfikacja jest krótka, zwięzła i na temat.

W tym konkretnym przypadku, wysyłanie SMS odbywa się poprzez zwykły WebRequest z parametrami przekazanymi w querystringu, a w zamian dostajemy odpowiedź w strumieniu (Stream) za pomocą standardowego WebResponse.

Całość jest całkiem prosta i może być zrealizowana, za pomocą klasy z jedną metodą (co najwyżej należy skonfigurować parametry wedle naszych potrzeb):

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Text;
using System.Web;

namespace sms
{
    public class MobitexApi
    {
        public static List<KeyValuePair<string, string>> SendSms(string number, string text)
        {
            List<KeyValuePair<string, string>> keyValueResponse = new List<KeyValuePair<string, string>>();
            try
            {
                string user = "userName";
                string pass = "passInMD51a2bc4f3f52dac6d872ae12";
                string type = "sms";
                string from = "fromUserName";
                string ext_id = "1234";
                string encodedText = HttpUtility.HtmlEncode(text);

                string requestStringUrl = string.Format("https://api.mobitex.pl/sms.php?user={0}&pass={1}&type={2}&number={3}&text={4}&from={5}&ext_id={6}",
                    user, pass, type, number, encodedText, from, ext_id);

                HttpWebRequest HttpWReq = (HttpWebRequest)WebRequest.Create(requestStringUrl);
                //handle error code: ssl_error_bad_cert_domain
                HttpWReq.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(
                delegate
                {
                    return true;
                });
                HttpWebResponse HttpWResp = (HttpWebResponse)HttpWReq.GetResponse();

                Stream response = HttpWResp.GetResponseStream();
                StreamReader reader = new StreamReader(response);
                string responseString = reader.ReadToEnd();
                HttpWResp.Close();

                var respStringTable = responseString.Split(',');

                for (int i = 0; i < respStringTable.Length; i++)
                {
                    string keyValue = respStringTable[i];
                    if (!string.IsNullOrEmpty(keyValue))
                    {
                        string key = keyValue.Substring(0, keyValue.IndexOf(':'));
                        string value = keyValue.Substring(keyValue.IndexOf(": ") + 1);

                        keyValueResponse.Add(new KeyValuePair<string, string>(key, value));
                    }
                }
            }
            catch (Exception ex)
            {
                //TODO:
                //Error handling in here (for example NLog)
            }
            return keyValueResponse;
        }
    }
}
Całość rozwiązania sprowadza się, do utworzenia odpowiedniego querystringa, w którym przekazujemy wszystkie interesujące nas parametry (patrz dokumentacja), a nast. tworzymy web request. Przed wykonaniem dodajemy obsługę eventu "ServerCertificateValidationCallback". Jest to spowodowane tym, że mobitex posiada nieprawidłowy certyfikat bezpieczeństwa i w trakcie wykonywania httpWebRequest dostajemy pytanie czy jesteśmy tego świadomi i mimo to chcemy kontynuować naszą akcję. Po wszystkim, dostajemy odpowiedź z mobitexu, która wyglada mniej więcej tak:
Status: 002, Id: 03a72a49fb9595f3737bc4a2519ff283, Number: 4860X123456
 więc parsujemy ją do nieco bardziej przyjaznego w obsłudze typu danych, czyli kolekcji obiektów typu "KeyValuePair".

Mobitex posiada też możliwość sprawdzenia stanu konta. Czytając dokumentację techniczną brakuje mi natomiast jakiegoś raportu podsumowywującego wszystkie sms wysłane w danych (sparametryzowanym) okresie czasu z danego konta (gdybym chciał zobaczyć datę, status oraz num. tel na jakie wysłałem wszystkie sms powiedzmy w poprzednim mieś.) i myślę, że w najbliższym czasie im takie pytanie zadam.


p.s. W przypadku korzystania z sieci korporacyjnych, należy się upewnić, aby mieć odblokowany port 443 dla serwera 213.5.10.22.
p.s.2 Uwaga. Nr. tel. w parametrze powinien być w formacie 4860X123456
p.s.3  ServerCertificateValidationCallback dostępny jest dopiero w .NET 4.5

Brak komentarzy:

Prześlij komentarz