| БиблиотекиHTTP и SMTP
Для работы с нашим сервисом по протоколам HTTP/HTTPS или SMTP вам достаточно подключить файл соответствующей
библиотеки, после чего вы сможете отправлять SMS-сообщения или проверять статус вызовом одной команды.Для PHP
Скачать файл библиотеки:
smsc_api.php
Исходный код библиотеки:
<?php // M.SMSC.RU API (m.smsc.ru) версия 3.8 (03.07.2019)
define("SMSC_LOGIN", ""); // логин клиента define("SMSC_PASSWORD", ""); // пароль клиента. Если передан пустой логин, то SMSC_PASSWORD используется, как API ключ, вместо логина и пароля define("SMSC_POST", 0); // использовать метод POST define("SMSC_HTTPS", 0); // использовать HTTPS протокол define("SMSC_CHARSET", "windows-1251"); // кодировка сообщения: utf-8, koi8-r или windows-1251 (по умолчанию) define("SMSC_DEBUG", 0); // флаг отладки define("SMTP_FROM", "api@m.smsc.ru"); // e-mail адрес отправителя
// Функция отправки SMS // // обязательные параметры: // // $phones - список телефонов через запятую или точку с запятой // $message - отправляемое сообщение // // необязательные параметры: // // $translit - переводить или нет в транслит (1,2 или 0) // $time - необходимое время доставки в виде строки (DDMMYYhhmm, h1-h2, 0ts, +m) // $id - идентификатор сообщения. Представляет собой 32-битное число в диапазоне от 1 до 2147483647. // $format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram) // $sender - имя отправителя (Sender ID). // $query - строка дополнительных параметров, добавляемая в URL-запрос ("valid=01:00&maxsms=3&tz=2") // $files - массив путей к файлам для отправки mms или e-mail сообщений // // возвращает массив (<id>, <количество sms>, <стоимость>, <баланс>) в случае успешной отправки // либо массив (<id>, -<код ошибки>) в случае ошибки
function send_sms($phones, $message, $translit = 0, $time = 0, $id = 0, $format = 0, $sender = false, $query = "", $files = array()) { static $formats = [1 => "flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"];
$m = _smsc_send_cmd("send", "cost=3&phones=".urlencode($phones)."&mes=".urlencode($message). "&translit=$translit&id=$id".($format > 0 ? "&".$formats[$format] : ""). ($sender === false ? "" : "&sender=".urlencode($sender)). ($time ? "&time=".urlencode($time) : "").($query ? "&$query" : ""), $files);
// (id, cnt, cost, balance) или (id, -error)
if (SMSC_DEBUG) { if ($m[1] > 0) echo "Сообщение отправлено успешно. ID: $m[0], всего SMS: $m[1], стоимость: $m[2], баланс: $m[3].\n"; else echo "Ошибка №", -$m[1], $m[0] ? ", ID: ".$m[0] : "", "\n"; }
return $m; }
// SMTP версия функции отправки SMS
function send_sms_mail($phones, $message, $translit = 0, $time = 0, $id = 0, $format = 0, $sender = "") { return mail("send@send.m.smsc.ru", "", SMSC_LOGIN.":".SMSC_PASSWORD.":$id:$time:$translit,$format,$sender:$phones:$message", "From: ".SMTP_FROM."\nContent-Type: text/plain; charset=".SMSC_CHARSET."\n"); }
// Функция получения стоимости SMS // // обязательные параметры: // // $phones - список телефонов через запятую или точку с запятой // $message - отправляемое сообщение // // необязательные параметры: // // $translit - переводить или нет в транслит (1,2 или 0) // $format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram) // $sender - имя отправителя (Sender ID) // $query - строка дополнительных параметров, добавляемая в URL-запрос ("list=79999999999:Ваш пароль: 123\n78888888888:Ваш пароль: 456") // // возвращает массив (<стоимость>, <количество sms>) либо массив (0, -<код ошибки>) в случае ошибки
function get_sms_cost($phones, $message, $translit = 0, $format = 0, $sender = false, $query = "") { static $formats = [1 => "flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"];
$m = _smsc_send_cmd("send", "cost=1&phones=".urlencode($phones)."&mes=".urlencode($message). ($sender === false ? "" : "&sender=".urlencode($sender)). "&translit=$translit".($format > 0 ? "&".$formats[$format] : "").($query ? "&$query" : ""));
// (cost, cnt) или (0, -error)
if (SMSC_DEBUG) { if ($m[1] > 0) echo "Стоимость рассылки: $m[0]. Всего SMS: $m[1]\n"; else echo "Ошибка №", -$m[1], "\n"; }
return $m; }
// Функция проверки статуса отправленного SMS или HLR-запроса // // $id - ID cообщения или список ID через запятую // $phone - номер телефона или список номеров через запятую // $all - вернуть все данные отправленного SMS, включая текст сообщения (0,1 или 2) // // возвращает массив (для множественного запроса двумерный массив): // // для одиночного SMS-сообщения: // (<статус>, <время изменения>, <код ошибки доставки>) // // для HLR-запроса: // (<статус>, <время изменения>, <код ошибки sms>, <код IMSI SIM-карты>, <номер сервис-центра>, <код страны регистрации>, <код оператора>, // <название страны регистрации>, <название оператора>, <название роуминговой страны>, <название роумингового оператора>) // // при $all = 1 дополнительно возвращаются элементы в конце массива: // (<время отправки>, <номер телефона>, <стоимость>, <sender id>, <название статуса>, <текст сообщения>) // // при $all = 2 дополнительно возвращаются элементы <страна>, <оператор> и <регион> // // при множественном запросе: // если $all = 0, то для каждого сообщения или HLR-запроса дополнительно возвращается <ID сообщения> и <номер телефона> // // если $all = 1 или $all = 2, то в ответ добавляется <ID сообщения> // // либо массив (0, -<код ошибки>) в случае ошибки
function get_status($id, $phone, $all = 0) { $m = _smsc_send_cmd("status", "phone=".urlencode($phone)."&id=".urlencode($id)."&all=".(int)$all);
// (status, time, err, ...) или (0, -error)
if (!strpos($id, ",")) { if (SMSC_DEBUG ) if ($m[1] != "" && $m[1] >= 0) echo "Статус SMS = $m[0]", $m[1] ? ", время изменения статуса - ".date("d.m.Y H:i:s", $m[1]) : "", "\n"; else echo "Ошибка №", -$m[1], "\n";
if ($all && count($m) > 9 && (!isset($m[$idx = $all == 1 ? 14 : 17]) || $m[$idx] != "HLR")) // ',' в сообщении $m = explode(",", implode(",", $m), $all == 1 ? 9 : 12); } else { if (count($m) == 1 && strpos($m[0], "-") == 2) return explode(",", $m[0]);
foreach ($m as $k => $v) $m[$k] = explode(",", $v); }
return $m; }
// Функция получения баланса // // без параметров // // возвращает баланс в виде строки или false в случае ошибки
function get_balance() { $m = _smsc_send_cmd("balance"); // (balance) или (0, -error)
if (SMSC_DEBUG) { if (!isset($m[1])) echo "Сумма на счете: ", $m[0], "\n"; else echo "Ошибка №", -$m[1], "\n"; }
return isset($m[1]) ? false : $m[0]; }
// ВНУТРЕННИЕ ФУНКЦИИ
// Функция вызова запроса. Формирует URL и делает 5 попыток чтения через разные подключения к сервису
function _smsc_send_cmd($cmd, $arg = "", $files = array()) { $url = $_url = (SMSC_HTTPS ? "https" : "http")."://m.smsc.ru/sys/$cmd.php?".(SMSC_LOGIN ? "login=".urlencode(SMSC_LOGIN)."&psw=" : "apikey=").urlencode(SMSC_PASSWORD)."&fmt=1&charset=".SMSC_CHARSET."&".$arg;
$i = 0; do { if ($i++) $url = str_replace('://m.smsc.ru/', '://www'.$i.'.m.smsc.ru/', $_url);
$ret = _smsc_read_url($url, $files, 3 + $i); } while ($ret == "" && $i < 5);
if ($ret == "") { if (SMSC_DEBUG) echo "Ошибка чтения адреса: $url\n";
$ret = ","; // фиктивный ответ }
$delim = ",";
if ($cmd == "status") { parse_str($arg, $m);
if (strpos($m["id"], ",")) $delim = "\n"; }
return explode($delim, $ret); }
// Функция чтения URL. Для работы должно быть доступно: // curl или fsockopen (только http) или включена опция allow_url_fopen для file_get_contents
function _smsc_read_url($url, $files, $tm = 5) { $ret = ""; $post = SMSC_POST || strlen($url) > 2000 || $files;
if (function_exists("curl_init")) { static $c = 0; // keepalive
if (!$c) { $c = curl_init(); curl_setopt_array($c, array( CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => $tm, CURLOPT_TIMEOUT => 60, CURLOPT_SSL_VERIFYPEER => 0, CURLOPT_HTTPHEADER => array("Expect:") )); }
curl_setopt($c, CURLOPT_POST, $post);
if ($post) { list($url, $post) = explode("?", $url, 2);
if ($files) { parse_str($post, $m);
foreach ($m as $k => $v) $m[$k] = isset($v[0]) && $v[0] == "@" ? sprintf("\0%s", $v) : $v;
$post = $m; foreach ($files as $i => $path) if (file_exists($path)) $post["file".$i] = function_exists("curl_file_create") ? curl_file_create($path) : "@".$path; }
curl_setopt($c, CURLOPT_POSTFIELDS, $post); }
curl_setopt($c, CURLOPT_URL, $url);
$ret = curl_exec($c); } elseif ($files) { if (SMSC_DEBUG) echo "Не установлен модуль curl для передачи файлов\n"; } else { if (!SMSC_HTTPS && function_exists("fsockopen")) { $m = parse_url($url);
if (!$fp = fsockopen($m["host"], 80, $errno, $errstr, $tm)) $fp = fsockopen("212.24.33.196", 80, $errno, $errstr, $tm);
if ($fp) { stream_set_timeout($fp, 60);
fwrite($fp, ($post ? "POST $m[path]" : "GET $m[path]?$m[query]")." HTTP/1.1\r\nHost: m.smsc.ru\r\nUser-Agent: PHP".($post ? "\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: ".strlen($m['query']) : "")."\r\nConnection: Close\r\n\r\n".($post ? $m['query'] : ""));
while (!feof($fp)) $ret .= fgets($fp, 1024); list(, $ret) = explode("\r\n\r\n", $ret, 2);
fclose($fp); } } else $ret = file_get_contents($url); }
return $ret; }
// Examples: // include "smsc_api.php"; // list($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "Ваш пароль: 123", 1); // list($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, 0, 0, 0, false, "maxsms=3"); // list($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, 0, 0, 5, false); // list($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "", 0, 0, 0, 3, false); // list($sms_id, $sms_cnt, $cost, $balance) = send_sms("dest@mysite.com", "Ваш пароль: 123", 0, 0, 0, 8, "source@mysite.com", "subj=Confirmation"); // list($cost, $sms_cnt) = get_sms_cost("79999999999", "Вы успешно зарегистрированы!"); // send_sms_mail("79999999999", "Ваш пароль: 123", 0, "0101121000"); // list($status, $time) = get_status($sms_id, "79999999999"); // $balance = get_balance();
?>
Пример использования библиотеки:
<? include_once "smsc_api.php"; ... list($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "Ваш пароль: 123", 1); ... list($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, 0, 0, 0, false, "maxsms=3"); ... list($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, 0, 0, 5, false); ... list($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "", 0, 0, 0, 3, false); ... list($cost, $sms_cnt) = get_sms_cost("79999999999", "Вы успешно зарегистрированы!"); ... list($status, $time) = get_status($sms_id, "79999999999"); ... $balance = get_balance(); ... // отправка SMS через e-mail send_sms_mail("79999999999", "Ваш пароль: 123"); ... ?>
Для Perl
Скачать файл библиотеки:
smsc_api.pm
Исходный код библиотеки:
#!/usr/bin/perl # M.SMSC.RU API (m.smsc.ru) версия 1.9 (03.07.2019)
package smsc_api;
use strict; use warnings;
# Константы для настройки библиотеки use constant SMSC_LOGIN => ""; # логин клиента use constant SMSC_PASSWORD => ""; # пароль клиента. Если передан пустой логин, то SMSC_PASSWORD используется, как API ключ, вместо логина и пароля use constant SMSC_POST => 0; # использовать метод POST use constant SMSC_HTTPS => 0; # использовать HTTPS протокол use constant SMSC_CHARSET => 'utf-8'; # $charset - кодировка сообщения (windows-1251 или koi8-r), по умолчанию используется utf-8 use constant SMSC_DEBUG => 0; # флаг отладки
# Константы для отправки SMS по SMTP use constant SMTP_FROM => 'api@m.smsc.ru'; # e-mail адрес отправителя use constant SMTP_SERVER => 'send.m.smsc.ru'; # адрес smtp сервера
use LWP::UserAgent; use URI::Escape; use Net::SMTP;
use vars qw(@EXPORT); use Exporter 'import'; @EXPORT = qw(send_sms send_sms_mail get_sms_cost get_status get_balance);
# Функция отправки SMS # # обязательные параметры: # # $phones - список телефонов через запятую или точку с запятой # $message - отправляемое сообщение # # необязательные параметры: # # $translit - переводить или нет в транслит (1,2 или 0) # $time - необходимое время доставки в виде строки (DDMMYYhhmm, h1-h2, 0ts, +m) # $id - идентификатор сообщения. Представляет собой 32-битное число в диапазоне от 1 до 2147483647. # $format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram) # $sender - имя отправителя (Sender ID). # $query - строка дополнительных параметров, добавляемая в URL-запрос ("valid=01:00&maxsms=3") # # возвращает массив (<id>, <количество sms>, <стоимость>, <баланс>) в случае успешной отправки # либо массив (<id>, -<код ошибки>) в случае ошибки
sub send_sms { my ($phones, $message, $translit, $time, $id, $format, $sender, $query) = @_;
my @formats = ("flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1");
my @m = _smsc_send_cmd("send", "cost=3&phones=".uri_escape($phones)."&mes=".uri_escape($message). ($translit ? "&translit=$translit" : "").($id ? "&id=$id" : "").($format ? "&".$formats[$format-1] : ""). (defined $sender ? "&sender=".uri_escape($sender) : ""). ($time ? "&time=".uri_escape($time) : "").($query ? "&$query" : ""));
# (id, cnt, cost, balance) или (id, -error)
if (SMSC_DEBUG) { if ($m[1] > 0) { print "Сообщение отправлено успешно. ID: $m[0], всего SMS: $m[1], стоимость: $m[2], баланс: $m[3]\n"; } else { print "Ошибка №", -$m[1], $m[0] ? ", ID: ".$m[0] : "", "\n"; } }
return @m; }
# SMTP версия функции отправки SMS
sub send_sms_mail { my ($phones, $message, $translit, $time, $id, $format, $sender) = @_;
my $smtp = Net::SMTP->new(SMTP_SERVER);
$smtp->mail(SMTP_FROM); $smtp->to('send@send.m.smsc.ru');
$smtp->data(); $smtp->datasend("To: send\@send.m.smsc.ru\n"); $smtp->datasend("Content-Type: text/plain; charset=".SMSC_CHARSET."\n"); $smtp->datasend("\n"); $smtp->datasend(SMSC_LOGIN.":".SMSC_PASSWORD.":".($id ? $id : ""). ":".($time ? $time : "").":".($translit ? $translit : ""). ",".($format ? $format : "").(defined $sender ? ",".$sender : ""). ":$phones:$message\n"); $smtp->dataend(); $smtp->quit; }
# Функция получения стоимости SMS # # обязательные параметры: # # $phones - список телефонов через запятую или точку с запятой # $message - отправляемое сообщение # # необязательные параметры: # # $translit - переводить или нет в транслит (1,2 или 0) # $format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram) # $sender - имя отправителя (Sender ID) # $query - строка дополнительных параметров, добавляемая в URL-запрос ("list=79999999999:Ваш пароль: 123\n78888888888:Ваш пароль: 456") # # возвращает массив (<стоимость>, <количество sms>) либо массив (0, -<код ошибки>) в случае ошибки
sub get_sms_cost { my ($phones, $message, $translit, $format, $sender, $query) = @_;
my @formats = ("flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1");
my @m = _smsc_send_cmd("send", "cost=1&phones=".uri_escape($phones)."&mes=".uri_escape($message). (defined $sender ? "&sender=".uri_escape($sender) : ""). ($translit ? "&translit=$translit" : "").($format ? "&".$formats[$format-1] : "").($query ? "&$query" : ""));
# (cost, cnt) или (0, -error)
if (SMSC_DEBUG) { if ($m[1] > 0) { print "Стоимость рассылки: $m[0]. Всего SMS: $m[1]\n"; } else { print "Ошибка №", -$m[1], "\n"; } }
return @m; }
# Функция проверки статуса отправленного SMS или HLR-запроса # # $id - ID cообщения # $phone - номер телефона # # возвращает массив: # для отправленного SMS (<статус>, <время изменения>, <код ошибки sms>) # для HLR-запроса (<статус>, <время изменения>, <код ошибки sms>, <код IMSI SIM-карты>, <номер сервис-центра>, <код страны регистрации>, # <код оператора абонента>, <название страны регистрации>, <название оператора абонента>, <название роуминговой страны>, # <название роумингового оператора>) # # При $all = 1 дополнительно возвращаются элементы в конце массива: # (<время отправки>, <номер телефона>, <стоимость>, <sender id>, <название статуса>, <текст сообщения>) # # либо массив (0, -<код ошибки>) в случае ошибки
sub get_status { my ($id, $phone, $all) = @_; $all ||= 0;
my @m = _smsc_send_cmd("status", "phone=".uri_escape($phone)."&id=$id&all=$all");
# (status, time, err, ...) или (0, -error)
if (SMSC_DEBUG) { if (exists $m[2]) { print "Статус SMS = $m[0]", $m[1] ? ", время изменения статуса - ".localtime($m[1]) : "", "\n"; } else { print "Ошибка №", -$m[1], "\n"; } }
if ($all && @m > 9 && (!exists $m[14] || $m[14] ne "HLR")) { # ',' в сообщении @m = split(",", join(",", @m), 9); }
return @m; }
# Функция получения баланса # # без параметров # # возвращает баланс в виде строки или undef в случае ошибки
sub get_balance { my @m = _smsc_send_cmd("balance"); # (balance) или (0, -error)
if (SMSC_DEBUG) { if (!exists $m[1]) { print "Сумма на счете: ", $m[0], "\n"; } else { print "Ошибка №", -$m[1], "\n"; } }
return exists $m[1] ? undef : $m[0]; }
# ВНУТРЕННИЕ ФУНКЦИИ
# Функция вызова запроса. Формирует URL и делает 3 попытки чтения
sub _smsc_send_cmd { my ($cmd, $arg) = @_;
my $url_orig = (SMSC_HTTPS ? "https" : "http")."://m.smsc.ru/sys/$cmd.php"; my $url = $url_orig; $arg = (SMSC_LOGIN ? "login=".uri_escape(SMSC_LOGIN)."&psw=" : "apikey=").uri_escape(SMSC_PASSWORD)."&fmt=1&charset=".SMSC_CHARSET.($arg ? "&".$arg : "");
my $ret; my $i = 1;
do {
if ($i > 1) { $url = $url_orig; $url =~ s/smsc/www$i.smsc/; }
$ret = _smsc_read_url($url, $arg); } while ($ret eq "" && ++$i < 6);
if ($ret eq "") { print "Ошибка чтения адреса: $url\n" if (SMSC_DEBUG); $ret = ",0"; # фиктивный ответ }
return split(/,/, $ret); }
# Функция чтения URL
sub _smsc_read_url { my ($url, $arg) = @_;
my $ret = ""; my $post = SMSC_POST || length($arg) > 2000;
my $ua = LWP::UserAgent->new; $ua->timeout(60);
my $response = $post ? $ua->post($url, Content => $arg) : $ua->get($url."?".$arg);
$ret = $response->content if $response->is_success;
return $ret; }
1;
# Examples: # use smsc_api; # my ($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "Ваш пароль: 123", 1); # my ($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, 0, 0, 0, undef, "maxsms=3"); # my ($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, 0, 0, 5); # my ($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "", 0, 0, 0, 3); # my ($cost, $sms_cnt) = get_sms_cost("79999999999", "Вы успешно зарегистрированы!"); # send_sms_mail("79999999999", "Ваш пароль: 123"); # my ($status, $time) = get_status($sms_id, "79999999999"); # my $balance = get_balance();
Пример использования библиотеки:
use smsc_api; ... my ($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "Ваш пароль: 123", 1); ... my ($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, 0, 0, 0, undef, "maxsms=3"); ... my ($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, 0, 0, 5); ... my ($sms_id, $sms_cnt, $cost, $balance) = send_sms("79999999999", "", 0, 0, 0, 3); ... send_sms_mail("79999999999", "Ваш пароль: 123"); ... my ($status, $time) = get_status($sms_id, "79999999999"); ... my $balance = get_balance(); ... my ($cost, $sms_cnt) = get_sms_cost("79999999999", "Вы успешно зарегистрированы!");
Для Ruby
Скачать файл библиотеки:
smsc_api.rb
Исходный код библиотеки:
#coding: utf-8
# M.SMSC.RU API (m.smsc.ru) версия 1.5 (03.07.2019)
require "net/http"
require "net/https"
require "net/smtp"
require "uri"
require "erb"
class SMSC
# Константы для настройки библиотеки
SMSC_LOGIN = "" # логин клиента
SMSC_PASSWORD = "" # пароль клиента. Если передан пустой логин, то SMSC_PASSWORD используется, как API ключ, вместо логина и пароля
SMSC_POST = false # использовать метод POST
SMSC_HTTPS = false # использовать HTTPS протокол
SMSC_CHARSET = "utf-8" # кодировка сообщения: koi8-r или windows-1251 (по умолчанию utf-8)
SMSC_DEBUG = false # флаг отладки
SMTP_FROM = "api@m.smsc.ru" # e-mail адрес отправителя
# Функция отправки SMS
#
# обязательные параметры:
#
# phones - список телефонов через запятую или точку с запятой
# message - отправляемое сообщение
#
# необязательные параметры:
#
# translit - переводить или нет в транслит (1,2 или 0)
# time - необходимое время доставки в виде строки (DDMMYYhhmm, h1-h2, 0ts, +m)
# id - идентификатор сообщения. Представляет собой 32-битное число в диапазоне от 1 до 2147483647.
# format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram)
# sender - имя отправителя (Sender ID).
# query - строка дополнительных параметров, добавляемая в URL-запрос ("valid=01:00&maxsms=3&tz=2")
#
# возвращает массив (<id>, <количество sms>, <стоимость>, <баланс>) в случае успешной отправки
# либо массив (<id>, -<код ошибки>) в случае ошибки
def send_sms(phones, message, translit = 0, time = 0, id = 0, format = 0, sender = false, query = "")
formats = ["flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"]
m = _smsc_send_cmd("send", "cost=3&phones=" + _urlencode(phones) + "&mes=" + _urlencode(message) +
"&translit=#{translit}&id=#{id}" + (format > 0 ? "&#{formats[format-1]}" : "") +
(sender == false ? "" : "&sender=" + _urlencode(sender)) +
(time ? "&time=" + _urlencode(time) : "") + (query ? "&#{query}" : ""))
# (id, cnt, cost, balance) или (id, -error)
if SMSC_DEBUG
if m[1] > "0"
puts "Сообщение отправлено успешно. ID: #{m[0]}, всего SMS: #{m[1]}, стоимость: #{m[2]}, баланс: #{m[3]}\n"
else
puts "Ошибка №#{m[1][1]}" + (m[0] > "0" ? ", ID: #{m[0]}" : "") + "\n";
end
end
return m
end
# SMTP версия функции отправки SMS
def send_sms_mail(phones, message, translit = 0, time = 0, id = 0, format = 0, sender = "")
$VERBOSE = nil
Net::SMTP.start("send.m.smsc.ru") do |smtp|
smtp.send_message("Content-Type: text/plain; charset=#{SMSC_CHARSET}\n\n#{SMSC_LOGIN}:#{SMSC_PASSWORD}:#{id}:#{time}:#{translit},#{format},#{sender}:#{phones}:#{message}", SMTP_FROM, "send@send.m.smsc.ru")
end
$VERBOSE = true
end
# Функция получения стоимости SMS
#
# обязательные параметры:
#
# phones - список телефонов через запятую или точку с запятой
# message - отправляемое сообщение
#
# необязательные параметры:
#
# translit - переводить или нет в транслит (1,2 или 0)
# format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram)
# sender - имя отправителя (Sender ID)
# query - строка дополнительных параметров, добавляемая в URL-запрос ("list=79999999999:Ваш пароль: 123\n78888888888:Ваш пароль: 456")
#
# возвращает массив (<стоимость>, <количество sms>) либо массив (0, -<код ошибки>) в случае ошибки
def get_sms_cost(phones, message, translit = 0, format = 0, sender = false, query = "")
formats = ["flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"]
m = _smsc_send_cmd("send", "cost=1&phones=" + _urlencode(phones) + "&mes=" + _urlencode(message) +
"&translit=#{translit}" + (format > 0 ? "&#{formats[format-1]}" : "") +
(sender == false ? "" : "&sender=" + _urlencode(sender)) +
(query ? "&#{query}" : ""))
# (cost, cnt) или (0, -error)
if SMSC_DEBUG
if m[1] > "0"
puts "Стоимость рассылки: #{m[0]}. Всего SMS: #{m[1]}\n"
else
puts "Ошибка №#{m[1][1]}\n"
end
end
return m
end
# Функция проверки статуса отправленного SMS или HLR-запроса
#
# id - ID cообщения
# phone - номер телефона
#
# возвращает массив:
# для отправленного SMS (<статус>, <время изменения>, <код ошибки sms>)
# для HLR-запроса (<статус>, <время изменения>, <код ошибки sms>, <код IMSI SIM-карты>, <номер сервис-центра>,
# <код страны регистрации>, <код оператора абонента>, <название страны регистрации>, <название оператора абонента>,
# <название роуминговой страны>, <название роумингового оператора>)
#
# При all = 1 дополнительно возвращаются элементы в конце массива:
# (<время отправки>, <номер телефона>, <стоимость>, <sender id>, <название статуса>, <текст сообщения>)
#
# либо массив (0, -<код ошибки>) в случае ошибки
def get_status(id, phone, all = 0)
m = _smsc_send_cmd("status", "phone=" + _urlencode(phone) + "&id=#{id}&all=#{all}")
# (status, time, err, ...) или (0, -error)
if SMSC_DEBUG
if m[1] != "" && m[1] >= "0"
puts "Статус SMS = #{m[0]}" + (m[1] > "0" ? ", время изменения статуса - " + Time.at(m[1].to_i).strftime("%d.%m.%Y %T") : "") + "\n"
else
puts "Ошибка №#{m[1][1]}\n"
end
end
if all && m.size > 9 && ((defined?(m[14])).nil? || m[14] != "HLR")
m = (m.join(",")).split(",", 9)
end
return m
end
# Функция получения баланса
#
# без параметров
#
# возвращает баланс в виде строки или false в случае ошибки
def get_balance
m = _smsc_send_cmd("balance") # (balance) или (0, -error)
if SMSC_DEBUG
if m.length < 2
puts "Сумма на счете: #{m[0]}\n"
else
puts "Ошибка №#{m[1][1]}\n"
end
end
return m.length < 2 ? m[0] : false
end
# ВНУТРЕННИЕ ФУНКЦИИ
# Функция вызова запроса. Формирует URL и делает 5 попыток чтения
def _smsc_send_cmd(cmd, arg = "")
url_orig = (SMSC_HTTPS ? "https" : "http") + "://m.smsc.ru/sys/#{cmd}" + ".php?" + (SMSC_LOGIN ? "login=" + _urlencode(SMSC_LOGIN) + "&psw=" : "apikey=") + _urlencode(SMSC_PASSWORD) + "&fmt=1&charset=#{SMSC_CHARSET}&#{arg}"
url = url_orig.clone
uri = URI.parse(url)
http = _server_connect(uri)
i = 1
begin
if (i > 1)
url = url_orig.clone
url.sub!("://m.smsc.ru/", "://www" + i.to_s + ".m.smsc.ru/")
uri = URI.parse(url)
http = _server_connect(uri)
end
begin
r = (SMSC_POST || url.length > 2000) ? http.post2(uri.path, uri.query) : http.get2(uri.path + "?" + uri.query)
ret = r.body
rescue
ret = ""
end
i+=1
end until ret != "" || i == 6
if ret == ""
puts "Ошибка чтения адреса: #{url}\n" if SMSC_DEBUG
ret = "0,0" # фиктивный ответ
end
return ret.split(",")
end
# Подключение к серверу
def _server_connect(uri)
http = Net::HTTP.new(uri.host, uri.port)
if SMSC_HTTPS
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
return http
end
# кодирование параметра в http-запросе
def _urlencode(str)
ERB::Util.url_encode(str)
end
end
# Examples:
# sms = SMSC.new()
#
# ret = sms.send_sms("79999999999", "Ваш пароль: 123", 1)
# ret = sms.send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, 0, 0, 0, false, "maxsms=3")
# ret = sms.send_sms("79237476298", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, 0, 0, 5)
# ret = sms.send_sms("79999999999", "", 0, 0, 0, 3)
# ret = sms.get_sms_cost("79999999999", "Вы успешно зарегистрированы!")
# sms.send_sms_mail("79999999999", "Ваш пароль: 123", 0, "0101121000")
# ret = sms.get_status(12345, "79999999999")
# balance = sms.get_balance
Пример использования библиотеки:
#coding: utf-8 require "./smsc_api" ... sms = SMSC.new() ... ret = sms.send_sms("79999999999", "Ваш пароль: 123", 1) ... ret = sms.send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, 0, 0, 0, false, "maxsms=3") ... ret = sms.send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, 0, 0, 5) ... ret = sms.send_sms("79999999999", "", 0, 0, 0, 3) ... sms.send_sms_mail("79999999999", "Ваш пароль: 123", 0, "0101121000") ... ret = sms.get_status(12345, "79999999999") ... balance = sms.get_balance ... ret = sms.get_sms_cost("79999999999", "Вы успешно зарегистрированы!")
Для Python
Скачать файл библиотеки:
smsc_api.py
Исходный код библиотеки:
# -*- coding: utf-8 -*- # M.SMSC.RU API (m.smsc.ru) версия 2.0 (03.07.2019)
from datetime import datetime from time import sleep import smtplib
try: from urllib import urlopen, quote except ImportError: from urllib.request import urlopen from urllib.parse import quote
# Константы для настройки библиотеки SMSC_LOGIN = "" # логин клиента SMSC_PASSWORD = "" # пароль клиента. Если передан пустой логин, то SMSC_PASSWORD используется, как API ключ, вместо логина и пароля SMSC_POST = False # использовать метод POST SMSC_HTTPS = False # использовать HTTPS протокол SMSC_CHARSET = "utf-8" # кодировка сообщения (windows-1251 или koi8-r), по умолчанию используется utf-8 SMSC_DEBUG = False # флаг отладки
# Константы для отправки SMS по SMTP SMTP_FROM = "api@m.smsc.ru" # e-mail адрес отправителя SMTP_SERVER = "send.m.smsc.ru" # адрес smtp сервера SMTP_LOGIN = "" # логин для smtp сервера SMTP_PASSWORD = "" # пароль для smtp сервера
# Вспомогательная функция, эмуляция тернарной операции ?: def ifs(cond, val1, val2): if cond: return val1 return val2
# Класс для взаимодействия с сервером m.smsc.ru
class SMSC(object):
# Метод отправки SMS # # обязательные параметры: # # phones - список телефонов через запятую или точку с запятой # message - отправляемое сообщение # # необязательные параметры: # # translit - переводить или нет в транслит (1,2 или 0) # time - необходимое время доставки в виде строки (DDMMYYhhmm, h1-h2, 0ts, +m) # id - идентификатор сообщения. Представляет собой 32-битное число в диапазоне от 1 до 2147483647. # format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram) # sender - имя отправителя (Sender ID). # query - строка дополнительных параметров, добавляемая в URL-запрос ("valid=01:00&maxsms=3") # # возвращает массив (<id>, <количество sms>, <стоимость>, <баланс>) в случае успешной отправки # либо массив (<id>, -<код ошибки>) в случае ошибки
def send_sms(self, phones, message, translit=0, time="", id=0, format=0, sender=False, query=""): formats = ["flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"]
m = self._smsc_send_cmd("send", "cost=3&phones=" + quote(phones) + "&mes=" + quote(message) + \ "&translit=" + str(translit) + "&id=" + str(id) + ifs(format > 0, "&" + formats[format-1], "") + \ ifs(sender == False, "", "&sender=" + quote(str(sender))) + \ ifs(time, "&time=" + quote(time), "") + ifs(query, "&" + query, ""))
# (id, cnt, cost, balance) или (id, -error)
if SMSC_DEBUG: if m[1] > "0": print("Сообщение отправлено успешно. ID: " + m[0] + ", всего SMS: " + m[1] + ", стоимость: " + m[2] + ", баланс: " + m[3]) else: print("Ошибка №" + m[1][1:] + ifs(m[0] > "0", ", ID: " + m[0], ""))
return m
# SMTP версия метода отправки SMS
def send_sms_mail(self, phones, message, translit=0, time="", id=0, format=0, sender=""): server = smtplib.SMTP(SMTP_SERVER)
if SMSC_DEBUG: server.set_debuglevel(1)
if SMTP_LOGIN: server.login(SMTP_LOGIN, SMTP_PASSWORD)
server.sendmail(SMTP_FROM, "send@send.m.smsc.ru", "Content-Type: text/plain; charset=" + SMSC_CHARSET + "\n\n" + \ SMSC_LOGIN + ":" + SMSC_PASSWORD + ":" + str(id) + ":" + time + ":" + str(translit) + "," + \ str(format) + "," + sender + ":" + phones + ":" + message) server.quit()
# Метод получения стоимости SMS # # обязательные параметры: # # phones - список телефонов через запятую или точку с запятой # message - отправляемое сообщение # # необязательные параметры: # # translit - переводить или нет в транслит (1,2 или 0) # format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram) # sender - имя отправителя (Sender ID) # query - строка дополнительных параметров, добавляемая в URL-запрос ("list=79999999999:Ваш пароль: 123\n78888888888:Ваш пароль: 456") # # возвращает массив (<стоимость>, <количество sms>) либо массив (0, -<код ошибки>) в случае ошибки
def get_sms_cost(self, phones, message, translit=0, format=0, sender=False, query=""): formats = ["flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"]
m = self._smsc_send_cmd("send", "cost=1&phones=" + quote(phones) + "&mes=" + quote(message) + \ ifs(sender == False, "", "&sender=" + quote(str(sender))) + \ "&translit=" + str(translit) + ifs(format > 0, "&" + formats[format-1], "") + ifs(query, "&" + query, ""))
# (cost, cnt) или (0, -error)
if SMSC_DEBUG: if m[1] > "0": print("Стоимость рассылки: " + m[0] + ". Всего SMS: " + m[1]) else: print("Ошибка №" + m[1][1:])
return m
# Метод проверки статуса отправленного SMS или HLR-запроса # # id - ID cообщения # phone - номер телефона # # возвращает массив: # для отправленного SMS (<статус>, <время изменения>, <код ошибки sms>) # для HLR-запроса (<статус>, <время изменения>, <код ошибки sms>, <код IMSI SIM-карты>, <номер сервис-центра>, <код страны регистрации>, # <код оператора абонента>, <название страны регистрации>, <название оператора абонента>, <название роуминговой страны>, # <название роумингового оператора>) # # При all = 1 дополнительно возвращаются элементы в конце массива: # (<время отправки>, <номер телефона>, <стоимость>, <sender id>, <название статуса>, <текст сообщения>) # # либо массив (0, -<код ошибки>) в случае ошибки
def get_status(self, id, phone, all = 0): m = self._smsc_send_cmd("status", "phone=" + quote(phone) + "&id=" + str(id) + "&all=" + str(all))
# (status, time, err, ...) или (0, -error)
if SMSC_DEBUG: if m[1] >= "0": tm = "" if m[1] > "0": tm = str(datetime.fromtimestamp(int(m[1]))) print("Статус SMS = " + m[0] + ifs(m[1] > "0", ", время изменения статуса - " + tm, "")) else: print("Ошибка №" + m[1][1:])
if all and len(m) > 9 and (len(m) < 14 or m[14] != "HLR"): m = (",".join(m)).split(",", 8)
return m
# Метод получения баланса # # без параметров # # возвращает баланс в виде строки или False в случае ошибки
def get_balance(self): m = self._smsc_send_cmd("balance") # (balance) или (0, -error)
if SMSC_DEBUG: if len(m) < 2: print("Сумма на счете: " + m[0]) else: print("Ошибка №" + m[1][1:])
return ifs(len(m) > 1, False, m[0])
# ВНУТРЕННИЕ МЕТОДЫ
# Метод вызова запроса. Формирует URL и делает 3 попытки чтения
def _smsc_send_cmd(self, cmd, arg=""): url = ifs(SMSC_HTTPS, "https", "http") + "://m.smsc.ru/sys/" + cmd + ".php" _url = url arg = ifs(SMSC_LOGIN, "login=" + quote(SMSC_LOGIN) + "&psw=", "apikey=") + quote(SMSC_PASSWORD) + "&fmt=1&charset=" + SMSC_CHARSET + "&" + arg
i = 0 ret = ""
while ret == "" and i <= 5: if i > 0: url = _url.replace("m.smsc.ru/", "www" + str(i) + ".m.smsc.ru/") else: i += 1
try: if SMSC_POST or len(arg) > 2000: data = urlopen(url, arg.encode(SMSC_CHARSET)) else: data = urlopen(url + "?" + arg)
ret = str(data.read().decode(SMSC_CHARSET)) except: ret = ""
i += 1
if ret == "": if SMSC_DEBUG: print("Ошибка чтения адреса: " + url) ret = "," # фиктивный ответ
return ret.split(",")
# Examples: # smsc = SMSC() # smsc.send_sms("79999999999", "test", sender="sms") # smsc.send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", query="maxsms=3") # smsc.send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", format=5) # smsc.send_sms("79999999999", "", format=3) # r = smsc.get_sms_cost("79999999999", "Вы успешно зарегистрированы!") # smsc.send_sms_mail("79999999999", "test2", format=1) # r = smsc.get_status(12345, "79999999999") # print(smsc.get_balance())
Пример использования библиотеки:
from smsc_api import * ... smsc = SMSC() ... r = smsc.send_sms("79999999999", "Ваш пароль: 123", sender="sms") ... r = smsc.send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", query="maxsms=3") ... r = smsc.send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", format=5) ... r = smsc.send_sms("79999999999", "", format=3) ... r = smsc.get_sms_cost("79999999999", "Вы успешно зарегистрированы!") ... r = smsc.get_status(12345, "79999999999") ... balance = smsc.get_balance() ... # отправка SMS через e-mail smsc.send_sms_mail("79999999999", "Ваш пароль: 123") ...
Для Java
Скачать файл библиотеки:
smsc_api.java
Исходный код библиотеки:
/* * M.SMSC.RU API (m.smsc.ru) версия 1.4 (27.10.2021) smsc's sms sender package */ package smsc;
import java.net.*; import java.io.*; import java.lang.Math;
public class Smsc {
String SMSC_LOGIN = ""; // логин клиента String SMSC_PASSWORD = ""; // пароль клиента. Если передан пустой логин, то SMSC_PASSWORD используется, как API ключ, вместо логина и пароля boolean SMSC_HTTPS = false; // использовать HTTPS протокол String SMSC_CHARSET = "utf-8"; // кодировка сообщения: koi8-r, windows-1251 или utf-8 (по умолчанию) boolean SMSC_DEBUG = false; // флаг отладки boolean SMSC_POST = false; // Использовать метод POST
/** * constructors */ public Smsc() { }
public Smsc(String login, String password) { SMSC_LOGIN = login; SMSC_PASSWORD = password; }
public Smsc(String login, String password, String charset) { SMSC_LOGIN = login; SMSC_PASSWORD = password; SMSC_CHARSET = charset; }
public Smsc(String login, String password, String charset, boolean debug) { SMSC_LOGIN = login; SMSC_PASSWORD = password; SMSC_CHARSET = charset; SMSC_DEBUG = debug; }
/** * Отправка SMS * * @param phones - список телефонов через запятую или точку с запятой * @param message - отправляемое сообщение * @param translit - переводить или нет в транслит (1,2 или 0) * @param time - необходимое время доставки в виде строки (DDMMYYhhmm, h1-h2, 0ts, +m) * @param id - идентификатор сообщения. Представляет собой 32-битное число в диапазоне от 1 до 2147483647. * @param format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram) * @param sender - имя отправителя (Sender ID). * @param query - строка дополнительных параметров, добавляемая в URL-запрос ("valid=01:00&maxsms=3&tz=2") * @return array (<id>, <количество sms>, <стоимость>, <баланс>) в случае успешной отправки * или массив (<id>, -<код ошибки>) в случае ошибки */
public String[] send_sms(String phones, String message, int translit, String time, String id, int format, String sender, String query) { String[] formats = {"", "flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"}; String[] m = {};
try { m = _smsc_send_cmd("send", "cost=3&phones=" + URLEncoder.encode(phones, SMSC_CHARSET) + "&mes=" + URLEncoder.encode(message, SMSC_CHARSET) + "&translit=" + translit + "&id=" + id + (format > 0 ? "&" + formats[format] : "") + (sender.equals("") ? "" : "&sender=" + URLEncoder.encode(sender, SMSC_CHARSET)) + (time.equals("") ? "" : "&time=" + URLEncoder.encode(time, SMSC_CHARSET) ) + (query.equals("") ? "" : "&" + query)); } catch (UnsupportedEncodingException e) { System.out.print("Указанная кодировка символов не поддерживается!\n" + e + "\n"); }
if (m.length > 1) { if (SMSC_DEBUG) { if (Integer.parseInt(m[1]) > 0) { System.out.println("Сообщение отправлено успешно. ID: " + m[0] + ", всего SMS: " + m[1] + ", стоимость: " + m[2] + ", баланс: " + m[3]); } else { System.out.print("Ошибка №" + Math.abs(Integer.parseInt(m[1]))); System.out.println(Integer.parseInt(m[0])>0 ? (", ID: " + m[0]) : ""); } } } else { System.out.println("Не получен ответ от сервера."); }
return m; };
/** * Получение стоимости SMS * * @param phones - список телефонов через запятую или точку с запятой * @param message - отправляемое сообщение. * @param translit - переводить или нет в транслит (1,2 или 0) * @param format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram) * @param sender - имя отправителя (Sender ID) * @param query - строка дополнительных параметров, добавляемая в URL-запрос ("list=79999999999:Ваш пароль: 123\n78888888888:Ваш пароль: 456") * @return array(<стоимость>, <количество sms>) либо (0, -<код ошибки>) в случае ошибки */
public String[] get_sms_cost(String phones, String message, int translit, int format, String sender, String query) { String[] formats = {"", "flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"}; String[] m = {};
try { m = _smsc_send_cmd("send", "cost=1&phones=" + URLEncoder.encode(phones, SMSC_CHARSET) + "&mes=" + URLEncoder.encode(message, SMSC_CHARSET) + "&translit=" + translit + (format > 0 ? "&" + formats[format] : "") + (sender.equals("") ? "" : "&sender=" + URLEncoder.encode(sender, SMSC_CHARSET)) + (query.equals("") ? "" : "&" + query)); } catch (UnsupportedEncodingException e) { System.out.print("Указанная кодировка символов не поддерживается!\n" + e + "\n"); } // (cost, cnt) или (0, -error)
if (m.length > 1) { if (SMSC_DEBUG) { if (Integer.parseInt(m[1]) > 0) System.out.println("Стоимость рассылки: " + m[0] + ", Всего SMS: " + m[1]);
else System.out.print("Ошибка №" + Math.abs(Integer.parseInt(m[1]))); } } else System.out.println("Не получен ответ от сервера.");
return m; }
/** * Проверка статуса отправленного SMS или HLR-запроса * * @param id - ID cообщения * @param phone - номер телефона * @param all - дополнительно возвращаются элементы в конце массива: * (<время отправки>, <номер телефона>, <стоимость>, <sender id>, <название статуса>, <текст сообщения>) * @return array * для отправленного SMS (<статус>, <время изменения>, <код ошибки sms>) * для HLR-запроса (<статус>, <время изменения>, <код ошибки sms>, <код страны регистрации>, <код оператора абонента>, * <название страны регистрации>, <название оператора абонента>, <название роуминговой страны>, <название роумингового оператор * <код IMSI SIM-карты>, <номер сервис-центра>) * либо array(0, -<код ошибки>) в случае ошибки */
public String[] get_status(int id, String phone, int all) { String[] m = {}; String tmp;
try { m = _smsc_send_cmd("status", "phone=" + URLEncoder.encode(phone, SMSC_CHARSET) + "&id=" + id + "&all=" + all);
if (m.length > 1) { if (SMSC_DEBUG) { if (!m[1].equals("") && Integer.parseInt(m[1]) >= 0) { java.sql.Timestamp currentTimestamp = new java.sql.Timestamp(Integer.parseInt(m[1])); System.out.println("Статус SMS = " + m[0]); } else System.out.println("Ошибка №" + Math.abs(Integer.parseInt(m[1]))); }
if (all == 1 && m.length > 9 && (m.length < 14 || !m[14].equals("HLR"))) { tmp = _implode(m, ","); m = tmp.split(",", 9); } } else System.out.println("Не получен ответ от сервера."); } catch (UnsupportedEncodingException e) { System.out.print("Указанная кодировка символов не поддерживается!\n" + e + "\n"); }
return m; }
/** * Получениe баланса * * @return String баланс или пустую строку в случае ошибки */
public String get_balance() { String[] m = {};
m = _smsc_send_cmd("balance", ""); // (balance) или (0, -error)
if (m.length >= 1) { if (SMSC_DEBUG) { if (m.length == 1) System.out.println("Сумма на счете: " + m[0]); else System.out.println("Ошибка №" + Math.abs(Integer.parseInt(m[1]))); } } else { System.out.println("Не получен ответ от сервера."); } return m.length == 2 ? "" : m[0]; }
/** * Формирование и отправка запроса * @param cmd - требуемая команда * @param arg - дополнительные параметры */
private String[] _smsc_send_cmd(String cmd, String arg){ String ret = ",";
try { String _url = (SMSC_HTTPS ? "https" : "http") + "://m.smsc.ru/sys/" + cmd +".php?" + (SMSC_LOGIN != "" ? "login=" + URLEncoder.encode(SMSC_LOGIN, SMSC_CHARSET) + "&psw=" : "apikey=") + URLEncoder.encode(SMSC_PASSWORD, SMSC_CHARSET) + "&fmt=1&charset=" + SMSC_CHARSET + "&" + arg;
String url = _url; int i = 0; do { if (i++ > 0) { url = _url; url = url.replace("://m.smsc.ru/", "://www" + (i) + ".m.smsc.ru/"); } ret = _smsc_read_url(url); } while (ret.equals("") && i < 5); } catch (UnsupportedEncodingException e) { System.out.print("Указанная кодировка символов не поддерживается!\n" + e + "\n"); }
return ret.split(","); }
/** * Чтение URL * @param url - ID cообщения * @return line - ответ сервера */ private String _smsc_read_url(String url) {
String line = "", real_url = url; String[] param = {}; boolean is_post = (SMSC_POST || url.length() > 2000);
if (is_post) { param = url.split("\\?",2); real_url = param[0]; }
try { URL u = new URL(real_url); InputStream is;
if (is_post){ URLConnection conn = u.openConnection(); conn.setDoOutput(true); OutputStreamWriter os = new OutputStreamWriter(conn.getOutputStream(), SMSC_CHARSET); os.write(param[1]); os.flush(); os.close(); System.out.println("post"); is = conn.getInputStream(); } else { is = u.openStream(); }
InputStreamReader reader = new InputStreamReader(is, SMSC_CHARSET);
int ch; while ((ch = reader.read()) != -1) { line += (char)ch; }
reader.close(); } catch (MalformedURLException e) { // Неверный урл, протокол... System.out.print("Ошибка при обработке URL-адреса!\n" + e + "\n"); } catch (IOException e) { System.out.print("Ошибка при операции передачи/приема данных!\n" + e + "\n"); }
return line; }
private static String _implode(String[] ary, String delim) { String out = "";
for (int i = 0; i < ary.length; i++) { if (i != 0) out += delim; out += ary[i]; }
return out; } }
// Examples: /* Smsc sd = new Smsc(); // or Smsc sd = new Smsc("login", "password");
sd.send_sms("79999999999", "Ваш пароль: 123", 1, "", "", 0, "", ""); sd.get_sms_cost("79999999999", "Вы успешно зарегистрированы!", 0, 0, "", ""); sd.get_status(sms_id, "79999999999"); sd.get_balanse(); */
Пример использования библиотеки:
import smsc_api.Smsc; ... Smsc sms= new Smsc(); ... String[] ret = sms.send_sms("79999999999", "Ваш пароль: 123", 1, "", "", 0, "", ""); ... String[] ret = sms.send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, "", "", 0, "", "maxsms=3"); ... String[] ret = sms.send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, "", "", 5, "", ""); ... String[] ret = sms.send_sms("79999999999", "", 0, "", "", 3, "", ""); ... String[] ret = sms.get_status(12345, "79999999999", 0); ... String balance = sms.get_balance(); ... String[] ret = sms.get_sms_cost("79999999999", "Вы успешно зарегистрированы!", 0, 0, "", "");
Для C# (C sharp; .net framework)
Скачать файл библиотеки:
smsc_api.cs
Исходный код библиотеки:
// M.SMSC.RU API (m.smsc.ru) версия 3.1 (03.07.2019)
using System;
using System.Web;
using System.Net;
using System.IO;
using System.Net.Mail;
using System.Text;
public class SMSC
{
// Константы с параметрами отправки
const string SMSC_LOGIN = ""; // логин клиента
const string SMSC_PASSWORD = ""; // пароль клиента. Если передан пустой логин, то SMSC_PASSWORD используется, как API ключ, вместо логина и пароля
bool SMSC_POST = false; // использовать метод POST
const bool SMSC_HTTPS = false; // использовать HTTPS протокол
const string SMSC_CHARSET = "utf-8"; // кодировка сообщения (windows-1251 или koi8-r), по умолчанию используется utf-8
const bool SMSC_DEBUG = false; // флаг отладки
// Константы для отправки SMS по SMTP
const string SMTP_FROM = "api@m.smsc.ru"; // e-mail адрес отправителя
const string SMTP_SERVER = "send.m.smsc.ru"; // адрес smtp сервера
const string SMTP_LOGIN = ""; // логин для smtp сервера
const string SMTP_PASSWORD = ""; // пароль для smtp сервера
public string[][] D2Res;
// Метод отправки SMS
//
// обязательные параметры:
//
// phones - список телефонов через запятую или точку с запятой
// message - отправляемое сообщение
//
// необязательные параметры:
//
// translit - переводить или нет в транслит
// time - необходимое время доставки в виде строки (DDMMYYhhmm, h1-h2, 0ts, +m)
// id - идентификатор сообщения. Представляет собой 32-битное число в диапазоне от 1 до 2147483647.
// format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram)
// sender - имя отправителя (Sender ID).
// query - строка дополнительных параметров, добавляемая в URL-запрос ("valid=01:00&maxsms=3")
//
// возвращает массив строк (<id>, <количество sms>, <стоимость>, <баланс>) в случае успешной отправки
// либо массив строк (<id>, -<код ошибки>) в случае ошибки
public string[] send_sms(string phones, string message, int translit = 0, string time = "", int id = 0, int format = 0, string sender = "", string query = "", string[] files = null)
{
if (files != null)
SMSC_POST = true;
string[] formats = {"flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"};
string[] m = _smsc_send_cmd("send", "cost=3&phones=" + _urlencode(phones)
+ "&mes=" + _urlencode(message) + "&id=" + id.ToString() + "&translit=" + translit.ToString()
+ (format > 0 ? "&" + formats[format-1] : "") + (sender != "" ? "&sender=" + _urlencode(sender) : "")
+ (time != "" ? "&time=" + _urlencode(time) : "") + (query != "" ? "&" + query : ""), files);
// (id, cnt, cost, balance) или (id, -error)
if (SMSC_DEBUG) {
if (Convert.ToInt32(m[1]) > 0)
_print_debug("Сообщение отправлено успешно. ID: " + m[0] + ", всего SMS: " + m[1] + ", стоимость: " + m[2] + ", баланс: " + m[3]);
else
_print_debug("Ошибка №" + m[1].Substring(1, 1) + (m[0] != "0" ? ", ID: " + m[0] : ""));
}
return m;
}
// SMTP версия метода отправки SMS
public void send_sms_mail(string phones, string message, int translit = 0, string time = "", int id = 0, int format = 0, string sender = "")
{
MailMessage mail = new MailMessage();
mail.To.Add("send@send.m.smsc.ru");
mail.From = new MailAddress(SMTP_FROM, "");
mail.Body = SMSC_LOGIN + ":" + SMSC_PASSWORD + ":" + id.ToString() + ":" + time + ":"
+ translit.ToString() + "," + format.ToString() + "," + sender
+ ":" + phones + ":" + message;
mail.BodyEncoding = Encoding.GetEncoding(SMSC_CHARSET);
mail.IsBodyHtml = false;
SmtpClient client = new SmtpClient(SMTP_SERVER, 25);
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.EnableSsl = false;
client.UseDefaultCredentials = false;
if (SMTP_LOGIN != "")
client.Credentials = new NetworkCredential(SMTP_LOGIN, SMTP_PASSWORD);
client.Send(mail);
}
// Метод получения стоимости SMS
//
// обязательные параметры:
//
// phones - список телефонов через запятую или точку с запятой
// message - отправляемое сообщение
//
// необязательные параметры:
//
// translit - переводить или нет в транслит
// format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram)
// sender - имя отправителя (Sender ID)
// query - строка дополнительных параметров, добавляемая в URL-запрос ("list=79999999999:Ваш пароль: 123\n78888888888:Ваш пароль: 456")
//
// возвращает массив (<стоимость>, <количество sms>) либо массив (0, -<код ошибки>) в случае ошибки
public string[] get_sms_cost(string phones, string message, int translit = 0, int format = 0, string sender = "", string query = "")
{
string[] formats = {"flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"};
string[] m = _smsc_send_cmd("send", "cost=1&phones=" + _urlencode(phones)
+ "&mes=" + _urlencode(message) + translit.ToString() + (format > 0 ? "&" + formats[format-1] : "")
+ (sender != "" ? "&sender=" + _urlencode(sender) : "") + (query != "" ? "&query" : ""));
// (cost, cnt) или (0, -error)
if (SMSC_DEBUG) {
if (Convert.ToInt32(m[1]) > 0)
_print_debug("Стоимость рассылки: " + m[0] + ". Всего SMS: " + m[1]);
else
_print_debug("Ошибка №" + m[1].Substring(1, 1));
}
return m;
}
// Метод проверки статуса отправленного SMS или HLR-запроса
//
// id - ID cообщения или список ID через запятую
// phone - номер телефона или список номеров через запятую
// all - вернуть все данные отправленного SMS, включая текст сообщения (0,1 или 2)
//
// возвращает массив (для множественного запроса возвращается массив с единственным элементом, равным 1. В этом случае статусы сохраняются в
// двумерном динамическом массиве класса D2Res):
//
// для одиночного SMS-сообщения:
// (<статус>, <время изменения>, <код ошибки доставки>)
//
// для HLR-запроса:
// (<статус>, <время изменения>, <код ошибки sms>, <код IMSI SIM-карты>, <номер сервис-центра>, <код страны регистрации>, <код оператора>,
// <название страны регистрации>, <название оператора>, <название роуминговой страны>, <название роумингового оператора>)
//
// при all = 1 дополнительно возвращаются элементы в конце массива:
// (<время отправки>, <номер телефона>, <стоимость>, <sender id>, <название статуса>, <текст сообщения>)
//
// при all = 2 дополнительно возвращаются элементы <страна>, <оператор> и <регион>
//
// при множественном запросе (данные по статусам сохраняются в двумерном массиве D2Res):
// если all = 0, то для каждого сообщения или HLR-запроса дополнительно возвращается <ID сообщения> и <номер телефона>
//
// если all = 1 или all = 2, то в ответ добавляется <ID сообщения>
//
// либо массив (0, -<код ошибки>) в случае ошибки
public string[] get_status(string id, string phone, int all = 0)
{
string[] m = _smsc_send_cmd("status", "phone=" + _urlencode(phone) + "&id=" + _urlencode(id) + "&all=" + all.ToString());
// (status, time, err, ...) или (0, -error)
if (id.IndexOf(',') == -1)
{
if (SMSC_DEBUG)
{
if (m[1] != "" && Convert.ToInt32(m[1]) >= 0)
{
int timestamp = Convert.ToInt32(m[1]);
DateTime offset = new DateTime(1970, 1, 1, 0, 0, 0, 0);
DateTime date = offset.AddSeconds(timestamp);
_print_debug("Статус SMS = " + m[0] + (timestamp > 0 ? ", время изменения статуса - " + date.ToLocalTime() : ""));
}
else
_print_debug("Ошибка №" + m[1].Substring(1, 1));
}
int idx = all == 1 ? 9 : 12;
if (all > 0 && m.Length > idx && (m.Length < idx + 5 || m[idx + 5] != "HLR"))
m = String.Join(",", m).Split(",".ToCharArray(), idx);
}
else
{
if (m.Length == 1 && m[0].IndexOf('-') == 2)
return m[0].Split(',');
Array.Resize(ref D2Res, 0);
Array.Resize(ref D2Res, m.Length);
for (int i = 0; i < D2Res.Length; i++)
D2Res[i] = m[i].Split(',');
Array.Resize(ref m, 1);
m[0] = "1";
}
return m;
}
// Метод получения баланса
//
// без параметров
//
// возвращает баланс в виде строки или пустую строку в случае ошибки
public string get_balance()
{
string[] m = _smsc_send_cmd("balance", ""); // (balance) или (0, -error)
if (SMSC_DEBUG) {
if (m.Length == 1)
_print_debug("Сумма на счете: " + m[0]);
else
_print_debug("Ошибка №" + m[1].Substring(1, 1));
}
return m.Length == 1 ? m[0] : "";
}
// ПРИВАТНЫЕ МЕТОДЫ
// Метод вызова запроса. Формирует URL и делает 3 попытки чтения
private string[] _smsc_send_cmd(string cmd, string arg, string[] files = null)
{
string url, _url;
arg = (SMSC_LOGIN != "" ? "login=" + _urlencode(SMSC_LOGIN) + "&psw=" : "apikey=") + _urlencode(SMSC_PASSWORD) + "&fmt=1&charset=" + SMSC_CHARSET + "&" + arg;
url = _url = (SMSC_HTTPS ? "https" : "http") + "://m.smsc.ru/sys/" + cmd + ".php" + (SMSC_POST ? "" : "?" + arg);
string ret;
int i = 0;
HttpWebRequest request;
StreamReader sr;
HttpWebResponse response;
do
{
if (i++ > 0)
url = _url.Replace("m.smsc.ru/", "www" + i.ToString() + ".m.smsc.ru/");
request = (HttpWebRequest)WebRequest.Create(url);
if (SMSC_POST) {
request.Method = "POST";
string postHeader, boundary = "----------" + DateTime.Now.Ticks.ToString("x");
byte[] postHeaderBytes, boundaryBytes = Encoding.ASCII.GetBytes("--" + boundary + "--\r\n"), tbuf;
StringBuilder sb = new StringBuilder();
int bytesRead;
byte[] output = new byte[0];
if (files == null) {
request.ContentType = "application/x-www-form-urlencoded";
output = Encoding.UTF8.GetBytes(arg);
request.ContentLength = output.Length;
}
else {
request.ContentType = "multipart/form-data; boundary=" + boundary;
string[] par = arg.Split('&');
int fl = files.Length;
for (int pcnt = 0; pcnt < par.Length + fl; pcnt++)
{
sb.Clear();
sb.Append("--");
sb.Append(boundary);
sb.Append("\r\n");
sb.Append("Content-Disposition: form-data; name="");
bool pof = pcnt < fl;
String[] nv = new String[0];
if (pof)
{
sb.Append("File" + (pcnt + 1));
sb.Append(""; filename="");
sb.Append(Path.GetFileName(files[pcnt]));
}
else {
nv = par[pcnt - fl].Split('=');
sb.Append(nv[0]);
}
sb.Append(""");
sb.Append("\r\n");
sb.Append("Content-Type: ");
sb.Append(pof ? "application/octet-stream" : "text/plain; charset="" + SMSC_CHARSET + """);
sb.Append("\r\n");
sb.Append("Content-Transfer-Encoding: binary");
sb.Append("\r\n");
sb.Append("\r\n");
postHeader = sb.ToString();
postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);
output = _concatb(output, postHeaderBytes);
if (pof)
{
FileStream fileStream = new FileStream(files[pcnt], FileMode.Open, FileAccess.Read);
// Write out the file contents
byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))];
bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
tbuf = buffer;
Array.Resize(ref tbuf, bytesRead);
output = _concatb(output, tbuf);
}
}
else {
byte[] vl = Encoding.UTF8.GetBytes(nv[1]);
output = _concatb(output, vl);
}
output = _concatb(output, Encoding.UTF8.GetBytes("\r\n"));
}
output = _concatb(output, boundaryBytes);
request.ContentLength = output.Length;
}
Stream requestStream = request.GetRequestStream();
requestStream.Write(output, 0, output.Length);
}
try
{
response = (HttpWebResponse)request.GetResponse();
sr = new StreamReader(response.GetResponseStream());
ret = sr.ReadToEnd();
}
catch (WebException) {
ret = "";
}
}
while (ret == "" && i < 5);
if (ret == "") {
if (SMSC_DEBUG)
_print_debug("Ошибка чтения адреса: " + url);
ret = ","; // фиктивный ответ
}
char delim = ',';
if (cmd == "status")
{
string[] par = arg.Split('&');
for (i = 0; i < par.Length; i++)
{
string[] lr = par[i].Split("=".ToCharArray(), 2);
if (lr[0] == "id" && lr[1].IndexOf("%2c") > 0) // запятая в id - множественный запрос
delim = '\n';
}
}
return ret.Split(delim);
}
// кодирование параметра в http-запросе
private string _urlencode(string str) {
if (SMSC_POST) return str;
return HttpUtility.UrlEncode(str);
}
// объединение байтовых массивов
private byte[] _concatb(byte[] farr, byte[] sarr)
{
int opl = farr.Length;
Array.Resize(ref farr, farr.Length + sarr.Length);
Array.Copy(sarr, 0, farr, opl, sarr.Length);
return farr;
}
// вывод отладочной информации
private void _print_debug(string str) {
System.Windows.Forms.MessageBox.Show(str);
}
}
// Examples:
// SMSC smsc = new SMSC();
// string[] r = smsc.send_sms("79999999999", "Ваш пароль: 123", 2);
// string[] r = smsc.send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, "", 0, 0, "", "maxsms=3");
// string[] r = smsc.send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, "", 0, 5);
// string[] r = smsc.send_sms("79999999999", "", 0, "", 0, 3);
// string[] r = smsc.send_sms("dest@mysite.com", "Ваш пароль: 123", 0, 0, 0, 8, "source@mysite.com", "subj=Confirmation");
// string[] r = smsc.get_sms_cost("79999999999", "Вы успешно зарегистрированы!");
// smsc.send_sms_mail("79999999999", "Ваш пароль: 123", 0, "0101121000");
// string[] r = smsc.get_status("12345", "79999999999");
// string balance = smsc.get_balance();
Пример использования библиотеки:
SMSC smsc = new SMSC(); ... string[] r = smsc.send_sms("79999999999", "Ваш пароль: 123", 1); ... string[] r = smsc.send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, "", 0, 0, "", "maxsms=3"); ... string[] r = smsc.send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, "", 0, 5); ... string[] r = smsc.send_sms("79999999999", "", 0, "", 0, 3); ... string[] r = smsc.get_sms_cost("79999999999", "Вы успешно зарегистрированы!"); ... string[] r = smsc.get_status(12345, "79999999999"); ... string balance = smsc.get_balance(); ... // отправка SMS через e-mail smsc.send_sms_mail("79999999999", "Ваш пароль: 123"); ...
Для Delphi
Скачать файл библиотеки:
smsc_api.pas
Исходный код библиотеки:
// M.SMSC.RU API для Delphi (m.smsc.ru) версия 3.3 (03.07.2019)
unit smsc_api;
interface
uses IdHTTP, IdURI, IdMessage, IdSMTP, IdStrings, IdGlobal, IdGlobalProtocols, StrUtils, SysUtils,
Forms, Classes, DateUtils, Types, Windows, IdMultipartFormData;
var
SMSC_POST: Boolean = False; // использовать метод POST
const
// Константы с параметрами отправки
SMSC_LOGIN: String = ''; // логин клиента
SMSC_PASSWORD: String = ''; // пароль клиента. Если передан пустой логин, то SMSC_PASSWORD используется, как API ключ, вместо логина и пароля
SMSC_CHARSET: String = {$IFDEF UNICODE}// кодировка сообщения (utf-8 или koi8-r), по умолчанию используется windows-1251
'utf-8'
{$ELSE}
'windows-1251'
{$ENDIF};
SMSC_DEBUG: Boolean = False; // флаг отладки
// Константы для отправки SMS по SMTP
SMTP_FROM: String = 'api@m.smsc.ru'; // e-mail адрес отправителя
SMTP_SERVER: String = 'send.m.smsc.ru'; // адрес smtp сервера
SMTP_LOGIN: String = ''; // логин для smtp сервера
SMTP_PASSWORD: String = ''; // пароль для smtp сервера
type
SMSC = class
public
D2Res: array of TStringDynArray;
// Общедоступные методы класса SMSС
function send_sms(phones: String; mes: String; translit: Integer = 0; time: String = ''; id: Integer = 0; format: Integer = 0; sender: String = ''; query: String = ''; files: TStringList = nil): TStringDynArray;
procedure send_sms_mail(phones: String; mes: String; translit: Integer = 0; time: String = ''; id: Integer = 0; format: Integer = 0; senderid: String = '');
function get_sms_cost(phones: String; mes: String; translit: Integer = 0; format: Integer = 0; sender: String = ''; query: String = ''): TStringDynArray;
function get_status(id: String; phone: String; all: Integer = 0): TStringDynArray;
function get_balance: String;
private
// Приватные методы класса SMSС
function _smsc_send_cmd(cmd: String; arg: String; files: TStringList = nil): TStringDynArray;
function _urlencode(str: String): String;
procedure _print_debug(str: String);
function _ifs(cond: Boolean; val1: String; val2: String): String;
end;
var
formats: array[0..13] of String = ('', 'flash=1', 'push=1', 'hlr=1', 'bin=1', 'bin=2', 'ping=1', 'mms=1', 'mail=1', 'call=1', 'viber=1', 'soc=1', '', 'tg=1');
implementation
// Метод отправки SMS
//
// обязательные параметры:
//
// phones - список телефонов через запятую или точку с запятой
// mes - отправляемое сообщение
//
// необязательные параметры:
//
// translit - переводить или нет в транслит
// time - необходимое время доставки в виде строки (DDMMYYhhmm, h1-h2, 0ts, +m)
// id - идентификатор сообщения. Представляет собой 32-битное число в диапазоне от 1 до 2147483647.
// format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram)
// sender - имя отправителя (Sender ID).
// query - строка дополнительных параметров, добавляемая в URL-запрос ('valid=01:00&maxsms=3')
// files - массив путей к файлам при отправке mms или e-mail сообщений
//
// возвращает массив (<id>, <количество sms>, <стоимость>, <баланс>) в случае успешной отправки
// либо (<id>, -<код ошибки>) в случае ошибки
function SMSC.send_sms(phones: String; mes: String; translit: Integer = 0; time: String = ''; id: Integer = 0; format: Integer = 0; sender: String = ''; query: String = ''; files: TStringList = nil): TStringDynArray;
begin
if files <> nil then
SMSC_POST := true;
Result := _smsc_send_cmd('send', 'cost=3&phones=' + _urlencode(phones) + '&mes=' + _urlencode(mes) + '&id=' + IntToStr(id) + '&translit=' + IntToStr(translit) +
_ifs(format > 0, '&' + formats[format], '') + _ifs(sender <> '', '&sender=' + _urlencode(sender), '') + _ifs(time <> '', '&time=' +
_urlencode(time), '') + _ifs(query <> '', '&' + query, ''), files);
// (id, cnt, cost, balance) или (id, -error)
if SMSC_DEBUG then
if StrToInt(Result[1]) > 0 then
_print_debug('Сообщение отправлено успешно. ID: ' + Result[0] + ', всего SMS: ' + Result[1]
+ ', стоимость: ' + Result[2] + ', баланс: ' + Result[3])
else
_print_debug('Ошибка №' + Result[1][2] + ', ID: ' + Result[0]);
end;
// SMTP версия метода отправки SMS
procedure SMSC.send_sms_mail(phones: String; mes: String; translit: Integer = 0; time: String = ''; id: Integer = 0; format: Integer = 0; senderid: String = '');
var
msg: TIdMessage;
begin
msg := TIdMessage.Create(nil);
with TIdSMTP.Create(nil) do
begin
Port := 25;
Host := SMTP_SERVER;
if SMTP_LOGIN <> '' then
begin
Username := SMTP_LOGIN;
Password := SMTP_PASSWORD;
end;
msg.Recipients.EMailAddresses := 'send@send.m.smsc.ru';
msg.From.Address := SMTP_FROM;
msg.ContentType := 'text/plain';
msg.CharSet := SMSC_CHARSET;
SysLocale.PriLangID := LANG_SYSTEM_DEFAULT; // если не поставить, то Indy будет оборачивать в koi8-r заголовки
msg.Body.Add(SMSC_LOGIN + ':' + SMSC_PASSWORD + ':' + IntToStr(id) + ':' + time + ':' + IntToStr(translit) + ',' + IntToStr(format) + ',' + senderid + ':' + phones + ':' + mes);
Connect;
Send(msg);
Disconnect;
Destroy;
end;
msg.Destroy;
end;
// Метод получения стоимости SMS
//
// обязательные параметры:
//
// phones - список телефонов через запятую или точку с запятой
// message - отправляемое сообщение
//
// необязательные параметры:
//
// translit - переводить или нет в транслит
// format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram)
// sender - имя отправителя (Sender ID)
// query - строка дополнительных параметров, добавляемая в URL-запрос ('list=79999999999:Ваш пароль: 123'#13#10 + '78888888888:Ваш пароль: 456')
//
// возвращает массив (<стоимость>, <количество sms>) либо (0, -<код ошибки>) в случае ошибки
function SMSC.get_sms_cost(phones: String; mes: String; translit: Integer = 0; format: Integer = 0; sender: String = ''; query: String = ''): TStringDynArray;
begin
Result := _smsc_send_cmd('send', 'cost=1&phones=' + _urlencode(phones) + '&mes=' + _urlencode(mes) + '&translit=' + IntToStr(translit) +
_ifs(format > 0, '&' + formats[format], '') + _ifs(sender <> '', '&sender=' + _urlencode(sender), '') + _ifs(query <> '', '&' + query, ''));
// (cost, cnt) или (0, -error)
if SMSC_DEBUG then
if StrToInt(Result[1]) > 0 then
_print_debug('Стоимость рассылки: ' + Result[0] + '. Всего SMS: ' + Result[1])
else
_print_debug('Ошибка №' + Result[1][2]);
end;
// Метод проверки статуса отправленного SMS или HLR-запроса
//
// id - ID cообщения или список ID через запятую
// phone - номер телефона или список номеров через запятую
// all - вернуть все данные отправленного SMS, включая текст сообщения (0,1 или 2)
//
// возвращает массив (для множественного запроса возвращается массив с единственным элементом, равным 1. В этом случае статусы сохраняются в
// двумерном динамическом массиве класса D2Res):
//
// для одиночного SMS-сообщения:
// (<статус>, <время изменения>, <код ошибки доставки>)
//
// для HLR-запроса:
// (<статус>, <время изменения>, <код ошибки sms>, <код IMSI SIM-карты>, <номер сервис-центра>, <код страны регистрации>, <код оператора>,
// <название страны регистрации>, <название оператора>, <название роуминговой страны>, <название роумингового оператора>)
//
// при all = 1 дополнительно возвращаются элементы в конце массива:
// (<время отправки>, <номер телефона>, <стоимость>, <sender id>, <название статуса>, <текст сообщения>)
//
// при all = 2 дополнительно возвращаются элементы <страна>, <оператор> и <регион>
//
// при множественном запросе (данные по статусам сохраняются в двумерном массиве D2Res):
// если all = 0, то для каждого сообщения или HLR-запроса дополнительно возвращается <ID сообщения> и <номер телефона>
//
// если all = 1 или all = 2, то в ответ добавляется <ID сообщения>
//
// либо массив (0, -<код ошибки>) в случае ошибки
function SMSC.get_status(id: String; phone: String; all: Integer = 0): TStringDynArray;
var
ans: String;
TZInfo: TIME_ZONE_INFORMATION;
i, idx: Integer;
begin
Result := _smsc_send_cmd('status', 'phone=' + _urlencode(phone) + '&id=' + _urlencode(id) + '&all=' + IntToStr(all));
// (status, time, err, ...) или (0, -error)
if Pos(',', id) = 0 then
begin
if SMSC_DEBUG then
if (Result[1] <> '') and (StrToInt(Result[1]) >= 0) then
begin
ans := 'Статус SMS = ' + Result[0];
GetTimeZoneInformation(TZInfo);
if StrToInt(Result[1]) > 0 then
ans := ans + ', время изменения статуса - ' + DateTimeToStr(UnixToDateTime(StrToInt64(Result[1]) - TZInfo.Bias * 60));
_print_debug(ans);
end
else
_print_debug('Ошибка №' + Result[1][2]);
idx := StrToInt(_ifs(all = 1, '9', '12'));
if (all > 0) and (Length(Result) > idx) and ((Length(Result) < idx + 5) or (Result[idx + 5] <> 'HLR')) then
begin
ans := '';
for i := 0 to Length(Result) - 1 do
ans := ans + Result[i] + _ifs(i = Length(Result) - 1, '', ',');
SetLength(Result, idx);
for i := 0 to idx - 2 do
IdStrings.SplitString(ans, ',', Result[i], ans);
Result[idx - 1] := ans;
end;
end
else
begin
if (Length(Result) = 1) and (Pos('-', Result[0]) = 3) then
Result := StrUtils.SplitString(Result[0], ',')
else
begin
SetLength(D2Res, 0);
SetLength(D2Res, Length(Result));
for i := 0 to Length(D2Res) - 1 do
D2Res[i] := StrUtils.SplitString(Result[i], ',');
SetLength(Result, 1);
Result[0] := '1';
end;
end;
end;
// Метод получения баланса
//
// без параметров
//
// возвращает баланс в виде строки или пустую строку в случае ошибки
function SMSC.get_balance: String;
var
bal: TStringDynArray;
begin
bal := _smsc_send_cmd('balance', ''); // (balance) или (0, -error)
if SMSC_DEBUG then
if Length(bal) = 1 then
_print_debug('Сумма на счете: ' + bal[0])
else
_print_debug('Ошибка №' + bal[1][2]);
if Length(bal) = 1 then
Result := bal[0]
else
Result := '';
end;
// ПРИВАТНЫЕ МЕТОДЫ
//
// Метод вызова запроса. Формирует URL и делает 3 попытки чтения
function SMSC._smsc_send_cmd(cmd: String; arg: String; files: TStringList = nil): TStringDynArray;
var
par: TIdMultiPartFormDataStream;
params: TStringDynArray;
aurl, _aurl, s, delim, VLeft, VRight, auth: String;
cnt, i: Integer;
pf: TIdFormDataField;
begin
if (SMSC_LOGIN <> '')
auth := 'login=' + _urlencode(SMSC_LOGIN) + '&psw=';
else
auth := 'apikey=';
arg := auth + _urlencode(SMSC_PASSWORD) + '&fmt=1&charset=' + SMSC_CHARSET + '&' + arg;
aurl := 'http://m.smsc.ru/sys/' + cmd + '.php';
_aurl := aurl;
with TIdHTTP.Create(nil) do
begin
cnt := 0;
repeat
if cnt > 0 then
aurl := StringReplace(_aurl, 'm.smsc.ru', 'www' + IntToStr(cnt) + '.m.smsc.ru', [rfReplaceAll])
else
Inc(cnt);
try
if SMSC_POST then
begin
par := TIdMultiPartFormDataStream.Create;
for i := 1 to files.Count do
par.AddFile('File' + IntToStr(i), files.Strings[i-1], 'application/octet-stream');
params := StrUtils.SplitString(arg, '&');
for i := 1 to Length(params) do
begin
IdStrings.SplitString(params[i-1], '=', VLeft, VRight);
pf := par.AddFormField(VLeft, VRight);
pf.Charset := SMSC_CHARSET;
pf.ContentTransfer := 'binary';
end;
s := Post(aurl, par);
par.Destroy;
end
else
s := Get(aurl + '?' + arg);
except
s := '';
end;
Inc(cnt);
until (s <> '') or (cnt > 5);
if s = '' then
begin
if SMSC_DEBUG then
_print_debug('Ошибка чтения адреса: ' + aurl + '?' + arg);
s := ','; // фиктивный ответ
end;
Destroy;
end;
delim := ',';
if cmd = 'status' then
begin
params := StrUtils.SplitString(arg, '&');
for i := 0 to Length(params) - 1 do
begin
IdStrings.SplitString(params[i], '=', VLeft, VRight);
if (VLeft = 'id') and (Pos('%2C', VRight) > 0) then // запятая в id - множественный запрос
delim := #10;
end;
end;
Result := StrUtils.SplitString(s, delim);
end;
// кодирование параметра в http-запросе
function SMSC._urlencode(str: String): String;
var
EncodeStr, UnsafeChars: String;
UStr: UTF8String;
i, j: Integer;
begin
UnsafeChars := '!"#%&''*,:;<=>?[]^`{|} ';
EncodeStr := '';
if SMSC_POST then
Result := str
else
begin
for i := 1 to Length(str) do
if (CharIsInSet(str, i, UnsafeChars) or not CharIsInSet(str, i, CharRange(Char(33), Char(126)))) then
begin
UStr := UTF8String(str[i]);
for j := 1 to Length(UStr) do
EncodeStr := EncodeStr + '%' + IntToHex(Byte(UStr[j]), 2);
end
else
EncodeStr := EncodeStr + str[i];
Result := EncodeStr;
end;
end;
// вывод отладочной информации
procedure SMSC._print_debug(str: String);
begin
with Application do MessageBox(PChar(str), '');
end;
function SMSC._ifs(cond: Boolean; val1: String; val2: String): String;
begin
if cond then
Result := val1
else
Result := val2;
end;
end.
// Examples:
// var
// sms: SMSC;
// ret: TStringDynArray;
// balance: String;
// begin
// sms := SMSC.Create;
// ret := sms.send_sms('79999999999', 'Ваш пароль: 123', 1);
// ret := sms.send_sms('79999999999', 'http://m.smsc.ru'#13#10 + 'M.SMSC.RU', 0, '', 0, 0, '', 'maxsms=3');
// ret := sms.send_sms('79999999999', '0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101', 0, '', 0, 5);
// ret := sms.send_sms('79999999999', '', 0, '', 0, 3);
// ret := sms.send_sms('dest@mysite.com', 'Ваш пароль: 123', 0, 0, 0, 8, 'source@mysite.com', 'subj=Confirmation');
// ret := sms.get_sms_cost('79999999999', 'Вы успешно зарегистрированы!');
// sms.send_sms_mail('79999999999', 'Ваш пароль: 123', 0, '0101121000', 0, 1);
// ret := sms.get_status(12345, '79999999999');
// balance := sms.get_balance;
// sms.Destroy;
// end;
Пример использования библиотеки:
uses smsc_api; ... var sms: SMSC; ret: TStringDynArray; balance: String; ... begin ... sms := SMSC.Create; ... ret := sms.send_sms('79999999999', 'Ваш пароль: 123', 1); ... ret := sms.send_sms('79999999999', 'http://m.smsc.ru'#13#10 + 'M.SMSC.RU', 0, '', 0, 0, '', 'maxsms=3'); ... ret := sms.send_sms('79999999999', '0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101', 0, '', 0, 5); ... ret := sms.send_sms('79999999999', '', 0, '', 0, 3); ... ret := sms.get_sms_cost('79999999999', 'Вы успешно зарегистрированы!'); ... ret := sms.get_status(12345, '79999999999'); ... balance := sms.get_balance; ... // отправка SMS через e-mail sms.send_sms_mail('79999999999', 'Ваш пароль: 123'); ... sms.Destroy; ... end;
Для C++ Builder
Скачать файл библиотеки:
smsc_api.cpp
Исходный код библиотеки:
// M.SMSC.RU API для C++ Builder (m.smsc.ru) версия 2.1 (03.07.2019)
#include <vcl.h>
#include <IdHTTP.hpp>
#include <IdMessage.hpp>
#include <IdSMTP.hpp>
#include <DateUtils.hpp>
#include <IdStrings.hpp>
# include <System.StrUtils.hpp>
// Константы с параметрами отправки
const char* SMSC_LOGIN = ""; // логин клиента
const char* SMSC_PASSWORD = ""; // пароль клиента. Если передан пустой логин, то SMSC_PASSWORD используется, как API ключ, вместо логина и пароля
Boolean SMSC_POST = false; // использовать метод POST
const char* SMSC_CHARSET =
#ifdef _DELPHI_STRING_UNICODE
"utf-8";
#else
"windows-1251";
#endif // кодировка сообщения (utf-8 или koi8-r), по умолчанию используется windows-1251
const Boolean SMSC_DEBUG = false; // флаг отладки
// Константы для отправки SMS по SMTP
const char* SMTP_FROM = "api@m.smsc.ru"; // e-mail адрес отправителя
const char* SMTP_SERVER = "send.m.smsc.ru"; // адрес smtp сервера
const char* SMTP_LOGIN = ""; // логин для smtp сервера
const char* SMTP_PASSWORD = ""; // пароль для smtp сервера
typedef DynamicArray < DynamicArray < String > > T2DStringDynArray;
class SMSC {
public:
// Динамический двумерный строковый массив
T2DStringDynArray D2Res;
// Общедоступные методы класса SMSС
//
// Метод отправки SMS
//
// обязательные параметры:
//
// phones - список телефонов через запятую или точку с запятой
// mes - отправляемое сообщение
//
// необязательные параметры:
//
// translit - переводить или нет в транслит
// time - необходимое время доставки в виде строки (DDMMYYhhmm, h1-h2, 0ts, +m)
// id - идентификатор сообщения. Представляет собой 32-битное число в диапазоне от 1 до 2147483647.
// format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram)
// sender - имя отправителя (Sender ID).
// query - строка дополнительных параметров, добавляемая в URL-запрос ("valid=01:00&maxsms=3")
// files - массив путей к файлам при отправке mms или e-mail сообщений
//
// возвращает массив (<id>, <количество sms>, <стоимость>, <баланс>) в случае успешной отправки
// либо (<id>, -<код ошибки>) в случае ошибки
TStringDynArray send_sms(String phones, String mes, int translit = 0, String time = "", int id = 0, int format = 0, String sender = "", String query = "", TStringList *files = NULL)
{
TStringDynArray m;
if (files != NULL)
SMSC_POST = true;
String formats[13] = {"flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"};
m = _smsc_send_cmd("send", "cost=3&phones=" + _urlencode(phones) + "&mes=" + _urlencode(mes) + "&id=" + IntToStr(id) + "&translit=" + IntToStr(translit) +
(format > 0 ? "&" + formats[format-1] : String("")) + (sender != "" ? "&sender=" + _urlencode(sender) : String("")) + (time != "" ? "&time=" +
_urlencode(time) : String("")) + (query != "" ? "&" + query : String("")), files);
// (id, cnt, cost, balance) или (id, -error)
if (SMSC_DEBUG)
if (StrToInt(m[1]) > 0)
_print_debug("Сообщение отправлено успешно. ID: " + m[0] + ", всего SMS: " + m[1] +
", стоимость: " + m[2] + ", баланс: " + m[3]);
else
_print_debug("Ошибка №" + m[1].SubString(2, 1) + ", ID: " + m[0]);
return m;
}
// SMTP версия метода отправки SMS
void send_sms_mail(String phones, String mes, int translit = 0, String time = "", int id = 0, int format = 0, String senderid = "")
{
TIdMessage* msg = new TIdMessage(0);
TIdSMTP* idsmtp = new TIdSMTP(0);
idsmtp->Port = 25;
idsmtp->Host = SMTP_SERVER;
if (SMTP_LOGIN != "") {
idsmtp->Username = SMTP_LOGIN;
idsmtp->Password = SMTP_PASSWORD;
}
msg->Recipients->EMailAddresses = "send@send.m.smsc.ru";
msg->From->Address = SMTP_FROM;
msg->ContentType = "text/plain";
msg->CharSet = SMSC_CHARSET;
SysLocale.PriLangID = LANG_SYSTEM_DEFAULT; // если не поставить, то Indy будет оборачивать в koi8-r заголовки
msg->Body->Add(SMSC_LOGIN + String(':') + SMSC_PASSWORD + String(':') + IntToStr(id) + String(':') + time + String(':') + IntToStr(translit) + String(',') + IntToStr(format) + String(',') + senderid + String(':') + phones + String(':') + mes);
idsmtp->Connect();
idsmtp->Send(msg);
idsmtp->Disconnect();
idsmtp->Free();
msg->Free();
}
// Метод получения стоимости SMS
//
// обязательные параметры:
//
// phones - список телефонов через запятую или точку с запятой
// message - отправляемое сообщение
//
// необязательные параметры:
//
// translit - переводить или нет в транслит
// format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram)
// sender - имя отправителя (Sender ID)
// query - строка дополнительных параметров, добавляемая в URL-запрос ("list=79999999999:Ваш пароль: 123\n78888888888:Ваш пароль: 456")
//
// возвращает массив (<стоимость>, <количество sms>) либо (0, -<код ошибки>) в случае ошибки
TStringDynArray get_sms_cost(String phones, String mes, int translit = 0, int format = 0, String sender = "", String query = "")
{
TStringDynArray m;
String formats[13] = {"flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"};
m = _smsc_send_cmd("send", "cost=1&phones=" + _urlencode(phones) + "&mes=" + _urlencode(mes) + "&translit=" + IntToStr(translit) +
(format > 0 ? "&" + formats[format-1] : String("")) + (sender != "" ? "&sender=" + _urlencode(sender) : String("")) + (query != "" ? "&" + query : String("")));
// (cost, cnt) или (0, -error)
if (SMSC_DEBUG)
if (StrToInt(m[1]) > 0)
_print_debug("Стоимость рассылки: " + m[0] + ". Всего SMS: " + m[1]);
else
_print_debug("Ошибка №" + m[1].SubString(2, 1));
return m;
}
// Метод проверки статуса отправленного SMS или HLR-запроса
//
// id - ID cообщения или список ID через запятую
// phone - номер телефона или список номеров через запятую
// all - вернуть все данные отправленного SMS, включая текст сообщения (0,1 или 2)
//
// возвращает массив (для множественного запроса возвращается массив с единственным элементом, равным 1. В этом случае статусы сохраняются в
// двумерном динамическом массиве класса D2Res):
//
// для одиночного SMS-сообщения:
// (<статус>, <время изменения>, <код ошибки доставки>)
//
// для HLR-запроса:
// (<статус>, <время изменения>, <код ошибки sms>, <код IMSI SIM-карты>, <номер сервис-центра>, <код страны регистрации>, <код оператора>,
// <название страны регистрации>, <название оператора>, <название роуминговой страны>, <название роумингового оператора>)
//
// при all = 1 дополнительно возвращаются элементы в конце массива:
// (<время отправки>, <номер телефона>, <стоимость>, <sender id>, <название статуса>, <текст сообщения>)
//
// при all = 2 дополнительно возвращаются элементы <страна>, <оператор> и <регион>
//
// при множественном запросе (данные по статусам сохраняются в двумерном массиве D2Res):
// если all = 0, то для каждого сообщения или HLR-запроса дополнительно возвращается <ID сообщения> и <номер телефона>
//
// если all = 1 или all = 2, то в ответ добавляется <ID сообщения>
//
// либо массив (0, -<код ошибки>) в случае ошибки
TStringDynArray get_status(String id, String phone, int all = 0)
{
TIME_ZONE_INFORMATION TZInfo;
TStringDynArray m;
String ans;
int i;
m = _smsc_send_cmd("status", "phone=" + _urlencode(phone) + "&id=" + _urlencode(id) + "&all=" + IntToStr(all));
// (status, time, err, ...) или (0, -error)
if (id.Pos(",") == 0) {
if (SMSC_DEBUG)
if ((m[1] != "") && (StrToInt(m[1]) >= 0))
{
String ans = "Статус SMS = " + m[0];
GetTimeZoneInformation(&TZInfo);
if (StrToInt(m[1]) > 0)
ans = ans + ", время изменения статуса - " + DateTimeToStr(UnixToDateTime(StrToInt64(m[1]) - TZInfo.Bias * 60));
_print_debug(ans);
}
else
_print_debug("Ошибка №" + m[1].SubString(2, 1));
int idx = all == 1 ? 9 : 12;
if (all > 0 && m.Length > idx && (m.Length < idx + 5 || m[idx + 5] != "HLR"))
{
ans = "";
for (i = 0; i < m.Length; i++)
ans += m[i] + (i == m.Length - 1 ? "" : ",");
m.Length = idx;
for (i = 0; i < idx - 1; i++)
SplitString(ans, ",", m[i], ans);
m[idx - 1] = ans;
}
}
else {
if (m.Length == 1 && m[0].Pos("-") == 3)
return SplitString(m[0], ",");
D2Res.Length = 0;
D2Res.Length = m.Length;
for (i = 0; i < D2Res.Length; i++)
D2Res[i] = SplitString(m[i], ",");
m.Length = 1;
m[0] = "1";
}
return m;
}
// Метод получения баланса
//
// без параметров
//
// возвращает баланс в виде строки или пустую строку в случае ошибки
String get_balance(void)
{
TStringDynArray m;
m = _smsc_send_cmd("balance", ""); // (balance) или (0, -error)
if (SMSC_DEBUG)
if (m.Length == 1)
_print_debug("Сумма на счете: " + m[0]);
else
_print_debug("Ошибка №" + m[1].SubString(2, 1));
return m.Length == 1 ? m[0] : String("");
}
private:
// Приватные методы класса SMSС
//
// Метод вызова запроса. Формирует URL и делает 3 попытки чтения
TStringDynArray _smsc_send_cmd(String cmd, String arg, TStringList *files = NULL)
{
TIdHTTP* idhttp = new TIdHTTP(0);
String s, delim, pl, pr, url, _url;
int i, cnt = 0;
arg = (String(SMSC_LOGIN) != "" ? "login=" + _urlencode(SMSC_LOGIN) + "&psw=" : "apikey=") + _urlencode(SMSC_PASSWORD) + "&fmt=1&charset=" + String(SMSC_CHARSET) + "&" + arg;
url = _url = "http://m.smsc.ru/sys/" + cmd + ".php";
do
{
if (cnt++)
url = StringReplace(_url, "m.smsc.ru", "www" + IntToStr(cnt) + ".m.smsc.ru", TReplaceFlags() << rfReplaceAll);
try {
if (SMSC_POST) {
TIdMultiPartFormDataStream *par = new TIdMultiPartFormDataStream();
for (i = 0; i < files->Count; i++)
par->AddFile("File" + IntToStr(i), files->Strings[i], "application/octet-stream");
TStringDynArray params = SplitString(arg, "&");
String VLeft, VRight;
TIdFormDataField *pf;
for (i = 0; i < params.Length; i++) {
SplitString(params[i], "=", VLeft, VRight);
pf = par->AddFormField(VLeft, VRight);
pf->Charset = SMSC_CHARSET;
pf->ContentTransfer = "binary";
}
s = idhttp->Post(url, par);
delete par;
par = NULL;
}
else
s = idhttp->Get(url + "?" + arg);
}
catch (...) {
s = "";
}
}
while ((s == "") && (cnt < 5));
if (s == "") {
if (SMSC_DEBUG)
_print_debug("Ошибка чтения адреса: " + url + "?" + arg);
s = ","; // фиктивный ответ
}
delete idhttp;
idhttp = NULL;
delim = ",";
if (cmd == "status") {
TStringDynArray par = SplitString(arg, "&");
for (i = 0; i < par.Length; i++) {
SplitString(par[i], "=", pl, pr);
if (pl == "id" && pr.Pos("%2C") > 1) // запятая в id - множественный запрос
delim = "\n";
}
}
return SplitString(s, delim);
}
// кодирование параметра в http-запросе
String _urlencode(String str)
{
if (SMSC_POST)
return str;
String UnsafeChars = "!"#%&'*,:;<=>?[]^`{|} ";
String EncodeStr = "";
UTF8String UStr;
int i, j;
for (i = 1; i <= str.Length(); i++)
if (CharIsInSet(str, i, UnsafeChars) || !CharIsInSet(str, i, CharRange(Char(33), Char(126)))) {
UStr = str[i];
for (j = 1; j <= UStr.Length(); j++)
EncodeStr += "%" + IntToHex(Byte(UStr[j]), 2);
}
else
EncodeStr += str[i];
return EncodeStr;
}
// вывод отладочной информации
void _print_debug(String str)
{
ShowMessage(str);
}
};
// Examples:
// TStringDynArray ret;
// SMSC* sms = new SMSC;
// String balance;
//
// ret = sms->send_sms("79999999999", "Ваш пароль: 123", 1);
// ret = sms->send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, "", 0, 0, "", "maxsms=3");
// ret = sms->send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, "", 0, 5);
// ret = sms->send_sms("79999999999", "", 0, "", 0, 3);
// ret = sms->send_sms("dest@mysite.com", "Ваш пароль: 123", 0, 0, 0, 8, "source@mysite.com", "subj=Confirmation");
// ret = sms->get_sms_cost("79999999999", "Вы успешно зарегистрированы!");
// sms->send_sms_mail("79999999999", "Ваш пароль: 123", 0, "0101121000");
// ret = sms->get_status(12345, "79999999999");
// balance = sms->get_balance();
//
// delete sms;
Пример использования библиотеки:
#include <smsc_api.cpp> ... TStringDynArray ret; SMSC* sms = new SMSC; String balance; ... ret = sms->send_sms("79999999999", "Ваш пароль: 123", 1); ... ret = sms->send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, "", 0, 0, "", "maxsms=3"); ... ret = sms->send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, "", 0, 5); ... ret = sms->send_sms("79999999999", "", 0, "", 0, 3); ... sms->send_sms_mail("79999999999", "Ваш пароль: 123", 0, "0101121000"); ... ret = sms->get_status(12345, "79999999999"); ... balance = sms->get_balance(); ... ret = sms->get_sms_cost("79999999999", "Вы успешно зарегистрированы!"); ... delete sms;
Для Microsoft Visual C++
Скачать файл библиотеки:
smsc_api_vc.cpp
Исходный код библиотеки:
// M.SMSC.RU API для Microsoft Visual C++ (m.smsc.ru) версия 1.3 (03.07.2019)
#define _AFXDLL
#include <afxinet.h>
#include <vector>
#include <Shlwapi.h>
#include <Strsafe.h>
using namespace std;
// Константы с параметрами отправки
const CString SMSC_LOGIN = ""; // логин клиента
const CString SMSC_PASSWORD = ""; // пароль клиента. Если передан пустой логин, то SMSC_PASSWORD используется, как API ключ, вместо логина и пароля
const bool SMSC_HTTPS = false; // использовать протокол HTTPS
const bool SMSC_POST = false; // использовать метод POST
const CString SMSC_CHARSET =
#if defined _UNICODE || defined UNICODE
"utf-8";
#else
"windows-1251";
#endif // кодировка сообщения (utf-8 или koi8-r), по умолчанию используется windows-1251
const bool SMSC_DEBUG = false; // флаг отладки
class SMSC {
public:
// Общедоступные методы класса SMSС
//
// Метод отправки SMS
//
// обязательные параметры:
//
// phones - список телефонов через запятую или точку с запятой
// message - отправляемое сообщение
//
// необязательные параметры:
//
// translit - переводить или нет в транслит
// time - необходимое время доставки в виде строки (DDMMYYhhmm, h1-h2, 0ts, +m)
// id - идентификатор сообщения. Представляет собой 32-битное число в диапазоне от 1 до 2147483647.
// format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram)
// sender - имя отправителя (Sender ID).
// query - строка дополнительных параметров, добавляемая в URL-запрос ("valid=01:00&maxsms=3")
//
// возвращает массив (<id>, <количество sms>, <стоимость>, <баланс>) в случае успешной отправки
// либо (<id>, -<код ошибки>) в случае ошибки
vector<CString> send_sms(CString phones, CString message, int translit = 0, CString time = "", int id = 0, int format = 0, CString sender = "", CString query = "")
{
CString tt, ir;
CString formats[13] = {"flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"};
ir.Format((CString)"%i", id);
tt.Format((CString)"%i", translit);
vector<CString> m = _smsc_send_cmd("send", "cost=3&phones=" + (CString)_urlencode(phones) +
"&mes=" + (CString)_urlencode(message) + "&id=" + ir + "&translit=" + tt + (format > 0 ? "&" + formats[format - 1] : "") +
(sender != "" ? "&sender=" + (CString)_urlencode(sender) : "") + (time != "" ? "&time=" + (CString)_urlencode(time) : "") +
(query != "" ? "&" + query : ""));
// (id, cnt, cost, balance) или (id, -error)
if (SMSC_DEBUG)
if (m[1] > "0")
_print_debug("Сообщение отправлено успешно. ID: " + m[0] + ", всего SMS: " + m[1] +
", стоимость: " + m[2] + ", баланс: " + m[3]);
else
_print_debug("Ошибка №" + m[1].Mid(1, 1) + ", ID: " + m[0]);
return m;
};
// Метод получения стоимости SMS
//
// обязательные параметры:
//
// phones - список телефонов через запятую или точку с запятой
// message - отправляемое сообщение
//
// необязательные параметры:
//
// translit - переводить или нет в транслит
// format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram)
// sender - имя отправителя (Sender ID)
// query - строка дополнительных параметров, добавляемая в URL-запрос ("list=79999999999:Ваш пароль: 123\n78888888888:Ваш пароль: 456")
//
// возвращает массив (<стоимость>, <количество sms>) либо (0, -<код ошибки>) в случае ошибки
vector<CString> get_sms_cost(CString phones, CString message, int translit = 0, int format = 0, CString sender = "", CString query = "")
{
CString tt;
CString formats[13] = {"flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1", "", "tg=1"};
tt.Format((CString)"%i", translit);
vector<CString> m = _smsc_send_cmd("send", "cost=1&phones=" + (CString)_urlencode(phones) +
"&mes=" + (CString)_urlencode(message) + "&translit=" + tt + (format > 0 ? "&" + formats[format-1] : "") +
(sender != "" ? "&sender=" + (CString)_urlencode(sender) : "") + (query != "" ? "&" + query : ""));
// (cost, cnt) или (0, -error)
if (SMSC_DEBUG)
if (m[1] > "0")
_print_debug("Стоимость рассылки: " + m[0] + ". Всего SMS: " + m[1]);
else
_print_debug("Ошибка №" + m[1].Mid(1, 1));
return m;
};
// Метод проверки статуса отправленного SMS или HLR-запроса
//
// id - ID cообщения
// phone - номер телефона
//
// возвращает массив:
// для отправленного SMS (<статус>, <время изменения>, <код ошибки sms>)
// для HLR-запроса (<статус>, <время изменения>, <код ошибки sms>, <код IMSI SIM-карты>, <номер сервис-центра>, <код страны регистрации>,
// <код оператора абонента>, <название страны регистрации>, <название оператора абонента>, <название роуминговой страны>,
// <название роумингового оператора>)
//
// При all = 1 дополнительно возвращаются элементы в конце массива:
// (<время отправки>, <номер телефона>, <стоимость>, <sender id>, <название статуса>, <текст сообщения>)
//
// либо (0, -<код ошибки>) в случае ошибки
vector<CString> get_status(int id, CString phone, int all = 0)
{
CString ans, ir, tr;
int i;
ir.Format((CString)"%i", id);
tr.Format((CString)"%i", all);
vector<CString> m = _smsc_send_cmd("status", "phone=" + (CString)_urlencode(phone) + "&id=" + ir + (all > 0 ? "&all=" + tr : ""));
// (status, time, err) или (0, -error)
if (SMSC_DEBUG)
if ((m[1] != "") && (m[1] >= "0"))
{
time_t tm = _ttoi(m[1]);
struct tm ltm;
TCHAR st[100] = {0};
localtime_s(<m, &tm);
_stprintf_s(st, 100, (CString)"%2d.%2d.%d %2d:%2d:%2d", ltm.tm_mday, (ltm.tm_mon) + 1, (ltm.tm_year) + 1900, ltm.tm_hour, ltm.tm_min, ltm.tm_sec);
_print_debug( "Статус SMS = " + m[0] + ", время изменения статуса - " + st);
}
else
_print_debug("Ошибка №" + m[1].Mid(1, 1));
if (all == 1 && m.size() > 9 && (m.size() < 14 || m[14] != "HLR"))
{
ans = m[0];
for (i = 1; i < (int)m.size(); i++)
ans += "," + m[i];
m.clear();
int cp = 0;
for (i = 0; i < 8; i++)
m.push_back(ans.Tokenize((CString)",", cp));
m.push_back(ans.Mid(cp));
}
return m;
};
// Метод получения баланса
//
// без параметров
//
// возвращает баланс в виде строки или пустую строку в случае ошибки
CString get_balance(void)
{
vector<CString> m = _smsc_send_cmd("balance", ""); // (balance) или (0, -error)
if (SMSC_DEBUG)
if (m.size() == 1)
_print_debug("Сумма на счете: " + m[0]);
else
_print_debug("Ошибка №" + m[1].Mid(1, 1));
return m.size() == 1 ? m[0] : "";
};
private:
// Приватные методы класса SMSС
//
// Метод вызова запроса. Формирует URL и делает 3 попытки чтения
vector<CString> _smsc_send_cmd(CString cmd, CString arg)
{
vector<CString> m;
int cnt = 0;
CString url, _url;
arg = (SMSC_LOGIN != "" ? "login=" + (CString)_urlencode(SMSC_LOGIN) + "&psw=" : "apikey=") + (CString)_urlencode(SMSC_PASSWORD) + "&fmt=1&charset=" + SMSC_CHARSET + "&" + arg;
url = _url = (SMSC_HTTPS ? "https" : "http") + (CString)"://m.smsc.ru/sys/" + cmd + ".php";
CString sr, ot, res, strcnt;
INTERNET_PORT pt;
DWORD st;
char sz[1024] = {0};
CInternetSession ses((CString)"Visual C++", PRE_CONFIG_INTERNET_ACCESS);
CHttpConnection *ds;
AfxParseURL(url + '?' + arg, st, sr, ot, pt);
ds = ses.GetHttpConnection(sr, NULL, pt);
do
{
if (cnt++) {
strcnt.Format((CString)"%i", cnt);
url = _url;
url.Replace((CString)"m.smsc.ru/", (CString)"www" + strcnt + ".m.smsc.ru/");
AfxParseURL(url + '?' + arg, st, sr, ot, pt);
ds = ses.GetHttpConnection(sr, NULL, pt);
}
CHttpFile *pc;
try {
if (SMSC_POST || arg.GetLength() > 2000)
{
pc = ds->OpenRequest(0, "/sys/" + cmd + ".php", NULL, 1, NULL, NULL, SMSC_HTTPS ? INTERNET_FLAG_SECURE : INTERNET_FLAG_EXISTING_CONNECT);
pc->SendRequest((CString)"Content-Type: application/x-www-form-urlencoded", (LPVOID)(LPCSTR)(CStringA)arg, arg.GetLength());
}
else
{
pc = ds->OpenRequest(1, ot, NULL, 1, NULL, NULL, SMSC_HTTPS ? INTERNET_FLAG_SECURE : INTERNET_FLAG_EXISTING_CONNECT);
pc->SendRequest();
}
pc->Read(sz, 1024);
}
catch (CInternetException* e) {
}
res = sz;
pc->Close();
}
while ((res == "") && (cnt < 5));
if (res == "")
{
if (SMSC_DEBUG)
_print_debug("Ошибка чтения адреса: " + url + "?" + arg);
res = ","; // фиктивный ответ
}
ds->Close();
ses.Close();
return _explode(res);
};
// кодирование параметра в http-запросе
CStringA _urlencode(CString s_in)
{
#if defined _UNICODE || defined UNICODE
const WCHAR *pt_utf16 = s_in;
const size_t cch_utf16m = INT_MAX - 1;
size_t cch_utf16;
::StringCchLengthW(pt_utf16, cch_utf16m, &cch_utf16);
++cch_utf16;
int cb_utf8 = ::WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, pt_utf16, static_cast<int>(cch_utf16), NULL, 0, NULL, NULL);
CStringA s_utf8;
CHAR *pt_utf8 = s_utf8.GetBuffer(cb_utf8);
::WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, pt_utf16, static_cast<int>(cch_utf16), pt_utf8, cb_utf8, NULL, NULL);
s_utf8.ReleaseBuffer();
return _encode(s_utf8);
#else
return _encode(s_in);
#endif
};
CStringA _encode(CStringA s_in)
{
CStringA s_out;
for (int i = 0; i < s_in.GetLength(); i++)
{
CHAR ch = s_in[i];
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
s_out.AppendChar(ch);
else
{
BYTE ccv = static_cast<BYTE>(ch);
CHAR eb[4];
sprintf_s(eb, sizeof(eb), "%%%02X", ccv);
s_out.Append(eb);
}
}
return s_out;
};
// вывод отладочной информации
void _print_debug(CString str)
{
MessageBox(NULL, str, NULL, MB_OK);
};
// разделение строки, возвращаемой сервером, на массив строк
vector<CString> _explode(CString str)
{
int cp = 0;
vector<CString> m;
do
{
m.push_back(str.Tokenize((CString)",", cp));
}
while (m.back() != "");
m.pop_back();
return m;
};
};
// Examples:
// SMSC *sms = new SMSC();
// СString balance;
// vector<CString> ret;
//
// ret = sms->send_sms("79999999999", "Ваш пароль: 123", 1);
// ret = sms->send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, "", 0, 0, "", "maxsms=3");
// ret = sms->send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, "", 0, 5);
// ret = sms->send_sms("79999999999", "", 0, "", 0, 3);
// ret = sms->get_sms_cost("79999999999", "Вы успешно зарегистрированы!");
// ret = sms->get_status(12345, "79999999999");
// balance = sms->get_balance();
//
// delete sms;
Пример использования библиотеки:
#include "smsc_api_vc.cpp" ... SMSC *sms = new SMSC(); СString balance; vector<CString> ret; ... ret = sms->send_sms("79999999999", "Ваш пароль: 123", 1); ... ret = sms->send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, "", 0, 0, "", "maxsms=3"); ... ret = sms->send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, "", 0, 5); ... ret = sms->send_sms("79999999999", "", 0, "", 0, 3); ... ret = sms->get_sms_cost("79999999999", "Вы успешно зарегистрированы!"); ... ret = sms->get_status(12345, "79999999999"); ... balance = sms->get_balance(); ... delete sms;
Для NodeJS
Скачать файл библиотеки:
smsc_api.js
Исходный код библиотеки:
// M.SMSC.RU API (m.smsc.ru) версия 1.2 (08.11.2021)
var Api = function () { 'use strict'; var http = require('http'); var qs = require('querystring'); var FormData = require('form-data'); var fs = require('fs');
var ssl = false, def_fmt = 3, host = 'm.smsc.ru', charset = 'utf-8';
var login = "", // логин клиента password = "", // пароль клиента. Если передан пустой логин, то SMSC_PASSWORD используется, как API ключ, вместо логина и пароля sender, log = console.log;
var PHONE_TYPES = { 'string' : 1, 'number' : 2 };
var get_host = function (www) { if (!www) www = ''; return (ssl? 'https://' : 'http://') + www + host + '/sys/'; };
var isInArr = function (arr, val) { if (!arr || !arr.length) return false; return arr.indexOf(val) !== -1; };
var convert_data = function (data, notConvert) { if (data.fmt) delete data.fmt; if (data.msg) { data.mes = data.msg; delete data.msg; } if (data.message) { data.mes = data.message; delete data.message; } if (data.phone && !isInArr(notConvert, 'phone')) { data.phones = data.phone; delete data.phone; } if (data.number) { data.phones = data.number; delete data.number; }
if (data.list) { var list = ''; for (var i in data.list) { list += i + ':' + data.list[i]+'\n'; } data.list = list; delete data.mes; }
if (data.phones && !(typeof data.phones in PHONE_TYPES)) data.phones = data.phones.join(','); };
var convert_files = function (form, data) { if (!data.files) return;
if (typeof data.files === 'string') { var f = data.files; var bin = fs.readFileSync(f); form.append(i, bin, { filename : f }); return; }
for (var i in data.files) { var f = data.files[i]; var bin = fs.readFileSync(f); form.append(i, bin, { filename : f }); }
delete data.files; };
var read_url = function (prs, clb, notConvert) { var fmt = prs.fmt ? prs.fmt : def_fmt;
var fd = new FormData(); fd.append('fmt', fmt);
if (login !== '') { fd.append('login', login); fd.append('psw', password); } else fd.append('apikey', password);
fd.append('charset', charset); if (prs.type) fd.append(prs.type, 1);
if (prs.data) { convert_data(prs.data, notConvert);
if (prs.data.files) { convert_files(fd, prs.data); }
for (var i in prs.data) { fd.append(i, prs.data[i]); } }
var www = ''; var count = 0; var submit = function () { fd.submit(get_host(www) + prs.file, function (err, res) {
if (err) { if (count++ < 5) { www = 'www'+(count !== 1 ? count : '')+'.'; submit(); } else { var error = { error : "Connection Error", error_code : 100 }; clb(error, JSON.stringify(error), error.error, error.error_code); } return; }
res.setEncoding(charset); var full_data = '';
res.on('data', function (data) { full_data += data; });
res.on('end', function (data) { if (clb) { var d = JSON.parse(full_data); clb(d, full_data, d.error_code ? d.error : null, d.error_code ? d.error_code : null); } });
}); };
submit(); return; };
// Конфигурирование this.configure = function (prs) { ssl = !!prs.ssl; login = prs.login; password = prs.password; if (prs.charset) charset = prs.charset; };
// Отправка сообщения любого типа (data — объект, включающий параметры отправки. Подробнее смотрите в документации к API) this.send = function (type, data, clb) { if (typeof data !== 'object') data = {}; var opts = { file : 'send.php', data : data }; opts['type'] = type; read_url(opts, clb); };
// Отправка простого SMS сообщения this.send_sms = function (data, clb) { if (typeof data !== 'object') data = {}; read_url({ file : 'send.php', data : data }, clb); };
// Получение статуса сообщения this.get_status = function (data, clb) { if (data.phones) { data.phone = data.phones; delete data.phones; } if (data.number) { data.phone = data.number; delete data.number; }
if (data.phone && !(typeof data.phone in PHONE_TYPES)) { data.phone = data.phone.join(','); }
read_url({ file : 'status.php', data : data }, clb, ['phone']); };
// Получение баланса this.get_balance = function (clb) { read_url({ file : 'balance.php', data : { cur : 1 } }, function (b, r, e, c) { clb(e ? 0 : b.balance, r, e, c); }); };
// Получение стоимости сообщения this.get_sms_cost = function (data, clb) { if (typeof data !== 'object') data = {}; if (!data.cost) data.cost = 1; read_url({ file : 'send.php', data : data }, function (b, r, e, c) { clb(e ? 0 : b.cost, r, e, c); }); };
// Запрос к API this.raw = function (file, data, clb) { read_url({ file : file, data : data }, clb); };
// Тестирование подключения и данных авторизации this.test = function (clb) { read_url({ file : 'balance.php' }, function (d, r, err) { clb(err); }); };
};
module.exports = new Api();
Пример использования библиотеки:
var smsc = require('./smsc/smsc.js');
smsc.configure({ login : 'alex', password : '123', //ssl : true/false, //charset : 'utf-8', });
// Проверка авторизации smsc.test(function (err) { if (err) return console.log('error: ' + err); ... });
// Отправка e-mail smsc.send('mail', { phones : 'alex@mysite.ru', mes : 'Тестовое сообщение', subj : 'Тема сообщения', sender : 'alex2@mysite.ru', }, function (data, raw, err, code) { if (err) return console.log(err, 'code: '+code); console.log(data); // object // console.log(raw); // string in JSON format });
// Отправка MMS smsc.send('mms', { phones : '79999999999', mes : 'Тестовое сообщение', fmt : 2, files : [ 'files/123.png' ] }, function (data, raw, err, code) { if (err) return console.log(err, 'code: '+code); console.log(data); // object // console.log(raw); // string in JSON format });
// Отправка списка SMS сообщений smsc.send_sms({ list : { '79999999999' : 'Hello, Alex!', '79999999999' : 'Hello, Petr!' } }, function (data, raw, err, code) { if (err) return console.log(err, 'code: '+code); console.log(data); // object console.log(raw); // string in JSON format });
// Отправка SMS smsc.send_sms({ phones : ['79999999999', '79999999999'], mes : 'Привет!' }, function (data, raw, err, code) { if (err) return console.log(err, 'code: '+code); console.log(data); // object console.log(raw); // string in JSON format });
// Обращение к скриптам API smsc.raw('send.php', { phones : '79999999999,79999999999', mes : 'Hello!' }, function (data, raw, err, code) { if (err) return console.log(err, 'code: '+code); console.log(data); // object console.log(raw); // string in JSON format });
// Получение баланса smsc.get_balance(function (balance, raw, err, code) { if (err) return console.log(err, 'code: '+code); console.log(balance); });
// Получение статуса сообщений smsc.get_status({ phones : 79999999999, id : 111, all : 1 }, function (status, raw, err, code) { if (err) return console.log(err, 'code: '+code); console.log(status); });
// Получение стоимости сообщений smsc.get_sms_cost({ phones : '79999999999', mes : 'Hello, World!', cost : 1 // default 1 }, function (status, raw, err, code) { if (err) return console.log(err, 'code: '+code); console.log(raw); });
Для С
Скачать файл библиотеки:
smsc_api.c
Исходный код библиотеки:
/* M.SMSC.RU cLib smsc API v. 0.0.2 (03.07.2019) */
#include <stdio.h> #include <stdlib.h> #include <curl/curl.h> #include <string.h>
#ifndef SMSC_API_H #define SMSC_API_H
#define UNICODE // Константы с параметрами отправки
static char* const SMSC_LOGIN = "";// логин клиента static char* const SMSC_PASSWORD = "";// пароль клиента. Если передан пустой логин, то SMSC_PASSWORD используется, как API ключ, вместо логина и пароля static char const SMSC_HTTPS = 1;// использовать протокол HTTPS static char SMSC_POST = 0;// использовать метод POST static char* const SMSC_CHARSET = #if defined _UNICODE || defined UNICODE "utf-8"; #else "windows-1251"; #endif // кодировка сообщения (utf-8 или koi8-r), по умолчанию используется windows-1251 static char const SMSC_DEBUG = 1; // флаг отладки
// Константы для отправки SMS по SMTP static char* const SMTP_FROM = "api@m.smsc.ru"; // e-mail адрес отправителя static char* const SMTP_SERVER = "send.m.smsc.ru"; // адрес smtp сервера static char* const SMTP_LOGIN = ""; // логин для smtp сервера static char* const SMTP_PASSWORD = ""; // пароль для smtp сервера
typedef char* string_t;
// Функция отправки SMS // // обязательные параметры: // // phones - список телефонов через запятую или точку с запятой // message - отправляемое сообщение // // необязательные параметры: // // translit - переводить или нет в транслит (1,2 или 0) // time - необходимое время доставки в виде строки (DDMMYYhhmm, h1-h2, 0ts, +m) // id - идентификатор сообщения. Представляет собой 32-битное число в диапазоне от 1 до 2147483647. // format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram) // sender - имя отправителя (Sender ID). // query - строка дополнительных параметров, добавляемая в URL-запрос ("valid=01:00&maxsms=3&tz=2") // files - массив путей к файлам для отправки mms или e-mail сообщений // // возвращает <id>, <количество sms>, <стоимость>, <баланс> в случае успешной отправки // либо <id>, -<код ошибки> в случае ошибки
string_t send_sms (string_t phones, string_t message, int translit, string_t time, int id, int format, string_t sender, string_t query, string_t files);
// SMTP версия метода отправки SMS void send_sms_mail(string_t phones, string_t mes, int translit, string_t time, int id, int format, string_t sender);
// Получение стоимости SMS // // обязательные параметры: // // phones - список телефонов через запятую или точку с запятой // message - отправляемое сообщение // // необязательные параметры: // // translit - переводить или нет в транслит // format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc, 13 - telegram) // sender - имя отправителя (Sender ID) // query - строка дополнительных параметров, добавляемая в URL-запрос ("list=79999999999:Ваш пароль: 123\n78888888888:Ваш пароль: 456") // // возвращает <стоимость>, <количество sms> либо 0, -<код ошибки> в случае ошибки
string_t get_sms_cost(string_t phones, string_t mes, int translit, int format, string_t sender, string_t query);
// Проверка статуса отправленного SMS или HLR-запроса // // id - ID cообщения или список ID через запятую // phone - номер телефона или список номеров через запятую // all - вернуть все данные отправленного SMS, включая текст сообщения (0,1 или 2) // // // для одиночного SMS-сообщения: // <статус>, <время изменения>, <код ошибки доставки> // // для HLR-запроса: // <статус>, <время изменения>, <код ошибки sms>, <код IMSI SIM-карты>, <номер сервис-центра>, <код страны регистрации>, <код оператора>, // <название страны регистрации>, <название оператора>, <название роуминговой страны>, <название роумингового оператора> // // при all = 1 дополнительно возвращаются элементы: // <время отправки>, <номер телефона>, <стоимость>, <sender id>, <название статуса>, <текст сообщения> // // при all = 2 дополнительно возвращаются элементы <страна>, <оператор> и <регион> // // если all = 0, то для каждого сообщения или HLR-запроса дополнительно возвращается <ID сообщения> и <номер телефона> // // если all = 1 или all = 2, то в ответ добавляется <ID сообщения> // // либо 0, -<код ошибки> в случае ошибки
string_t get_status(string_t id, string_t phone, int all);
// Получение баланса // // без параметров // // возвращает баланс в виде строки или пустую строку в случае ошибки
string_t get_balance(void);
void _print_debug(string_t str); string_t _urlencode(string_t str); string_t _urldecode(string_t str); string_t _smsc_send_cmd(string_t cmd, string_t arg, string_t files);
#endif /* SMSC_API_H */
string_t send_sms (string_t phones, string_t message, int translit, string_t time, int id, int format, string_t sender, string_t query, string_t files) { string_t res=NULL, arg=NULL; char formats[][13] = {"&flash=1", "&push=1", "&hlr=1", "&bin=1", "&bin=2", "&ping=1", "&mms=1", "&mail=1", "&call=1", "&viber=1", "&soc=1", "", "&tg=1"}; asprintf(&arg, "cost=3&phones=%s%s%s&translit=%d&id=%d%s%s%s%s%s%s%s", _urlencode(phones), message ? "&mes=" : "", message ? _urlencode(message) : "", translit, id, format > 0 ? formats[format - 1] : "", sender ? "&sender=" : "", sender ? _urlencode(sender) : "", time ? "&time=" : "", time ? _urlencode(time) : "", query ? "&" : "", query ? query : "");
if (SMSC_DEBUG) printf("%s\n",arg); res = _smsc_send_cmd("send", arg, files); free(arg); return res; }
void send_sms_mail(string_t phones, string_t mes, int translit, string_t time, int id, int format, string_t sender) { CURL *curl; CURLcode res = CURLE_OK; struct curl_slist *recipients = NULL;
curl = curl_easy_init(); string_t mail_body; asprintf(&mail_body,"%s:%s:%d:%s:%d,%d,%s:%s:%s", SMSC_LOGIN, SMSC_PASSWORD, id, time, translit, format, sender, phones, mes); if (SMSC_DEBUG) printf("%s\n",mail_body); if (curl) { curl_easy_setopt(curl, CURLOPT_URL, SMTP_SERVER); recipients = curl_slist_append(recipients, SMTP_FROM); curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients); res = curl_easy_perform(curl); if (res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); curl_slist_free_all(recipients); curl_easy_cleanup(curl); } }
string_t get_sms_cost(string_t phones, string_t mes, int translit, int format, string_t sender, string_t query) { string_t res, arg; char formats[][13] = {"&flash=1", "&push=1", "&hlr=1", "&bin=1", "&bin=2", "&ping=1", "&mms=1", "&mail=1", "&call=1", "&viber=1", "&soc=1", "", "&tg=1"};
asprintf(&arg, "cost=1&phones=%s&mes=%s&translit=%d%s%s%s%s%s", _urlencode(phones), _urlencode(mes), translit, format>0 ? formats[format-1] : "", sender ? "&sender=" : "", sender ? _urlencode(sender) : "", query ? "&query=" : "", query ? _urlencode(query) : ""); if (SMSC_DEBUG) printf("%s\n",arg); res = _smsc_send_cmd("send", arg, NULL); free(arg); return res; }
string_t get_balance(void) { return _smsc_send_cmd("balance", "", NULL); // (balance) или (0, -error) }
string_t get_status(string_t id, string_t phone, int all) { string_t arg; asprintf(&arg, "phone=%s&id=%s&all=%d", _urlencode(phone),_urlencode(id), all);
return _smsc_send_cmd("status", arg, NULL); }
//============================================================================== struct MemoryStruct { char *memory; size_t size; };
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; struct MemoryStruct *mem = (struct MemoryStruct *) userp; mem->memory = realloc(mem->memory, mem->size + realsize + 1); // printf("%d", mem->memory); if (mem->memory == NULL) { /* out of memory! */ printf("not enough memory (realloc returned NULL)\n"); return 0; }
memcpy(&(mem->memory[mem->size]), contents, realsize); mem->size += realsize; mem->memory[mem->size] = 0; return realsize; } //==============================================================================
string_t _smsc_send_cmd(string_t cmd, string_t arg, string_t files) { CURL *curl; CURLcode res; struct curl_slist *list = NULL; struct curl_httppost* cpost = NULL; struct curl_httppost* clast = NULL; string_t _arg, url, istr, dstr; char post, i=0;
struct MemoryStruct chunk; chunk.memory = malloc(1); // will be grown as needed by the realloc above chunk.memory[0] = 0; chunk.size = 0; // no data at this point
curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &chunk);
if (SMSC_LOGIN[0]) asprintf(&_arg, "login=%s&psw=%s&fmt=1&charset=%s&%s", _urlencode(SMSC_LOGIN), _urlencode(SMSC_PASSWORD), SMSC_CHARSET, arg); else asprintf(&_arg, "apikey=%s&fmt=1&charset=%s&%s", _urlencode(SMSC_PASSWORD), SMSC_CHARSET, arg);
post = SMSC_POST || files || (strlen(_arg) > 2000); do { asprintf(&url, "m.smsc.ru/sys/%s.php", cmd); if (i++) asprintf(&url, "%s://www%d.%s", SMSC_HTTPS ? "https" : "http", i, url); else asprintf(&url, "%s://%s", SMSC_HTTPS ? "https" : "http", url); if (post) { // разбираем строку параметров istr = strtok(_arg,"=&"); while (istr != NULL) { asprintf(&dstr,"%s", istr); istr = strtok (NULL, "=&"); // printf("%s=%s\n", dstr, istr); curl_formadd(&cpost, &clast, CURLFORM_COPYNAME, dstr, CURLFORM_COPYCONTENTS, _urldecode(istr), CURLFORM_END); istr = strtok (NULL, "=&"); } if (files) { res = curl_formadd(&cpost, &clast, CURLFORM_COPYNAME, "pictures", CURLFORM_FILE, files, CURLFORM_END); if (res != CURLE_OK) fprintf(stderr, "curl_easy_formadd() formfile failed: %s\n", curl_easy_strerror(res)); } curl_easy_setopt(curl, CURLOPT_HTTPPOST, cpost); } else asprintf(&url, "%s?%s",url, _arg); if (SMSC_DEBUG) printf("%s\n%s\n", url, _arg);
curl_easy_setopt(curl, CURLOPT_URL, url); res = curl_easy_perform(curl); if (res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); else if (SMSC_DEBUG) printf("%lu bytes retrieved\n%s\n", (long)chunk.size, chunk.memory); } while ((i < 5) && (res != CURLE_OK)); curl_easy_cleanup(curl); free(_arg); free(url); free(dstr); } return(chunk.memory); }
// кодирование параметра в http-запросе
string_t _urlencode(string_t str) { string_t output; CURL *curl; if (str) { curl = curl_easy_init(); if (curl) { string_t output = curl_easy_escape(curl, str, 0); curl_easy_cleanup(curl); return (output); } return(NULL); } return(NULL); }
// декодирование параметра в http-запросе
string_t _urldecode(string_t str) { string_t output; CURL *curl; if (str) { curl = curl_easy_init(); if (curl) { string_t output = curl_easy_unescape(curl, str, 0, NULL); curl_easy_cleanup(curl); return (output); } return(NULL); } return(NULL); } // вывод отладочной информации
void _print_debug(string_t str) { printf("%s\n", str); }
Пример использования библиотеки:
#include "smsc_api.c"
string_t ret, balance;
ret = send_sms("79999999999", "Ваш пароль: 123", 0, NULL, 0, 7, NULL, "subj=Privet", NULL); ... ret = send_sms("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, "", 0, 0, "", "maxsms=3", NULL); ... ret = send_sms("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, "", 0, 5, NULL, NULL, NULL); ... ret = get_sms_cost("79999999999", "Ваш пароль: 123", 0, 7, NULL, NULL); ... ret = get_status("12345", "79999999999", 1); ... balance = get_balance(); ...
Для Microsoft Excel
Скачать файл библиотеки:
smsc_api_excel.bas
Исходный код библиотеки:
Attribute VB_Name = "smsc_api"
' M.SMSC.RU API (www.m.smsc.ru) версия 1.2 (03.07.2019)
Public Const SMSC_DEBUG As Byte = 0 ' флаг отладки
Public Const SMSC_CHARSET As String = "utf-8" ' кодировка сообщения (utf-8 или koi8-r), по умолчанию используется windows-1251
Public SMSC_LOGIN As String ' логин клиента
Public SMSC_PASSWORD As String ' пароль клиента
Public SMSC_HTTPS As Byte ' использовать HTTPS протокол
Public Const SMTP_SERVER As String = "smtp.mail.ru" ' адрес SMTP сервера
Public Const SMTP_USERNAME As String = "<smtp_user_name>" ' логин на SMTP сервере
Public Const SMTP_PASSWORD As String = "<smtp_password>" ' пароль на SMTP сервере
Public Const SMTP_FROM As String = "smtp_user_name@mail.ru" ' e-mail адрес отправителя
Public CONNECT_MODE As Byte ' режим соединения с интернетом: 0 - прямое, 1 - Proxy, 2 - настройки из Internet Exporer
Public PROXY_SERVER As String ' адрес Proxy-сервера
Public PROXY_PORT As Integer ' порт Proxy-сервера
Public PROXY_AUTORIZATION As Byte ' флаг использования авторизации на Proxy-сервере
Public PROXY_USERNAME As String ' логин на Proxy-сервере
Public PROXY_PASSWORD As String ' пароль на Proxy-сервере
Public Connection As Object
' Пауза в приложении
'
' Параметры:
' PauseTime - время паузы в секундах
'
Private Sub Sleep(PauseTime As Integer)
Start = Timer
Do While Timer < Start + PauseTime
DoEvents
Loop
End Sub
Public Function URLEncode(ByVal Str As String) As String
Dim Ret
Ret = ""
CharStr = " !""@№#;%:?*().,/$^&\+"
Str = Trim(Str)
For i = 1 To Len(Str)
S = Mid(Str, i, 1)
SymCode = Asc(S)
' Перевод из UNICODE в ASCII
If ((SymCode > 1039) And (SymCode < 1104)) Then
SymCode = SymCode - 848
ElseIf SymCode = 8470 Then
SymCode = 185
ElseIf SymCode = 1105 Then
SymCode = 184
ElseIf SymCode = 1025 Then
SymCode = 168
End If
fl_replace = 0
If InStr(1, CharStr, S, vbBinaryCompare) > 0 Then
Ret = Ret & "%" & Hex(Int(SymCode / 16)) & Hex(Int(SymCode Mod 16))
fl_replace = 1
End If
If (SymCode <= 127) And (fl_replace = 0) Then
Ret = Ret & S
ElseIf fl_replace = 0 Then
Ret = Ret + "%" + Hex(Int(SymCode / 16)) & Hex(Int(SymCode Mod 16))
End If
Next i
URLEncode = Ret
End Function
' Функция чтения URL.
'
Private Function SMSC_Read_URL(URL As String, Params As String) As String
Dim Ret As String
On Error GoTo 0
Connection.Open "POST", Trim(URL), 0
Connection.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
Connection.Send Trim(Params)
Ret = Connection.ResponseText()
If Err.Number <> 0 Then
MsgBox "Не удалось получить данные с сервера!", , "Ошибка"
SMSC_Read_URL = ""
Exit Function
End If
SMSC_Read_URL = Ret
End Function
' Функция вызова запроса. Формирует URL и делает 5 попыток чтения.
'
Private Function SMSC_Send_Cmd(Cmd As String, Optional Arg As String = "")
Dim URL As String, Params As String, Ret As String
URL_orig = IIf(SMSC_HTTPS, "https", "http") & "://m.smsc.ru/sys/" & Cmd & ".php"
URL = URL_orig
Params = "login=" & SMSC_LOGIN & "&psw=" & SMSC_PASSWORD & "&fmt=1" _
& IIf(SMSC_CHARSET = "", "", "&charset=" + SMSC_CHARSET) & "&" & Arg
i = 1
Do
If i > 1 Then
URL = URL_orig
URL = Replace(URL, "://m.smsc.ru/", "://www" & i & ".m.smsc.ru/")
End If
Ret = SMSC_Read_URL(URL, Params)
i = i + 1
Loop While (Ret = "" And i < 6)
If (Ret = "") Then
If SMSC_DEBUG Then MsgBox "Ошибка чтения адреса: " & URL, , "Ошибка"
Ret = "," ' фиктивный ответ
End If
SMSC_Send_Cmd = Split(Ret, ",", -1, vbTextCompare)
End Function
' Функция получения баланса
'
' без параметров
'
' возвращает баланс в виде строки или CVErr(N_Ошибки) в случае ошибки
'
Public Function Get_Balance()
Dim m
m = SMSC_Send_Cmd("balance") ' (balance) или (0, -error)
If UBound(m) = 0 Then
Get_Balance = m(0)
Else
Get_Balance = CVErr(-m(1))
End If
End Function
' Функция отправки SMS
'
' обязательные параметры:
'
' Phones - список телефонов через запятую или точку с запятой
' Message - отправляемое сообщение
'
' необязательные параметры:
'
' Translit - переводить или нет в транслит (1 или 0)
' Time - необходимое время доставки в виде строки (DDMMYYhhmm, h1-h2, 0ts, +m)
' Id - идентификатор сообщения
' Format - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc)
' Sender - имя отправителя (Sender ID)
' Query - дополнительные параметры
'
' возвращает массив (<id>, <количество sms>, <стоимость>, <баланс>) в случае успешной отправки
' либо массив (<id>, -<код ошибки>) в случае ошибки
'
Public Function Send_SMS(Phones As String, Message As String, Optional Translit = 0, Optional Time = 0, Optional Id = 0, Optional Format = 0, Optional sender = "", Optional Query = "")
Dim Formats As Variant
Dim m
Formats = Array("flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1")
FormatStr = ""
If (Format > 0) Then
FormatStr = Formats(Format - 1)
End If
m = SMSC_Send_Cmd("send", "cost=3&phones=" & URLEncode(Phones) & "&mes=" & Message _
& "&translit=" & Translit & "&id=" & Id & IIf(Format > 0, "&" & FormatStr, "") _
& IIf(sender = "", "", "&sender=" & URLEncode(sender)) _
& "&charset=" & SMSC_CHARSET & IIf(Time = "", "", "&time=" & URLEncode(Time)) _
& IIf(Query = "", "", "&" & Query))
' (id, cnt, cost, balance) или (id, -error)
Send_SMS = m
End Function
' Функция получения стоимости SMS
'
' обязательные параметры:
'
' Phones - список телефонов через запятую или точку с запятой
' Message - отправляемое сообщение
'
' необязательные параметры:
'
' Translit - переводить или нет в транслит (1 или 0)
' Sender - имя отправителя (Sender ID)
' Query - дополнительные параметры
'
' возвращает массив (<стоимость>, <количество sms>) либо массив (0, -<код ошибки>) в случае ошибки
'
Public Function Get_SMS_Cost(Phones As String, Message As String, Optional Translit = 0, Optional sender = "", Optional Query = "")
Dim m
m = SMSC_Send_Cmd("send", "cost=1&phones=" & URLEncode(Phones) & "&mes=" & Message & IIf(sender = "", "", "&sender=" & URLEncode(sender)) _
& "&translit=" & Translit & IIf(Query = "", "", "&" & Query))
'(cost, cnt) или (0, -error)
Get_SMS_Cost = m
End Function
' Функция проверки статуса отправленного SMS
'
' Id - ID cообщения
' Phone - номер телефона
'
' возвращает массив
' для отправленного SMS (<статус>, <время изменения>, <код ошибки sms>)
' для HLR-запроса (<статус>, <время изменения>, <код ошибки sms>, <код страны регистрации>, <код оператора абонента>,
' <название страны регистрации>, <название оператора абонента>, <название роуминговой страны>, <название роумингового оператора>,
' <код IMSI SIM-карты>, <номер сервис-центра>)
' либо список (0, -<код ошибки>) в случае ошибки
'
Public Function Get_Status(Id, Phone)
Dim m
m = SMSC_Send_Cmd("status", "phone=" & URLEncode(Phone) & "&id=" & Id)
' (status, time, err) или (0, -error)
Get_Status = m
End Function
' Инициализация подключения
'
Public Function SMSC_Initialize()
On Error GoTo 0
Set Connection = CreateObject("WinHttp.WinHttpRequest.5.1")
Connection.Option 9, 80
If Err.Number = 440 Or Err.Number = 432 Then
MsgBox "Не удалось создать объект ""WinHttp.WinHttpRequest.5.1""!" & Chr(13) & "Проверьте наличие системной библиотеки ""WinHttp.dll""", , "Ошибка"
Err.Clear
End If
End Function
Полнофункциональная надстройка для отправки SMS-сообщений на основе библиотеки.
Инструкция по установке надстройки:
1) Находясь в главном окне Excel, откройте меню Файл, далее Параметры.
2) Откройте вкладку Надстройки и нажмите кнопку Перейти.
3) В появившемся окне нажмите Обзор и выберите файл с надстройкой.
4) После того, как надстройка появится в окне Доступные надстройки, выделите ее и нажмите ОК.
5) В главном окне во вкладке надстройки появится кнопка Отправить SMS.
6) Чтобы отправить SMS на несколько номеров выделите столбец с номерами и нажмите Отправить SMS.
7) Для отправки индивидуальных сообщений в первом столбце расположите номера телефонов, а во втором тексты сообщений, выделите их и нажмите Отправить SMS.
В некоторых случаях из-за обновления системы безопасности Windows все файлы, полученные из интернета/почты, блокируются при загрузке в Excel. Это делается без каких-либо предупреждающих сообщений.
Если в процессе установки нашей надстройки не появляется кнопка "Отправить SMS" или вкладка "Надстройки", то снять блокировку можно следующим образом:
1. Закрыть все окна Excel.
2. В проводнике выполнить правый клик мыши на файле надстройки.
3. Выбрать пункт "Свойства".
4. На вкладке "Общие" поставить флаг "Разблокировать".
5. Нажать кнопки "Применить" - "OK" или просто "OK".
Для Microsoft Access
Скачать smsc_api_access.accdb (768 КБ)
Для отправки SMS сообщений из Microsoft Access необходимо выполнить следующее:
1) Откройте файл smsc_api_access.accdb с помощью Microsoft Access версии 2007 или выше.
2) Откройте модуль smsc_api.
3) Укажите в строках Public Const SMSC_LOGIN As String, Public Const SMSC_PASSWORD As String Ваш логин и пароль соответственно и сохраните файл.
4) Перейдите на форму Отправка, заполните поля Телефон, Сообщение и, при необходимости, Sender ID и нажмите кнопку Отправить.Для 1С (Версия 7.7)
Скачать smsc_api_1c77.txt (52 Кб)
Исходный код библиотеки:
// M.SMSC.RU API (m.smsc.ru) версия 1.9 (03.07.2019)
Перем SMSC_Логин; // логин клиента Перем SMSC_Пароль; // пароль клиента Перем SMSC_HTTPS; // использовать HTTPS протокол Перем SMSC_Отладка; // флаг отладки Перем SMSC_Кодировка; // кодировка сообщения (utf-8 или koi8-r), по умолчанию используется windows-1251
Перем ЕСТЬ_ПРОКСИ; // Флаг использования PROXY-сервера Перем ПРОКСИ_АДРЕС; Перем ПРОКСИ_ПОРТ; Перем ПРОКСИ_ЛОГИН; Перем ПРОКСИ_ПАРОЛЬ;
Перем Соединение; Перем Hex[16]; Перем ФорматыСообщений[11];
//*************************************************************************************** // ВНУТРЕННИЕ СЛУЖЕБНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ //*************************************************************************************** // Процедура инициализации переменных // Процедура ИнициализацияПеременных()
SMSC_Логин = "login"; SMSC_Пароль = "password"; SMSC_Отладка = 0; SMSC_HTTPS = 1; SMSC_Кодировка = "";
ЕСТЬ_ПРОКСИ = 0; ПРОКСИ_АДРЕС = ""; ПРОКСИ_ПОРТ = ""; ПРОКСИ_ЛОГИН = ""; ПРОКСИ_ПАРОЛЬ = "";
КонецПроцедуры
//*************************************************************************************** // Функция преобразования строки вида х,у в список значений // Функция Строка2Список(Стр)
Перем Рез;
Рез = СоздатьОбъект("СписокЗначений"); й = 1;
Для й = 1 По 4 Цикл
Поз = Найти(Стр, ",");
Если Поз = 0 Тогда Рез.ДобавитьЗначение(Стр); Прервать; Иначе Рез.ДобавитьЗначение(Лев(Стр,Поз-1)); КонецЕсли;
Стр = Сред(Стр, Поз+1, СтрДлина(Стр)-Поз);
КонецЦикла;
Возврат Рез;
КонецФункции // Строка2Список()
//*************************************************************************************** Функция URLEncode(Стр1)
//СтрокаСимволов = " !""@№#;%:?*().,/$^&"; СтрокаСимволов = " @№#%?/$&+";
Рез = ""; Стр = СокрЛП(Стр1); Для Сч=1 По СтрДлина(Стр) Цикл Символ = Сред(Стр, Сч, 1); КС = КодСимв(Символ);
флЗаменили = 0; Если Найти(СтрокаСимволов, Символ) > 0 Тогда
Рез = Рез + "%"+ Hex[Цел(КС/16)+1] + Hex[Цел(КС%16)+1]; флЗаменили = 1;
КонецЕсли;
Если (КС <= 127) и (флЗаменили = 0) Тогда Рез = Рез + Символ; ИначеЕсли флЗаменили = 0 Тогда Рез = Рез + "%"+ Hex[Цел(КС/16)+1] + Hex[Цел(КС%16)+1]; КонецЕсли;
КонецЦикла;
Возврат Рез;
КонецФункции // URLEncode()
//******************************************************************************* // Переводит время в формате Unix DateTimeStamp в строку с датой, временем // // Пареметры: // ШтампВремени - штамп времени в формате Unix // Функция Unix2Date (ШтампВремени)
ЧислоДней = Цел(ШтампВремени / 86400);
Д = Дата("01.01.1970") + ЧислоДней; ОстСек = ШтампВремени % 86400;
Ч = Цел(ОстСек / 3600); ОстСек = ОстСек % 3600;
М = Цел(ОстСек / 60); С = ОстСек % 60;
Возврат Формат(Д, "Д ДДММГГГГ") + " " + Ч + ":" + М + ":" + С;
КонецФункции // Unix2Date()
//******************************************************************************* // Осуществляет загрузку внешней компоненты WinHttp.dll // Функция УстановитьКомпоненту()
Попытка
Соединение = СоздатьОбъект("WinHttp.WinHttpRequest.5.1"); Соединение.Option(9, 80); Если ЕСТЬ_ПРОКСИ = 1 Тогда Соединение.SetProxy(2, СокрЛП(ПРОКСИ_АДРЕС) + ":" + СокрЛП(ПРОКСИ_ПОРТ)); КонецЕсли;
Исключение
Сообщить("Не удалось создать объект WinHttp.WinHttpRequest.5.1!" + РазделительСтрок + "Проверьте наличие системной библиотеки ""WinHttp.dll""!"); Возврат 0;
КонецПопытки;
Возврат 1;
КонецФункции // УстановитьКомпоненту()
//*************************************************************************************** // Функция чтения адреса // Функция _SMSC_ПрочитатьАдрес(Адрес, Параметры)
Перем Рез;
Попытка Соединение.Open("POST", СокрЛП(Адрес), 0); Если ЕСТЬ_ПРОКСИ = 1 Тогда Соединение.SetCredentials(СокрЛП(ПРОКСИ_ЛОГИН), СокрЛП(ПРОКСИ_ПАРОЛЬ), 1); КонецЕсли; Соединение.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); Соединение.Send(СокрЛП(Параметры)); Рез = Соединение.ResponseText(); Исключение Сообщить("Не удалось получить данные с сервера!", "!"); Возврат ""; КонецПопытки;
Возврат Рез;
КонецФункции //_SMSC_ПрочитатьАдрес()
//*************************************************************************************** // Функция вызова запроса. Формирует URL и делает 5 попыток чтения. // Функция _SMSC_ПослатьКоманду(Команда, Аргументы = "")
Адрес = "http" + ?(SMSC_HTTPS = 2, "s", "") + "://m.smsc.ru/sys/" + Команда + ".php"; Параметры = "login=" + СокрЛП(URLEncode(SMSC_Логин)) + "&psw=" + СокрЛП(URLEncode(SMSC_Пароль)) + "&fmt=1" + ?(ПустаяСтрока(SMSC_Кодировка) = 1, "", "&charset=" + SMSC_Кодировка) + "&" + СокрЛП(Аргументы);
Для Сч = 1 По 5 Цикл
Если Сч > 1 Тогда Адрес = "http" + ?(SMSC_HTTPS = 2, "s" , "") + "://" + "www" + Сч + ".m.smsc.ru/sys/" + Команда + ".php"; КонецЕсли;
Рез = _SMSC_ПрочитатьАдрес(Адрес, Параметры);
Если ПустоеЗначение(Рез) = 0 Тогда Прервать; КонецЕсли;
КонецЦикла;
Если ПустоеЗначение (Рез) = 1 Тогда
Если SMSC_Отладка = 1 Тогда Сообщить("Ошибка чтения адреса: "+ Адрес + "?" + Параметры); КонецЕсли;
Рез = "," // Фиктивный ответ
КонецЕсли;
Возврат Строка2Список(Рез);
КонецФункции // _SMSC_ПослатьКоманду()
//*************************************************************************************** // Функция отправки SMS // // обязательные параметры: // // Телефоны - список телефонов через запятую или точку с запятой // Сообщение - отправляемое сообщение // // необязательные параметры: // // Транслит - переводить или нет в транслит (1 или 0) // Время - необходимое время доставки в виде строки (DDMMYYhhmm, h1-h2, 0ts, +m) // ИД - идентификатор сообщения // ФорматСообщения - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc) // Отправитель - имя отправителя (Sender ID) // ДопПараметры - строка дополнительных параметров, добавляемая в URL-запрос ("valid=01:00&maxsms=3&tz=2") // // возвращает список (<id>, <количество sms>, <стоимость>, <баланс>) в случае успешной отправки // либо список (<id>, -<код ошибки>) в случае ошибки // Функция ПослатьSMS(Телефоны, Сообщение, Транслит = 0, Время = "", ИД = 0, ФорматСообщения = 0, Отправитель = "", ДопПараметры = "")
Ответ = _SMSC_ПослатьКоманду ("send", "cost=3&phones=" + URLEncode(Телефоны) + "&mes=" + URLEncode(Сообщение) + "&translit=" + Транслит + "&id=" + ИД + ?(ФорматСообщения > 0, "&" + ФорматыСообщений[ФорматСообщения], "") + ?(ПустаяСтрока(Отправитель) = 1, "", "&sender=" + URLEncode(Отправитель)) + ?(ПустаяСтрока(Время) = 1, "", "&time=" + URLEncode(Время)) + ?(ПустаяСтрока(ДопПараметры) = 1, "", "&" + ДопПараметры));
// (id, cnt, cost, balance) или (id, -error)
Если (SMSC_Отладка = 1) Тогда
РезИД = Число(Ответ.ПолучитьЗначение(1)); Рез = Число(Ответ.ПолучитьЗначение(2)); Если (Рез > 0) Тогда Сообщить ("Сообщение отправлено успешно. ID: " + РезИД + ", всего SMS: " + Ответ.ПолучитьЗначение(2) + ", стоимость: " + Ответ.ПолучитьЗначение(3) + " руб., баланс: " + Ответ.ПолучитьЗначение(4) + " руб."); Иначе Сообщить ("Ошибка № " + Строка(-Рез) + ?(РезИД > 0, ", ID: " + РезИД, "")); КонецЕсли;
КонецЕсли;
Возврат Ответ;
КонецФункции // ПослатьSMS()
//*************************************************************************************** // Функция получения стоимости SMS // // обязательные параметры: // // Телефоны - список телефонов через запятую или точку с запятой // Сообщение - отправляемое сообщение // // необязательные параметры: // // Транслит - переводить или нет в транслит (1 или 0) // Отправитель - имя отправителя (Sender ID) // ДопПараметры - строка дополнительных параметров, добавляемая в URL-запрос ("list=79999999999:Ваш пароль: 123\n78888888888:Ваш пароль: 456") // // возвращает список (<стоимость>, <количество sms>) либо список (0, -<код ошибки>) в случае ошибки // Функция ПолучитьСтоимость(Телефоны, Сообщение, Транслит = 0, Отправитель = "", ДопПараметры = "")
Ответ = _SMSC_ПослатьКоманду("send", "cost=1&phones=" + URLEncode(Телефоны) + "&mes=" + URLEncode(Сообщение) + ?(ПустаяСтрока(Отправитель) = 1, "", "&sender=" + URLEncode(Отправитель)) + "&translit=" + Транслит + ?(ПустаяСтрока(ДопПараметры) = 1, "", "&" + ДопПараметры));
// (cost, cnt) или (0, -error)
Если (SMSC_Отладка = 1) Тогда
Рез1 = Число(Ответ.ПолучитьЗначение(1)); Рез2 = Число(Ответ.ПолучитьЗначение(2)); Если (Рез2 > 0) Тогда Сообщить ("Стоимость рассылки: " + Рез1 + " руб. Всего SMS: " + Рез2); Иначе Сообщить ("Ошибка № " + Строка(-Рез2)); КонецЕсли;
КонецЕсли;
Возврат Ответ;
КонецФункции
//*************************************************************************************** // Функция проверки статуса отправленного SMS // // ИД - ID cообщения // Телефон - номер телефона // // возвращает список: // для отправленного SMS (<статус>, <время изменения>, <код ошибки sms>) // для HLR-запроса (<статус>, <время изменения>, <код ошибки sms>, <код страны регистрации>, <код оператора абонента>, // <название страны регистрации>, <название оператора абонента>, <название роуминговой страны>, <название роумингового оператора>, // <код IMSI SIM-карты>, <номер сервис-центра>) // либо список (0, -<код ошибки>) в случае ошибки // Функция ПолучитьСтатус(ИД, Телефон)
Ответ = _SMSC_ПослатьКоманду("status", "phone=" + URLEncode(Телефон) + "&id=" + ИД);
// (status, time, err) или (0, -error)
Если (SMSC_Отладка = 1) Тогда
Рез1 = Число(Ответ.ПолучитьЗначение(1)); Рез2 = Число(Ответ.ПолучитьЗначение(2));
Если (Рез2 >= 0) Тогда Сообщить ("Статус SMS = " + Рез1 + ?(ПустоеЗначение(Рез2) = 0, ", время изменения статуса - " + Unix2Date(Число(Ответ.ПолучитьЗначение(2))), "")); Иначе Сообщить ("Ошибка № " + Строка(-Рез2)); КонецЕсли;
КонецЕсли;
Возврат Ответ;
КонецФункции // ПолучитьСтатус()
//*************************************************************************************** // Функция получения баланса // // без параметров // // возвращает баланс в виде строки или 0 в случае ошибки
Функция ПолучитьБаланс()
Ответ = _SMSC_ПослатьКоманду("balance"); // (balance) или (0, -error) Рез = Число(Ответ.ПолучитьЗначение(1));
Если (SMSC_Отладка = 1) Тогда
Если Рез >= 0 тогда Сообщить("Сумма на счете: " + Рез + " руб."); Иначе Сообщить("Ошибка № " + Строка(-Число(Ответ.ПолучитьЗначение(2)))); КонецЕсли;
КонецЕсли;
Возврат Рез;
КонецФункции // ПолучитьБаланс()
//*************************************************************************************** // Предопределенная процедура // Процедура ПриОткрытии()
Если УстановитьКомпоненту() = 0 Тогда Возврат; КонецЕсли;
ИнициализацияПеременных();
КонецПроцедуры // ПриОткрытии()
//*************************************************************************************** // ОПЕРАТОРЫ ОСНОВНОЙ ПРОГРАММЫ //*************************************************************************************** Hex[1]="0"; Hex[2]="1"; Hex[3]="2"; Hex[4]="3"; Hex[5]="4"; Hex[6]="5"; Hex[7]="6"; Hex[8]="7"; Hex[9]="8"; Hex[10]="9"; Hex[11]="A"; Hex[12]="B"; Hex[13]="C"; Hex[14]="D"; Hex[15]="E"; Hex[16]="F";
ФорматыСообщений[1] = "flash=1"; ФорматыСообщений[2] = "push=1"; ФорматыСообщений[3] = "hlr=1"; ФорматыСообщений[4] = "bin=1"; ФорматыСообщений[5] = "bin=2"; ФорматыСообщений[6] = "ping=1"; ФорматыСообщений[7] = "mms=1"; ФорматыСообщений[8] = "mail=1"; ФорматыСообщений[9] = "call=1"; ФорматыСообщений[10] = "viber=1"; ФорматыСообщений[11] = "soc=1";
// Examples: // Ответ = ПослатьSMS("79999999999", "Ваш пароль: 123", 1); // Ответ = ПослатьSMS("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, 0, 0, 0, "", "maxsms=3"); // Ответ = ПослатьSMS("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, 0, 0, 5, ""); // Ответ = ПослатьSMS("79999999999", "", 0, 0, 0, 3, ""); // Ответ = ПолучитьСтатус(sms_id, "79999999999"); // Баланс = ПолучитьБаланс();
Пример использования библиотеки:
... Ответ = ПослатьSMS("79999999999", "Ваш пароль: 123", 1); ... Ответ = ПослатьSMS("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, 0, 0, 0, "", "", "push=1"); ... Ответ = ПослатьSMS("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, 0, 0, 0, "", "", "bin=2"); ... Ответ = ПослатьSMS("79999999999", "", 0, 0, 0, 0, "", "", "hlr=1"); ... Ответ = ПолучитьСтатус(sms_id, "79999999999"); ... Баланс = ПолучитьБаланс(); ...
Полнофункциональная обработка для отправки SMS-сообщений на основе библиотеки.
Для 1С (Версия 8.2; 8.3)
Скачать smsc_api_1c82.txt (10 Кб)
Исходный код библиотеки:
// M.SMSC.RU API (www.m.smsc.ru) версия 1.19 (03.07.2019)
Перем SMSC_LOGIN; // логин клиента Перем SMSC_PASSWORD; // пароль клиента Перем SMSC_HTTPS; // использовать HTTPS протокол Перем SMSC_DEBUG; // флаг отладки
Перем ЕСТЬ_ПРОКСИ; // Флаг использования PROXY-сервера Перем ПРОКСИ_АДРЕС; Перем ПРОКСИ_ПОРТ; Перем ПРОКСИ_ЛОГИН; Перем ПРОКСИ_ПАРОЛЬ;
Перем Соединение; Перем ФорматыСообщений;
//*************************************************************************************** // ВНУТРЕННИЕ СЛУЖЕБНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ //***************************************************************************************
//*************************************************************************************** // Процедура инициализации переменных // Процедура ИнициализацияПеременных() SMSC_LOGIN = "<login>"; SMSC_PASSWORD = "<password>"; SMSC_DEBUG = 0; SMSC_HTTPS = 1; ЕСТЬ_ПРОКСИ = Ложь; ПРОКСИ_АДРЕС = ""; ПРОКСИ_ПОРТ = ""; ПРОКСИ_ЛОГИН = ""; ПРОКСИ_ПАРОЛЬ = ""; КонецПроцедуры
//*************************************************************************************** // Функция преобразования строки вида х,у в список значений // Функция Строка2Список(Стр) Перем Рез; Рез = Новый СписокЗначений; Сч = 1; Для Сч = 1 По 4 Цикл Поз = Найти(Стр, ","); Если Поз = 0 Тогда Рез.Добавить(Стр); Прервать; Иначе Рез.Добавить(Лев(Стр,Поз-1)); КонецЕсли; Стр = Сред(Стр, Поз+1, СтрДлина(Стр)-Поз); КонецЦикла; Возврат Рез; КонецФункции // Строка2Список()
//*************************************************************************************** // Переводит время в формате Unix DateTimeStamp в строку с датой, временем // // Пареметры: // ШтампВремени - штамп времени в формате Unix // Функция Unix2Date (ШтампВремени) Возврат Дата("19700101000000") + ШтампВремени; КонецФункции // Unix2Date()
//*************************************************************************************** функция Hex(КС) _Hex = Новый Массив(16); _Hex[0]="0"; _Hex[1]="1"; _Hex[2]="2"; _Hex[3]="3"; _Hex[4]="4"; _Hex[5]="5"; _Hex[6]="6"; _Hex[7]="7"; _Hex[8]="8"; _Hex[9]="9"; _Hex[10]="A"; _Hex[11]="B"; _Hex[12]="C"; _Hex[13]="D"; _Hex[14]="E"; _Hex[15]="F"; Возврат(_Hex[Цел(КС/16)] + _Hex[Цел(КС%16)]); конецфункции
//*************************************************************************************** Функция URLEncode(Стр1) Рез = ""; Стр= СокрЛП(Стр1); Для Сч=1 По СтрДлина(Стр) Цикл Символ = Сред(Стр, Сч, 1); КС = КодСимвола(Символ); Рез = Рез + "%"+ Hex(Цел(КС/256)) + "%"+ Hex(КС%256); КонецЦикла;
Возврат Рез; КонецФункции // URLEncode()
//*************************************************************************************** // Функция вызова запроса. Формирует URL и делает 3 попытки чтения. // Функция _SMSC_ПрочитатьАдрес(Сервер, РесурсНаСервере, _Параметры) Экспорт Перем Рез; Перем ХТТПОтвет; ЕСТЬ_ПРОКСИ = Ложь; Прокси = Неопределено; Если ЕСТЬ_ПРОКСИ Тогда Прокси = Новый ИнтернетПрокси; Прокси.НеИспользоватьПроксиДляЛокальныхАдресов = Истина; Прокси.Пользователь = ПРОКСИ_ЛОГИН; Прокси.Пароль = ПРОКСИ_ПАРОЛЬ; Прокси.Установить("http" + ?(SMSC_HTTPS=1, "s", ""), ПРОКСИ_АДРЕС, ПРОКСИ_ПОРТ); КонецЕсли; Попытка Если SMSC_HTTPS = 0 Тогда Соединение = Новый HTTPСоединение(Сервер, , , , Прокси, Ложь); Иначе Соединение = Новый HTTPСоединение(Сервер, , , , Прокси, 10, Новый ЗащищенноеСоединениеOpenSSL); Конецесли; Исключение Сообщить("Не удалось установить соединение с сервером:" + Символы.ПС + ИнформацияОбОшибке().Описание, СтатусСообщения.Важное); Возврат ""; КонецПопытки;
ИмяФайлаРезультата = ПолучитьИмяВременногоФайла(); РесурсПараметры = РесурсНаСервере+"?"+_Параметры; Если СтрДлина(РесурсПараметры) < 2000 Тогда // GET Попытка ХТТПОтвет = Соединение.Получить(РесурсПараметры, ИмяФайлаРезультата); Соединение = Неопределено; Исключение Сообщить("Не удалось получить данные с сервера", СтатусСообщения.Важное); Возврат ""; КонецПопытки; Иначе // POST //Создаём файл отправки - содержимое POST-запроса. ИмяФайлаОтправки = ПолучитьИмяВременногоФайла(); ФайлОтправки = Новый ЗаписьТекста(ИмяФайлаОтправки, КодировкаТекста.ANSI, "", ЛОЖЬ); ФайлОтправки.Записать(_Параметры); ФайлОтправки.Закрыть();
//Формируем заголовок POST-запроса. ЗаголовокHTTP = Новый Соответствие(); ЗаголовокHTTP.Вставить("Content-Type", "application/x-www-form-urlencoded"); ФайлОтправки = Новый Файл(ИмяФайлаОтправки); РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер()); ЗаголовокHTTP.Вставить("Content-Length", Строка(РазмерФайлаОтправки));
Попытка ХТТПОтвет = Соединение.ОтправитьДляОбработки(ИмяФайлаОтправки, РесурсНаСервере, ИмяФайлаРезультата, ЗаголовокHTTP); Соединение = Неопределено; Исключение Сообщить("Не удалось получить данные с сервера:" + Символы.ПС + ИнформацияОбОшибке().Описание, СтатусСообщения.Важное); Возврат ""; КонецПопытки; КонецЕсли; Кодировка = ""; Если Найти(ХТТПОтвет.Заголовки.Получить("Content-Type"), "charset=utf-16be") > 0 Тогда Кодировка = "UTF-16BE"; КонецЕсли; ФайлРезультата = Новый ЧтениеТекста(ИмяФайлаРезультата, Кодировка); Рез = ФайлРезультата.ПрочитатьСтроку(); Возврат Рез; КонецФункции //_SMSC_ПрочитатьАдрес()
//*************************************************************************************** // Функция вызова запроса. Формирует URL и делает 5 попыток чтения. // Функция _SMSC_ПослатьКоманду(Команда, Аргументы = "")
Сервер = "m.smsc.ru"; Ресурс = "/sys/" + Команда + ".php"; _Параметры = "login=" + СокрЛП(URLEncode(SMSC_LOGIN)) + "&psw=" + СокрЛП(URLEncode(SMSC_PASSWORD)) + "&fmt=1&charset=utf-16" + ?(Не ПустаяСтрока(Аргументы), "&" + СокрЛП(Аргументы), ""); Для Сч = 1 По 5 Цикл
Если Сч > 1 Тогда Сервер = "www" + Сч + ".m.smsc.ru"; КонецЕсли;
Рез = _SMSC_ПрочитатьАдрес(Сервер, Ресурс, _Параметры);
Если НЕ ПустаяСтрока(Рез) Тогда Прервать; КонецЕсли;
КонецЦикла;
Если ПустаяСтрока (Рез) Тогда
Если SMSC_DEBUG = 1 Тогда Сообщить("Ошибка чтения адреса: "+ Сервер + Ресурс + "?" + _Параметры); КонецЕсли;
Рез = "," // Фиктивный ответ
КонецЕсли;
Возврат Строка2Список(Рез);
КонецФункции // _SMSC_ПослатьКоманду()
//*************************************************************************************** // Функция отправки SMS // // обязательные параметры: // // Телефоны - список телефонов через запятую или точку с запятой // Сообщение - отправляемое сообщение // // необязательные параметры: // // Транслит - переводить или нет в транслит (1 или 0) // Время - необходимое время доставки в виде строки (DDMMYYhhmm, h1-h2, 0ts, +m) // ИД - идентификатор сообщения // ФорматСообщения - формат сообщения (0 - обычное sms, 1 - flash-sms, 2 - wap-push, 3 - hlr, 4 - bin, 5 - bin-hex, 6 - ping-sms, 7 - mms, 8 - mail, 9 - call, 10 - viber, 11 - soc) // Отправитель - имя отправителя (Sender ID) // ДопПараметры - строка дополнительных параметров, добавляемая в URL-запрос ("valid=01:00&maxsms=3&tz=2") // // возвращает список (<id>, <количество sms>, <стоимость>, <баланс>) в случае успешной отправки // либо массив (<id>, -<код ошибки>) в случае ошибки // Функция ПослатьSMS(Телефоны, Сообщение, Транслит = Ложь, Время = "", ИД = 0, ФорматСообщения = 0, Отправитель = "", ДопПараметры = "") Ответ = _SMSC_ПослатьКоманду ("send", "cost=3&phones=" + URLEncode(Телефоны) + "&mes=" + URLEncode(Сообщение) + "&translit=" + ?(Транслит,1,0) + "&id=" + XMLСТрока(ИД) + ?(ФорматСообщения > 0, "&" + ФорматыСообщений[ФорматСообщения], "") + ?(ПустаяСтрока(Отправитель), "", "&sender=" + URLEncode(Отправитель)) + ?(ПустаяСтрока(Время), "", "&time=" + URLEncode(Время)) + ?(ПустаяСтрока(ДопПараметры), "", "&" + ДопПараметры));
// (id, cnt, cost, balance) или (id, -error)
Если SMSC_DEBUG = 1 Тогда
РезИД = Число(Ответ[0].Значение); Рез = Число(Ответ[1].Значение); Если (Рез > 0) Тогда Сообщить ("Сообщение отправлено успешно. ID: " + РезИД + ", всего SMS: " + Ответ[1].Значение + ", стоимость: " + Ответ[2].Значение + " руб., баланс: " + Ответ[3].Значение + " руб."); Иначе Сообщить ("Ошибка № " + Строка(-Рез) + ?(РезИД > 0, ", ID: " + РезИД, "")); КонецЕсли;
КонецЕсли;
Возврат Ответ; КонецФункции // ПослатьSMS()
//*************************************************************************************** // Функция получения стоимости SMS // // обязательные параметры: // // Телефоны - список телефонов через запятую или точку с запятой // Сообщение - отправляемое сообщение // // необязательные параметры: // // Транслит - переводить или нет в транслит // Отправитель - имя отправителя (Sender ID) // ДопПараметры - строка дополнительных параметров, добавляемая в URL-запрос ("list=79999999999:Ваш пароль: 123\n78888888888:Ваш пароль: 456") // // возвращает список (<стоимость>, <количество sms>) либо список (0, -<код ошибки>) в случае ошибки // Функция ПолучитьСтоимость(Телефоны, Сообщение, Транслит = Ложь, Отправитель = "", ДопПараметры = "")
Ответ = _SMSC_ПослатьКоманду("send", "cost=1&phones=" + URLEncode(Телефоны) + "&mes=" + URLEncode(Сообщение) + ?(ПустаяСтрока(Отправитель), "", "&sender=" + URLEncode(Отправитель)) + "&translit=" + ?(Транслит,1,0) + ?(ПустаяСтрока(ДопПараметры), "", "&" + ДопПараметры));
// (cost, cnt) или (0, -error)
Если SMSC_DEBUG = 1 Тогда Рез1 = Число(Ответ[0].Значение); Рез2 = Число(Ответ[1].Значение); Если (Рез2 > 0) Тогда Сообщить ("Стоимость рассылки: " + Рез1 + " руб. Всего SMS: " + Рез2); Иначе Сообщить ("Ошибка № " + Строка(-Рез2)); КонецЕсли;
КонецЕсли;
Возврат Ответ; КонецФункции
//*************************************************************************************** // Функция проверки статуса отправленного SMS // // ИД - ID cообщения // Телефон - номер телефона // // возвращает список: // для отправленного SMS (<статус>, <время изменения>, <код ошибки sms>) // для HLR-запроса (<статус>, <время изменения>, <код ошибки sms>, <код страны регистрации>, <код оператора абонента>, // <название страны регистрации>, <название оператора абонента>, <название роуминговой страны>, <название роумингового оператора>, // <код IMSI SIM-карты>, <номер сервис-центра>) // либо список (0, -<код ошибки>) в случае ошибки // Функция ПолучитьСтатус(ИД, Телефон) Ответ = _SMSC_ПослатьКоманду("status", "phone=" + URLEncode(Телефон) + "&id=" + XMLСтрока(ИД));
// (status, time, err) или (0, -error)
Если SMSC_DEBUG = 1 Тогда
Рез1 = Число(Ответ[0].Значение); Рез2 = Число(Ответ[1].Значение); Если (Рез2 >= 0) Тогда Сообщить ("Статус SMS = " + Рез1 + ?(Рез2 > 0, ", время изменения статуса - " + Ответ[1].Значение, "")); Иначе Сообщить ("Ошибка № " + Строка(-Рез2)); КонецЕсли; КонецЕсли;
Возврат Ответ; КонецФункции // ПолучитьСтатус()
//*************************************************************************************** // Функция получения баланса // // без параметров // // возвращает баланс в виде строки или 0 в случае ошибки // Функция ПолучитьБаланс() Ответ = _SMSC_ПослатьКоманду("balance"); // (balance) или (0, -error) Рез = Число(Ответ[0].Значение);
Если SMSC_DEBUG Тогда
Если Рез >= 0 тогда Сообщить("Сумма на счете: " + Рез + " руб."); Иначе Сообщить("Ошибка № " + Строка(-Число(Ответ[1].Значение))); КонецЕсли;
КонецЕсли; Возврат Рез; КонецФункции // ПолучитьБаланс()
//*************************************************************************************** // Предопределенная процедура // Процедура ПередОткрытием(Отказ, СтандартнаяОбработка) ИнициализацияПеременных(); КонецПроцедуры // ПередОткрытием()
Процедура КнопкаВыполнитьНажатие() // Ответ = ПослатьSMS("79999999999", "Ваш пароль: 123", Истина); // Сообщение(Ответ); КонецПроцедуры
//*************************************************************************************** // ОПЕРАТОРЫ ОСНОВНОЙ ПРОГРАММЫ //***************************************************************************************
ФорматыСообщений = Новый Массив(12); ФорматыСообщений[1] = "flash=1"; ФорматыСообщений[2] = "push=1"; ФорматыСообщений[3] = "hlr=1"; ФорматыСообщений[4] = "bin=1"; ФорматыСообщений[5] = "bin=2"; ФорматыСообщений[6] = "ping=1"; ФорматыСообщений[7] = "mms=1"; ФорматыСообщений[8] = "mail=1"; ФорматыСообщений[9] = "call=1"; ФорматыСообщений[10] = "viber=1"; ФорматыСообщений[11] = "soc=1";
// Examples: // Ответ = ПослатьSMS("79999999999", "Ваш пароль: 123", Истина); // Ответ = ПослатьSMS("79999999999", "http://m.smsc.ru\nM.SMSC.RU", Ложь, 0, 0, 0, "", "maxsms=3"); // Ответ = ПослатьSMS("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", Ложь, 0, 0, 5, ""); // Ответ = ПослатьSMS("79999999999", "", Ложь, 0, 0, 3, ""); // Ответ = ПолучитьСтатус(sms_id, "79999999999"); // Баланс = ПолучитьБаланс();
Пример использования библиотеки:
... Ответ = ПослатьSMS("79999999999", "Ваш пароль: 123", 1); ... Ответ = ПослатьSMS("79999999999", "http://m.smsc.ru\nM.SMSC.RU", 0, 0, 0, 0, "", "", "push=1"); ... Ответ = ПослатьSMS("79999999999", "0605040B8423F0DC0601AE02056A0045C60C036D79736974652E72750001036D7973697465000101", 0, 0, 0, 0, "", "", "bin=2"); ... Ответ = ПослатьSMS("79999999999", "", 0, 0, 0, 0, "", "", "hlr=1"); ... Ответ = ПолучитьСтатус(sms_id, "79999999999"); ... Баланс = ПолучитьБаланс(); ...
Полнофункциональная обработка для отправки SMS-сообщений на основе библиотеки.
FAQ: Как подключиться по HTTPS-протоколу
SMPPДля PHP
Скачать файл библиотеки:
smsc_smpp.php
Исходный код библиотеки:
<?php // M.SMSC.RU API (m.smsc.ru) версия 1.4 (26.01.2017)
define("SMSC_HOST", "smpp.m.smsc.ru"); // адрес SMPP-сервера define("SMSC_PORT", 3700); // порт подключения define("SMSC_LOGIN", "login"); // логин клиента define("SMSC_PASSWORD", "password"); // пароль define("SMSC_CHARSET", "windows-1251"); // кодировка сообщения: utf-8, koi8-r или windows-1251 (по умолчанию)
class SMSC_SMPP { private $socket; private $sequence_number = 1;
public function __construct($port = 0) { $ip = gethostbyname(SMSC_HOST);
if ($ip == SMSC_HOST) // dns fail $ip = "212.24.33.196"; // fixed ip
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!$this->socket || !socket_connect($this->socket, $ip, $port ? $port : SMSC_PORT)) throw new Exception(socket_strerror(socket_last_error()));
if (!$this->bind()) throw new Exception("Bind error"); }
public function __destruct() { if ($this->socket) { $this->unbind(); socket_close($this->socket); } }
private function send_pdu($pdu) { $length = strlen($pdu);
if ($this->socket && socket_write($this->socket, $pdu, $length) == $length) { $reply = unpack("Nlen/Ncmd_id/Nstatus/Nseq/a*data", $this->read_pdu());
if ($reply['seq'] == $this->sequence_number++ && $reply['status'] == 0) // ok return $reply['data']; }
return false; }
private function read_pdu() { $pdu = ""; $wait_sec = 4;
while (socket_recv($this->socket, $pdu, 16, MSG_WAITALL) != 16 && --$wait_sec >= 0) sleep(1);
if ($wait_sec >= 0) { $header = unpack("N4", $pdu); $pdu .= socket_read($this->socket, $header[1] - 16); // body }
return $pdu; }
private function bind($system_type = '') { $pdu = pack("a".strlen(SMSC_LOGIN)."xa".strlen(SMSC_PASSWORD)."xa".strlen($system_type)."xCCCx", SMSC_LOGIN, SMSC_PASSWORD, $system_type, 0x34, 5, 1); // body $pdu = pack("NNNN", strlen($pdu) + 16, 0x02/*BIND_TRANSMITTER*/, 0, $this->sequence_number).$pdu; // header + body
return $this->send_pdu($pdu); }
public function unbind() { $pdu = pack("NNNN", 16, 0x06/*UNBIND*/, 0, $this->sequence_number); $this->send_pdu($pdu); }
// Функция отправки SMS // // обязательные параметры: // // $phones - список телефонов через запятую или точку с запятой // $message - отправляемое сообщение // // необязательные параметры: // // $sender - имя отправителя (Sender ID). Для отключения Sender ID по умолчанию необходимо в качестве имени // передать пустую строку или точку // $valid - "время жизни" сообщения в минутах // $use_tlv - тип отправки. true - передача текста сообщения в tlv-поле message_payload, false - передача // текста сообщения в поле short_message // time - необходимое время доставки в виде строки (DDMMYYYYhhmm или timestamp)
public function send_sms($phone, $message, $sender = ".", $valid = "", $use_tlv = true, $time = "") // $message в кодировке SMSC_CHARSET { if (preg_match('/[`\x80-\xff]/', $message)) { // is UCS chars $message = iconv(SMSC_CHARSET, "UTF-16BE", $message); $coding = 2; // UCS2 } else $coding = 0; // 7bit
if (!$use_tlv && strlen($message) > 255) $use_tlv = true;
$sm_length = strlen($message);
if ($valid) { $valid = min((int)$valid, 24 * 60); $valid = sprintf('0000%02d%02d%02d00000R', (int)($valid / 1440), ($valid % 1440) / 60, $valid % 60); }
if ($time) { if (strlen($time) == 12) { preg_match('~^(\d\d)(\d\d)(\d{4})(\d\d)(\d\d)$~', $time, $m); $time = mktime($m[4], $m[5], 0, $m[2], $m[1], $m[3]); }
$tz = (int)(date('Z', $time) / (15 * 60)); $time = date('ymdHi', $time).'000'.str_pad(abs($tz), 2, '0', STR_PAD_LEFT).($tz >= 0 ? '+' : '-'); }
$pdu = pack("xCCa".strlen($sender)."xCCa".strlen($phone)."xCCCa".strlen($time)."xa".strlen($valid)."xCCCC", // body 5, // source_addr_ton 1, // source_addr_npi $sender, // source_addr 1, // dest_addr_ton 1, // dest_addr_npi $phone, // destination_addr 0, // esm_class 0, // protocol_id 3, // priority_flag $time, // schedule_delivery_time $valid, // validity_period 0, // registered_delivery_flag 0, // replace_if_present_flag $coding * 4,// data_coding 0). // sm_default_msg_id
($use_tlv ? "\0\x04\x24".pack("n", $sm_length) : chr($sm_length)). // TLV message_payload tag OR sm_length + short_message
$message; // short_message
$pdu = pack("NNNN", strlen($pdu) + 16, 0x04/*SUBMIT_SM*/, 0, $this->sequence_number).$pdu; // header + body
return $this->send_pdu($pdu); // message id or false on error } }
// Examples: // include "smsc_smpp.php"; // try { // $S = new SMSC_SMPP(); // $S->send_sms("79999999999", "test message", "sender"); // } // catch (Exception $e) { // echo $e->getMessage(); // }
?>
Пример использования библиотеки:
<? include_once "smsc_smpp.php";
$S = new SMSC_SMPP(); ... $S->send_sms("79999999999", "test message"); ... if ($S->send_sms("79999999999", "Тестовое сообщение", "sender")) echo "Сообщение отправлено"; else echo "Произошла ошибка"; ?>
|