Страница 1 из 1

Отправка смс с сайта

СообщениеДобавлено: Пн апр 25, 2005 14:17
aka Time
Здравствуйте. Как прямо с сайта отправить смс-сообщение на мобильный. Знаю, что это сделать можно, но не знаю как. Какие при этом накладываются ограничения? -01-

СообщениеДобавлено: Пн апр 25, 2005 15:57
Олежек
> Отправка SMS с помощью PHP
Введение
Добрый день.
В этой статье я хочу показать вам, как можно отправить SMS с помощью PHP скрипта.
Хочу сразу сказать, что для каждого оператора нужно будет написать свой скрипт отправки SMS, но они принципиально не отличаются друг от друга. Таким образом, разобравшись со скриптом отправки SMS для одного оператора, вы с успехом напишите аналогичные скрипты для всех других операторов.


Так как я пользуюсь услугами оператора Мегафон, то и скрипт будет отправлять SMS на любой номер сети Мегафон.
Как вы, наверно, знаете, отправить SMS можно вполне беспрепятственно с сайта оператора (http://www.megafonmoscow.ru/misc/sms). Ознакомившись с формой отправки, выясняется, что для отправики SMS необходимо будет

Выбрать префикс.
Ввести номер телефона.
Ввести сообщение.
Выбрать по необходимости время отправки.
Главное, что нужно будет учитывать при написании сообщения (таковы условия отправки SMS с сайта Мегафона), это то, что длинна сообщения не должна превышать 110 символов (латиница), остальную часть сообщения Мегафон забирает под рекламу.

В чем же будет заключаться работа нашего скрипта? Так как SMS по идее должен отправлять пользователь из реального браузера, то наша задача будет заключаться в имитировании захода пользователя на страницу и последующей имитации отправки SMS пользователем. Как мы это сделаем? Мы сгенерируем точно такой же запрос скрипту отправки SMS (на http://www.megafonmoscow.ru/misc/sms2), что и генерирует браузер реального пользователя.

Форма запроса
Запрос создается на основе данных формы отправки SMS на сайте Мегафона.

Вот она:

Номер телефона: 7 926 7 095

Сообщение


Осталось символов
Использовать транслитерацию





Отложить отправку


-- 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 : -- 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 -- 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 -- Января Февраля Марта Апреля Мая Июня Июля Августа Сентября Октября Ноября Декабря ---- 2003 2004

(Вы можете указать дату и время отправки сообщения. В случае использования данной функции отправка сообщения произойдет в указанное время)





Вот ее код:

<form action=sms2 name="sendsms" method="post">

<select name="prefix">
<option value="7926">7 926</option>
<option value="7095">7 095</option>
</select>

<input name="addr" type="text">
<input name="mlength" value="(максимум 110 символов):">
<textarea name="message" style="width: 100%;"></textarea>
<input name="messlen" value="110">
<input name="transliterate" type="checkbox" checked>
<input name="send" value="Отправить" type="submit">
<input name="send_after_flag" value="on" type="checkbox">

<select name="send_hour">
<option value="-1">--</option>
<option value="0">00</option>
<option value="1">01</option>
...
<option value="23">23</option>
</select>

<select name="send_minute">
<option value="-1">--</option>
<option value="0">00</option>
<option value="1">01</option>
...
<option value="59">59</option>
</select>

<select name="send_day">
<option value="-1">--</option>
<option value="1">01</option>
<option value="2">02</option>
...
<option value="31">31</option>
</select>

<select name="send_month">
<option value="-1">--</option>
<option value="1">Января</option>
<option value="2">Февраля</option>
...
<option value="12">Декабря</option>
</select>

<select name="send_year">
<option value="-1">----</option>
<option value="2003">2003</option>
<option value="2004">2004</option>
</select>

</form>

Анализ кода формы
Анализуруя тег <form>, находим, что при нажатии на кнопку "Отправить", форма посылает запрос скрипту "sms2", который находится там же, что и страница с формой, то есть абсолютный путь к этому скрипту будет такой: /misc/sms2, и, соответственно, url: http://www.megafonmoscow.ru/misc/sms2 (напоминаю, что сама форма отправки SMS находится здесь /misc/sms, url: http://www.megafonmoscow.ru/misc/sms, так как в action написано "sms2" без слешей и других символов, то файл sms2 находится там же, где и файл sms с формой для отправки)

Фома использует метод POST для отправки данных (method="post").

В форме присутствуют следующие поля (см исходный код):
prefix - префикс номера. Так как это список (<select>), то prefix может принимать только одно из двух значений:7095 и 7926 (значения тегов <option>).
addr - ваш телефонный номер (6 знаков).
mlength - Поле, в котором написано "(максимум 110 символов):", соответственно принимает только это значение ("(максимум 110 символов):").
message - само сообщение, длинна которого по условию должна быть не более 110 символов.
messlen - в этом поле нам любезно пишется сколько осталось символов (с помощью javascript). Значение поля зависит исключительно от размера поля message и равно 110-размер message в символах. То есть еcлu message="Hello!", то messlen=110-6=104. Это будет необходимо учитывать в будущем при отправке данных.

Следующие параметры не так важны, но упомянуть о них стоит.
transliterate - флажок, отвечающий за транслитерацию. По умолчанию значение его равно "on" (не смотря на то, что в теге написано checked, значие "on" этот флажок принимает после отправки данных формы)
send_after_flag - флажок, который надо будет отметить, еcлu вы вдруг захотите отложить отправку, по умолчанию не отмечен и, соответственно, равен пустой строке.

Следующие параметры имеют смысл только при отмеченном send_after_flag
send_hour - час отправления в формате hh (00, 01 … 22), по умолчанию параметр не установлен и равен -1 (минус один).
send_minute - минута отправления в формате mm, по умолчанию равен -1.
send_day - число месяца отправления в формате dd, по умолчанию -1.
send_month - месяц отправления по-русски в родительном падеже (Января, Августа), по умолчанию -1.
send_year - год отправления в формате yyyy (2004), по умолчанию -1.

Структура запроса
Браузер пользователя при отправке данных формы, генерирует запрос для скрипта sms2.
Запрос состоит из заголовка и тела запроса. Тело запроса - это просто структурированные данные формы (как их структурировать написано ниже). Давайте лучше по-подробней разберемся с заголовком запроса.
Заголовок должен быть исключительно таким:

POST /misc/sms2 HTTP/1.1.
Host: www.megafonmoscow.ru
Referer: http://www.megafonmoscow.ru/misc/sms
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Content-Type: application/x-www-form-urlencoded
Accept: */*
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Content-Length: XXX

(Content-Length: XXX, где XXX - размер тела запроса в символах.)

В этом месте мы немного хитрим. Ведь наш скрипт будет выполняться на сервере, а это значит, что такие параметры, как Referer (откуда мы пришли) и User-Agent (Браузер), при стандартном запросе с сервера, будут отсутствовать по вполне логичным причинам (запрос идет с сервера, а не от браузера). Таким образом, нам приходится подделывать заголовок запроса, что бы все выглядело так, как будто сообщение отправляет реальный пользователь с вполне, кстати говоря, реальным IP (IP сервера, откуда будет запускаться скрипт).

Формируем скрипт.
Продвигаемся еще глубже. Формируем тело скрипта. Листинг его приведен в самом конце страницы, а здесь и далее скрипт формируется последовательно с комментариями.

1. Формируем данные формы:

// Переменные
$prefix='7926';
$addr='0000000'; // телефон
$mlength='(максимум 110 символов):';
$message='Hi';
$messlen=110-strlen($message); // Зависит от длинны сообщения. В Мегафоне ораничение на 110 символов
$transliterate='on';
$send_after_flag='';
$send_hour='-1';
$send_minute='-1';
$send_day='-1';
$send_month='-1';
$send_year='-1';

SMS, содержащее одно слово "Hi", отправляем на телефон +79260000000. Имена переменныъх совпадают с именами тегов input. Значения всех стоят по умолчанию, кроме трех: prefix, addr, message и messlen

2. Формируем тело запроса:

// Тело запроса
$POSTData=
"prefix=".urlencode($prefix)."&".
"addr=".urlencode($addr)."&".
"mlength=".urlencode($mlength)."&".
"message=".urlencode($message)."&".
"messlen=".urlencode($messlen)."&".
"transliterate=".urlencode($transliterate)."&".
"send=".urlencode('Отправить')."&".
"send_hour=".urlencode($send_hour)."&".
"send_minute=".urlencode($send_minute)."&".
"send_day=".urlencode($send_day)."&".
"send_month=".urlencode($send_month)."&".
"send_year=".urlencode($send_year);

Тело запроса при помощи метода POST формируются также как при методе GET. А именно структура тела запроса такая: параметр_1=значение_параметра_1&параметр_2=значение_параметра_2&…&параметр_N=значение_параметра_N;
Так же формируем тело запроса и мы.
Функция urlencode встроена в php и используется для перекодирования всех значений параметров в формат тела запроса (пробелы заменяются на "+", буквы на последовательности символа "%" и двух чисел в шестнадцатиричном формате).

3. Теперь сформируем весь запрос, состоящий из заголовка и тела.

// Запрос с заголовком и телом

$len=strlen($POSTData); // Размер в символах тела запроса
$nn="\r\n"; // возврат каретки и символ новой строки

$request=
"POST /misc/sms2 HTTP/1.1".$nn.
"Host: www.megafonmoscow.ru".$nn.
"Referer: http://www.megafonmoscow.ru/misc/sms".$nn.
"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)".$nn.
"Content-Type: application/x-www-form-urlencoded".$nn.
"Accept: */*".$nn.
"Accept-Encoding: gzip, deflate".$nn.
"Connection: Keep-Alive".$nn.
"Content-Length: $len".$nn.$nn.
"$POSTData";

Главное ничего не забыть и соблюсти все основополагающие принципы построения запроса. Каждый параметр заголовка запроса должен начинаться с новой строки. Последовательность символов возврата каретки (\r) и новой строки (\n) заменила переменная $nn, объявленная выше. Параметр Content-Length формируется в зависимости от длинны тела запроса $len ($len=strlen($POSTData). И не забудьте отделить заголовок запроса от тела пустой строкой! Не соблюдение, по крайней мере, одного из этих пунктов, может привести к неудовлетворительным результатам.

4. Теперь осталось только присоединиться к хосту и отправить наш запрос.
Вот как это осуществляется:

// Открываем сокет и отсылаем запрос скрипту
$socket='www.megafonmoscow.ru';

if ($fp = fsockopen($socket, 80, &$errno, &$errstr, 30)) {
fputs($fp,$request);
fclose($fp);
}
else {
print "Невозможно присоединиться, по причине:$errstr ($errno)<br>\n"; exit;
}

Мы присоединяемся к сокету 'www.megafonmoscow.ru' через стандартный 80 порт для http запросов. И работаем с сокетом как с файлом. Функцией fputs отправляем наш запрос. Потом закрываем соединение.

Все, скрипт собран, его листинг приведен ниже, и на этом предлагаю закончить. На последок хочу сказать, что многие операторы связи стараются защитить себя от подобных скриптов, ставя на их пути различные преграды. Удачный пример: Beeline, что бы отправить SMS, надо, помимо прочего, еще и вписать в специальное поле секретный код (последовательность цифр), указанный на картинке.

Полный листинг php скрипта отправки SMS
// Переменные
$prefix='7926';
$addr='0000000'; // телефон
$mlength='(максимум 110 символов):';
$message='Hi';
$messlen=110-strlen($message);// Зависит от длинны сообщения В мегафоне ораничение на 110 символов
$transliterate='on';
$send_after_flag='';
$send_hour='-1';
$send_minute='-1';
$send_day='-1';
$send_month='-1';
$send_year='-1';

// Тело запроса
$POSTData=
"prefix=".urlencode($prefix)."&".
"addr=".urlencode($addr)."&".
"mlength=".urlencode($mlength)."&".
"message=".urlencode($message)."&".
"messlen=".urlencode($messlen)."&".
"transliterate=".urlencode($transliterate)."&".
"send=".urlencode('Отправить')."&".
"send_hour=".urlencode($send_hour)."&".
"send_minute=".urlencode($send_minute)."&".
"send_day=".urlencode($send_day)."&".
"send_month=".urlencode($send_month)."&".
"send_year=".urlencode($send_year);

$len=strlen($POSTData); // Размер в символах тела запроса
$nn="\r\n"; // возврат каретки и символ новой строки

// Запрос с заголовком и телом
$request=
"POST /misc/sms2 HTTP/1.1".$nn.
"Host: www.megafonmoscow.ru".$nn.
"Referer: http://www.megafonmoscow.ru/misc/sms".$nn.
"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)".$nn.
"Content-Type: application/x-www-form-urlencoded".$nn.
"Accept: */*".$nn.
"Accept-Encoding: gzip, deflate".$nn.
"Connection: Keep-Alive".$nn.
"Content-Length: $len".$nn.$nn.
"$POSTData";

// Открываем сокет и отсылаем запрос скрипту

$socket='www.megafonmoscow.ru';

if ($fp = fsockopen($socket, 80, &$errno, &$errstr, 30)) {
fputs($fp,$request);
echo fgets($fp,1024);
fclose($fp);
}
else {
print "Невозможно присоединиться, по причине:$errstr ($errno)<br>\n"; exit;
}




Дык вчера сам искал, вот результат

СообщениеДобавлено: Пн апр 25, 2005 16:06
aka Time
Экаж ты наваял, просто зачитаешься... -06- -06- -01-

СообщениеДобавлено: Чт мар 13, 2008 12:41
PostFx
2Олежек:, спасибо, классный пост.
Понимаю, что прошло много времени =)
Но я сейчас пытаюсь сделать что-то типа этого. На megafonmoscow.ru ситуация поменялась:

во-первых, смс шлют с http://sms.megafonmoscow.ru
во-вторых, форма выглядит следующим образом:

<form action="/sms.action" method="post" enctype="multipart/form-data" class="simple" id="smsForm">
<input type="hidden" name="codekey" value="78437952" />
<input type="hidden" name="charcheck" value="йцукен" />
<input type="hidden" name="lang" value="rus" />

<div class="code">
<img src="/captcha/78437952" alt="код" class="code"/>

<div>
<input maxlength="4" size="9" value="" notice="Введите код с картинки" name="codevalue" type="text" id="codevalue" tabindex="1" autocomplete="off" />
</div>
</div>

<div class="phonenumber">
<select name="prefix">
<option value="7926" name="prefix_f">+ 7 926</option>
<option value="7925" name="prefix_f">+ 7 925</option>
<option value="7495" name="prefix_f">+ 7 495 (925*)</option>
</select>

<input maxlength="7" size="9" name="addr" type="text" id="addr" tabindex="2" notice="Введите номер телефона абонента"/>
</div>

<div class="message-wrapper">
<div class="message">
<p>
<input name="transliterate" id="transliterate" type="checkbox" class="radio" checked="checked"/>
</p>

<textarea rows="4" cols="29" name="message" id="message" tabindex="3" notice="Введите сообщение но не больше %s символов"></textarea>

<div>
<div>
<input maxlength="3" size="3" value="" name="messlen" type="text" id="messlen" readonly="readonly"/>
</div>

<span>символов осталось</span>
</div>
</div>

<p class="notice">
<strong>Примечание:</strong>
В Ваше сообщение будет включена информация о новых услугах.
</p>

<input type="submit" value="Отправить сейчас" name="go" />

<div class="custom_date">
<p>
<input value="on" name="send_after_flag" type="checkbox" id="send_after_flag_on"/>
</p>

<div>
<select name="send_day" class="date">
<option value="1"
>
01 ......
....
...
...


допустим, картинку-капчу я захватываю и вывожу на сайте, при этом пользователь вводит этот код.

Меня интересует, как поменяется запрос POST. Подскажите, пожалуйста

СообщениеДобавлено: Чт мар 13, 2008 16:51
PostFx
Добавил в POST новые поля, соответсвенно, сейчас я заполняю:
$POSTData=
"codekey=".urlencode($codekey)."&".
"charcheck=".urlencode($charcheck)."&".
"lang=".urlencode($lang)."&".
"codevalue=".urlencode($codevalue)."&".
"prefix=".urlencode($prefix)."&".
"addr=".urlencode($addr)."&".
"transliterate=".urlencode($transliterate)."&".
"message=".urlencode($message)."&".
"messlen=".urlencode($messlen)."&".
"send=".urlencode('Send')."&".
"go=".urlencode('GO')."&".
"send_hour=".urlencode($send_hour)."&".
"send_minute=".urlencode($send_minute)."&".
"send_day=".urlencode($send_day)."&".
"send_month=".urlencode($send_month)."&".
"send_year=".urlencode($send_year);

На мой запрос:

$request=
"POST /sms.action HTTP/1.1".$nn.
"Host: www.sms.megafonmoscow.ru".$nn.
"Referer: http://sms.megafonmoscow.ru/".$nn.
"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)".$nn.
"Content-Type: application/x-www-form-urlencoded".$nn.
"Accept: */*".$nn.
"Accept-Encoding: gzip, deflate".$nn.
"Connection: Keep-Alive".$nn.
"Content-Length: $len".$nn.$nn.
"$POSTData";

$socket='www.sms.megafonmoscow.ru';

if ($fp = fsockopen($socket, 80, &$errno, &$errstr, 30)) {
fputs($fp,$request);

while (!feof($fp))
{
$data .= fgets($fp,128);
}



получаю:

HTTP/1.1 405 Not Allowed Server: nginx/0.5.22 Date: Thu, 13 Mar 2008 13:50:32 GMT Content-Type: text/html Transfer-Encoding: chunked Connection: close 215
405 Not Allowed
nginx/0.5.22
0

СообщениеДобавлено: Чт мар 13, 2008 20:39
Padonak
Изображение

СообщениеДобавлено: Чт мар 13, 2008 22:57
Muerto
Чё то у меня возникло мнение, что с размером передаваемых данных что-то не в поряде. Т. е. клиент закрыл соединение в процессе получения данных. Content-Length не сработал. Насколько я помню там идёт обрыв как раз по chunked, если есть несоответствие кол-ва передаваемой информации внутренней проверке. Хотя могу и ошибаться. У нас Кипер админ - пусть расскажет за методы приёма поста сервером.

СообщениеДобавлено: Пт мар 14, 2008 10:45
PostFx
Есть небольшой прогресс ))
Внимательно присмотревшись, я, наконец, обнаружил, что у формы
enctype="multipart/form-data"

Собственно, вопрос, правильно ли вообще я пишу запрос:

$request=
"POST /sms.action HTTP/1.1".$nn.
"Host: www.sms.megafonmoscow.ru".$nn.
"Referer: http://sms.megafonmoscow.ru/".$nn.
"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)".$nn.
"Content-Type: application/x-www-form-urlencoded".$nn.
"Accept: */*".$nn.
"Accept-Encoding: gzip, deflate".$nn.
"Connection: Keep-Alive".$nn.
"Content-Length: $len".$nn.$nn.
"$POSTData";

?

Может, убрать вообще поле "Content-Type"?

СообщениеДобавлено: Пт мар 14, 2008 11:50
PostFx
Вобщем, вот такая форма отправляет с моего сайта нормально, но это просто HTML-форма с переадресацией на сайт магафона, а мне хочется добиться того же с помощью запроса HTTP.

<form action="http://sms.megafonmoscow.ru/sms.action" method="post">
<input type="hidden" name="codekey" value="78693051"/>
<input type="hidden" name="charcheck" value="йцукен"/>
<input type="hidden" name="lang" value="rus"/>

<img src="http://sms.megafonmoscow.ru/captcha/78693051"/>

<input type="hidden" name="codevalue" value="7s8b"/>

<input type="hidden" name="prefix" value="7926"/>
<input type="hidden" name="addr" value="xxxxxxx"/>

<input type="hidden" name="transliterate" value="on"/>
<input type="hidden" name="message" value="Здарова Диман"/>

<input type="submit" name="go" value="Отправить сейчас"/>

<input type="hidden" name="send_after_flag" value="off"/>
<input type="hidden" name="send_day" value="-1"/>
<input type="hidden" name="send_month" value="-1"/>
<input type="hidden" name="send_hour" value="-1"/>
<input type="hidden" name="send_minute" value="-1"/>
<input type="hidden" name="send_year" value="-1"/>
</form>


Как такую форму "передать" через HTTP запрос?

СообщениеДобавлено: Пт мар 14, 2008 15:20
PostFx
Решение оказалось простым -03-
В имени сокета и в поле "Host:" HTTP запроса не надо писать "www".

Если кому надо, вот работающий код:


<?php

$socket='sms.megafonmoscow.ru';
if (!($fp = fsockopen($socket, 80, &$errno, &$errstr, 30)))
{
echo "Нет связи с http://sms.megafonmoscow.ru";
exit();
}


$codekey='78723823';
$charcheck='йцукен';
$lang='rus';
$codevalue='';
$prefix='7926';
$addr='xxxxxxx';
$transliterate='on';
$message='Test message';
$go='Отправить сейчас';

$POSTData=
"codekey=".urlencode($codekey)."&".
"charcheck=".urlencode($charcheck)."&".
"lang=".urlencode($lang)."&".
"codevalue=".urlencode($codevalue)."&".
"prefix=".urlencode($prefix)."&".
"addr=".urlencode($addr)."&".
"transliterate=".urlencode($transliterate)."&".
"message=".urlencode($message)."&".
"go=".urlencode($go);

$len=strlen($POSTData);
$nn="\r\n";

$request=
"POST /sms.action HTTP/1.1".$nn.
"Host: sms.megafonmoscow.ru".$nn.
"Referer: http://sms.megafonmoscow.ru/".$nn.
"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)".$nn.
"Accept: */*".$nn.
"Connection: close".$nn.
"Content-Type: application/x-www-form-urlencoded".$nn.
"Content-Length: $len".$nn.$nn.
"$POSTData";


fputs($fp,$request);

while (!feof($fp))
$data .= fgets($fp,128);


echo $data;

fclose($fp);

?>

СообщениеДобавлено: Пт май 30, 2008 10:49
Moderator_
Dobri den!

Vi mojete sam script vilajit? ia chut zaputalsia tut. budu ochen blagadaren vam

zaranee spasiba -18-

СообщениеДобавлено: Пн июн 02, 2008 1:03
-=FRE$H=-
Очень умный человек Модератор)

Re: Отправка смс с сайта

СообщениеДобавлено: Сб июл 31, 2010 3:13
dpoint
Вы можете использовать Api для отправки сообщений http://www.2-waysms.com
Инструкция - http://cp.2-waysms.com/2-WaySMS_com_manual.pdf