File Coverage

blib/lib/SMS/API/SMSC.pm
Criterion Covered Total %
statement 20 66 30.3
branch 0 34 0.0
condition 5 18 27.7
subroutine 7 13 53.8
pod 4 5 80.0
total 36 136 26.4


line stmt bran cond sub pod time code
1             # It is dirty rework of original smsc.ru library. Now it has object interface.
2             package SMS::API::SMSC;
3              
4 1     1   979 use strict;
  1         3  
  1         42  
5 1     1   6 use warnings;
  1         3  
  1         35  
6 1     1   40 use 5.008_001;
  1         4  
  1         61  
7              
8             our $VERSION = 0.001;
9              
10 1     1   5237 use LWP::UserAgent;
  1         58842  
  1         27  
11 1     1   9 use URI::Escape;
  1         2  
  1         77  
12             require Carp;
13              
14 1     1   4 use constant SMSC_DEBUG => $ENV{SMSC_DEBUG};
  1         3  
  1         1473  
15              
16             sub new {
17 1     1 0 6358 my ($class, %args) = @_;
18              
19 1   33     30 bless {
      33        
      50        
      50        
      50        
20             login => $args{login} || Carp::croak('login required'),
21             password => $args{password} || Carp::croak('password requried'),
22             post => $args{post} || 0,
23             https => $args{https} || 0,
24             charset => $args{charset} || 'utf-8',
25             }, $class;
26             }
27              
28             my @FORMATS = ("flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1");
29              
30             sub send {
31 0     0 1   my ($self, $phones, $message, %args) = @_;
32              
33 0           my $cmd_arg = "cost=3&phones=" . uri_escape($phones);
34 0           $cmd_arg .= "&mes=" . uri_escape($message);
35 0           $cmd_arg .= "&charset=" . $self->{charset};
36              
37 0 0         $cmd_arg .= "&translit=$args{translit}" if $args{translit};
38 0 0         $cmd_arg .= "&id=$args{id}" if $args{id};
39 0 0         $cmd_arg .= $FORMATS[$args{format} - 1] if $args{format};
40 0 0         $cmd_arg .= "&time=" . uri_escape($args{time}) if $args{time};
41 0 0         $cmd_arg .= "&$args{query}" if $args{query};
42 0 0         $cmd_arg .= "&sender=" . uri_escape($args{sender})
43             if defined $args{sender};
44              
45 0           my @m = $self->_smsc_send_cmd("send", $cmd_arg);
46              
47             # (id, cnt, cost, balance) или (id, -error)
48              
49 0           if (SMSC_DEBUG) {
50             if ($m[1] > 0) {
51             print
52             "Сообщение отправлено успешно. ID: $m[0], всего SMS: $m[1], стоимость: $m[2] руб., баланс: $m[3] руб.\n";
53             }
54             else {
55             print "Ошибка №", -$m[1],
56             $m[0] ? ", ID: " . $m[0] : "", "\n";
57             }
58             }
59              
60 0           return @m;
61             }
62              
63             sub get_cost {
64 0     0 1   my ($self, $phones, $message, %args) = @_;
65              
66 0           my @formats = ("flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1");
67              
68 0 0         my @m = $self->_smsc_send_cmd(
    0          
    0          
    0          
69             "send",
70             "cost=1&phones="
71             . uri_escape($phones) . "&mes="
72             . uri_escape($message)
73             . (
74             defined $args{sender} ? "&sender=" . uri_escape($args{sender})
75             : ""
76             )
77             . "&charset="
78             . $self->{charset}
79             . ($args{translit} ? "&translit=$args{translit}" : "")
80             . ($args{format} ? "&" . $FORMATS[$args{format} - 1] : "")
81             . (
82             $args{query} ? "&$args{query}"
83             : ""
84             )
85             );
86              
87             # (cost, cnt) или (0, -error)
88              
89 0           if (SMSC_DEBUG) {
90             if ($m[1] > 0) {
91             print
92             "Стоимость рассылки: $m[0] руб. Всего SMS: $m[1]\n";
93             }
94             else {
95             print "Ошибка №", -$m[1], "\n";
96             }
97             }
98              
99 0           return @m;
100             }
101              
102             sub get_status {
103 0     0 1   my ($self, $id, $phone) = @_;
104              
105 0           my @m =
106             $self->_smsc_send_cmd("status",
107             "phone=" . uri_escape($phone) . "&id=" . $id);
108              
109             # (status, time, err) или (0, -error)
110              
111 0           if (SMSC_DEBUG) {
112             if (exists $m[2]) {
113             print "Статус SMS = $m[0]",
114             $m[1]
115             ? ", время изменения статуса - "
116             . localtime($m[1])
117             : "", "\n";
118             }
119             else {
120             print "Ошибка №", -$m[1], "\n";
121             }
122             }
123              
124 0           return @m;
125             }
126              
127             sub get_balance {
128 0     0 1   my $self = shift;
129              
130 0           my @m = $self->_smsc_send_cmd("balance"); # (balance) или (0, -error)
131              
132 0           if (SMSC_DEBUG) {
133             if (!exists $m[1]) {
134             print "Сумма на счете: ", $m[0], " руб.\n";
135             }
136             else {
137             print "Ошибка №", -$m[1], "\n";
138             }
139             }
140              
141 0 0         return exists $m[1] ? undef : $m[0];
142             }
143              
144              
145             # ВНУТРЕННИЕ ФУНКЦИИ
146              
147             # Функция вызова запроса. Формирует URL и делает 3 попытки чтения
148              
149             sub _smsc_send_cmd {
150 0     0     my ($self, $cmd, $arg) = @_;
151              
152 0 0         my $url = ($self->{https} ? "https" : "http") . "://smsc.ru/sys/$cmd.php";
153 0 0         $arg =
154             "login="
155             . uri_escape($self->{login}) . "&psw="
156             . uri_escape($self->{password})
157             . "&fmt=1&"
158             . ($arg ? $arg : "");
159              
160 0           my $ret;
161 0           my $i = 0;
162              
163 0   0       do {
164 0 0         sleep(2) if ($i);
165 0           $ret = $self->_smsc_read_url($url, $arg);
166             } while ($ret eq "" && ++$i < 3);
167              
168 0 0         if ($ret eq "") {
169 0           print "Ошибка чтения адреса: $url\n"
170             if (SMSC_DEBUG);
171 0           $ret = ",0"; # фиктивный ответ
172             }
173              
174 0           return split(/,/, $ret);
175             }
176              
177             # Функция чтения URL
178              
179             sub _smsc_read_url {
180 0     0     my ($self, $url, $arg) = @_;
181              
182 0           my $ret = "";
183 0   0       my $post = $self->{post} || length($arg) > 2000;
184              
185 0           my $ua = LWP::UserAgent->new;
186 0           $ua->timeout(60);
187              
188 0 0         my $response =
189             $post
190             ? $ua->post($url, Content => $arg)
191             : $ua->get($url . "?" . $arg);
192              
193 0 0         $ret = $response->content if $response->is_success;
194              
195 0           return $ret;
196             }
197              
198             1;
199              
200             __END__