Отправка SMS при помощи Delphi

Материал из DRKB


Алгоритм работы приложения для отправки sms достаточно простой. При помощи компонента twebbrowser нужно реализовать отправку данных на веб-сервер сотового оператора, содержащих информацию о телефонном номере, текст сообщения и некоторой служебной информации.

Отправку sms сообщения рассмотрим на примере оператора сотовой связи "Ульяновск- gsm ", позволяющего производить отправку sms сообщений через web- страничку по адресу:

http://sms.smarts-gsm.ru/sms.cgi

Для отправки sms сообщения нужно заполнить поля формы:

  • в поле "Кому" ввести полный телефонный номер, например 78422973421 .
  • в поле "Что" вводится текст сообщения.
  • в списке "Формат" выбирается тип сообщения.

Отправка сообщения инициализируется кнопкой "send >>".

Передаваемая строка на сервер оператора сотовой связи, при заполненном поле "Кому" - 78422973421, полем "Что" - "sms", в формате "Обычный sms" выглядит следующим образом:

to=78422973421&msg=sms&dcs=0 (1)

Разберемся откуда берется эта строка и что она означает. Если рассмотреть html код страницы, то видим следующую картину:

<form method=post action="http://sms.smarts-gsm.ru/sms.cgi"> 
<input type=text name=to value="" size=15>[номер абонента] 
<textarea name=msg cols=30 rows=5> </textarea> 
<select name=dcs> 
<option value=0>Обычный sms 
<option value=24 >flash sms 
<option value=200 >Индикация голосового сообщения (Вкл.) 
<option value=192 >Индикация голосового сообщения (Выкл.) 
<option value=201 >Иидикация наличия факса (Вкл.) 
<option value=193 >Иидикация наличия факса (Вкл.) 
<option value=202 >Индикация сообщения e-mail ( Вкл. ) 
<option value=194 >Индикация сообщения e-mail ( Выкл. ) 
<input type=reset value="clean"> 
<input type=submit value="send >>"> 
</form>


Очевидно, что это форма со следующими компонентами:

1) поле для ввода текста с именем to, куда вводится номер абонента
2) элемент ввода текста с именем msg, куда вводится текст сообщения
3) выпадающее меню с именем dcs, где выбирается тип сообщения
4) кнопка "clean" для очистки формы от текстовой информации
5) кнопка "send >>" для отправки содержимого формы на сервер

Таким образом, строка вида (1) образуется при отправке содержимого формы методом post на cgi шлюз по адресу http://sms.smarts-gsm.ru/sms.cgi

Делаем вывод, что нужно при помощи Delphi сформировать такую же строку и отослать ее на сервер оператора сотовой связи. Отправку строки будем производить методом Navigate2 компонента TWebBrowser.

Спецификация метода следующая :

procedure Navigate2(var Url: OleVariant; var Flags: OleVariant;
  var TargetFrameName: OleVariant; var PostData: OleVariant;
  var Headers: OleVariant); overload;

Описание: метод используется при навигации и закачки специфичных ресурсов. Может отсылать НТТР сообщения на специфичные адреса URL и показывать при этом результаты выполнения этого метода.

Параметры:

  • Url - указатель на локальный файл или ресурс в сети Интернет.
  • Flags - может принимать одно из нескольких возможных значений:
    • NavOpenInNewWindow = 1 - открывать файл или URL в новом окне
    • NavNoHistory = 2 - не добавлять файл в лист History. Новая страница заменяет имеющуюся страницу в кэше.
    • NavNoReadFromCache = 4 - Не читать страницу из кэша.
    • NavNoWriteToCache = 8 - Не записывать результат навигации в кэш.
    • NavAllowAutoSearch = 16 - Если навигация не удалась, разрешить браузеру искать ресурсы с таким же названием, но с именем домена (com, .edu, и т.д.)
  • TargetFrameName - имя фрейма в ресурсе, который должен быть отображен, или null если таковой не может отображаться в указанном URL.
  • PostData - содержит данные, пересылаемые серверу. Используется для генерации post метода. Если значение переменной null, то генерируется метод get. Данные, содержащиеся в PostData игнорируются, если URL по которому производится навигация, не HTTP типа.
  • Headers - содержит НТТР заголовок передаваемых данных

Создадим форму в Delphi из необходимых для заполнения строки вида (1) компонентов. Добавляем также компонент TWebBrowser и делаем его невидимым из эстетических соображений.

Номер телефона должен заноситься в компонент ComboBox1, а текст сообщения в Memo1. Обработчик кнопки "Отправить", будет выглядеть следующим образом:

var
  vWebAddr, vPostData, vFlags, vFrame, vHeaders: OleVariant;
  iLoop: Integer;
  Text, stPostData: string;
begin
  Text := Memo1.Text;
  // заполняем строковую переменную stpostdata значениями полей.
  // Отправляем обычный sms, поэтому dcs=0, исходя из значений в html форме <option value=0>Обычный sms
  stPostData := 'to=' + ComboBox1.Text + '&msg=' + Text + '&dcs=0';
  // создаем http заголовок в виде нуль-терминальной строки(оканчивающейся на #0);
  vHeaders := 'content-type:application/x-www-form-urlencoded' + #10#13#0;
  // для заполнения передаваемых данных создаем вариантный массив 
  // с минимальным пределом равным 0 и максимальным, равного длине строки Length(stPostData)
  // типа VarByte (8-ми битовое беззнаковое целочисленное значение (тип Byte))
  vPostData := VarArrayCreate([0, Length(stPostData)], VarByte);
  // посимвольно заполняем вариантный массив значениями нашей строки
  for iLoop := 0 to Length(stPostData)-1 do
  begin
    vPostData[iLoop] := Ord(stPostData[iLoop+1]);
  end;
  // обнуляем последний элемент
  vPostData[Length(stPostData)] := 0;
  // В поле VType помещается признак типа данных. Присваиваем вариантной структуре данных 
  // тип VarArray, что означает "Вариантный массив". Данная операция необходимо для того,
  // чтобы массив данных был вариантного типа. Если данную операцию не производить,
  // то массив, хотя и будет состоять из значений типа Variant, не будет вариантного типа.
  TVarData(vPostData).VType := VarArray;
  vWebAddr := 'http://sms.smarts-gsm.ru/sms.cgi';
  // ставим флаг "не записывать в кэш". 
  vFlags := NavNoWriteToCache;
  vFrame := EmptyParam;
  // используя метод Navigate2, отправляем заполненные структуры данных на известный нам адрес,
  // предусмотрев обработку ошибки.
  try
    WebBrowser1.Navigate2(vWebAddr, vFlags, vFrame, vPostData, vHeaders);
  except
  end;
end;

Подводные камни

1) Абонент может получить sms сообщение в другой кодировке. Это объясняется тем, что в шлюзе производится обработка принимаемого сообщения только в какой-либо одной кодировке. Все зависит от конкретной реализации cgi шлюза. В любом случае кодировка подбирается экспериментальным путем.
2) Результат отправки сообщения появляется в новой странице, к примеру "Сообщение отправлено успешно", после того, как сервер принимает сообщение и генерирует при помощи шлюза новую страницу. Так что узнать, корректно ли принял sms сообщение сервер, можно при анализе новой страницы, появляющейся в браузере.


Source: http://delphi-ex.narod.ru
ID: 03588