File Coverage

blib/lib/SMS/Send/IN/NICSMS.pm
Criterion Covered Total %
statement 29 79 36.7
branch 4 36 11.1
condition 0 3 0.0
subroutine 8 13 61.5
pod 2 2 100.0
total 43 133 32.3


line stmt bran cond sub pod time code
1             package SMS::Send::IN::NICSMS;
2              
3             # ABSTRACT: SMS::Send driver to send messages via NIC's SMS Gateway ( https://smsgw.sms.gov.in )
4              
5 2     2   20946 use 5.006;
  2         6  
6 2     2   9 use strict;
  2         4  
  2         37  
7 2     2   7 use warnings;
  2         4  
  2         60  
8 2     2   1167 use LWP::UserAgent;
  2         81324  
  2         71  
9 2     2   18 use URI::Escape;
  2         5  
  2         128  
10              
11 2     2   10 use base 'SMS::Send::Driver';
  2         5  
  2         1347  
12              
13             our $VERSION = '1.00'; # VERSION
14             our $AUTHORITY = 'cpan:INDRADG'; # AUTHORITY
15              
16             sub new {
17 1     1 1 81 my ( $class, %args ) = @_;
18              
19             # check we have the necessary credentials parameters
20 1 50       6 die "Username needs to be passed as 'username'" unless ( $args{_login} );
21 1 50       3 die "PIN / password needs to be passed as 'password'" unless ( $args{_password} );
22 1 50       2 die "SenderID / DLT Header needs to be passsed as 'signature'" unless ( $args{_signature} );
23 1 50       3 die "19-digit DLT Entity ID needs to be passed as 'dlt_entity_id'" unless ( $args{_dlt_entity_id} );
24              
25             # build the object
26 1         6 my $self = bless {
27             _endpoint => 'https://smsgw.sms.gov.in/failsafe/HttpLink',
28             _debug => 0,
29             %args
30             }, $class;
31              
32             # get an LWP user agent ready
33             # FIXME - bypassing SSL cert check due to NIC's cert chain borkage
34 1         7 $self->{ua} = LWP::UserAgent->new;
35             $self->{ua}->ssl_opts(
36 1         2532 SSL_verify_mode => 0,
37             verify_hostname => 0,
38             );
39            
40 1         51 return $self;
41             }
42              
43             sub _send_method {
44 0     0     my ( $self, @args ) = @_;
45              
46 0           my @params;
47 0           while (@args) {
48 0           my $key = shift @args;
49 0           my $val = shift @args;
50 0           push( @params, join( '=', uri_escape($key), uri_escape($val) ) );
51 0 0         print STDERR ">>> Arg $key = $val\n" if ( $self->{_debug} );
52             }
53 0           my $url = join( '?', $self->{_endpoint}, join( '&', @params ) );
54 0 0         print STDERR ">>> GET $url\n" if ( $self->{_debug} );
55              
56 0           my $res = $self->{ua}->get($url);
57              
58 0           my $errorbroker = $self->_ERRORHANDLER ( $res );
59              
60 0 0         if ( $errorbroker ) {
61 0           print STDERR "<<< Message sent successfully\n";
62 0 0         print STDERR "<<< SMS gateway response : $res->{_content}\n" if ( $self->{_debug} );
63 0           return 1;
64             } else {
65 0           print STDERR "<<< Message send failed\n";
66 0           print STDERR "<<< SMS gateway response : $res->{_content}\n";
67 0           return;
68             }
69             }
70              
71             sub send_sms {
72              
73 0     0 1   my ( $self, %args ) = @_;
74              
75             # FIXME : ugly hack to handle passing the DLT_TEMPLATE_ID for Koha ILS
76 0 0         if ( exists $self->{_iskohainstance} ) {
77 0 0         if ( $self->{_iskohainstance} eq "yes" ) {
78             # check if $args{text} is carrying the DLT_TEMPLATE_ID at the start of the message
79             # else throw an error
80             # As on date the IDs are 19 digit numbers
81              
82 0 0         die "19-digit DLT_TEMPLATE_ID not found at start of message!" unless ( $args{text} =~ /^\d{19}/ );
83              
84 0           $self->{_dlt_template_id} = substr( $args{text}, 0, 19);
85              
86 0           $args{text} =~ s!^\d{19}!!;
87             } else {
88 0           die "Incorrect value for the key 'iskohainstance' in IN/NICSMS.yaml. Check file!";
89             }
90             } else {
91 0           $self->{_dlt_template_id} = $args{_dlt_template_id};
92             }
93              
94             # check for message for 160 char limit
95 0           my $text = $self->_MESSAGETEXT ( $args{text} );
96            
97             # check destination number for well-formedness under NNP 2003 schema
98 0           my $to = $self->_TO ( $args{to} );
99              
100             $self->_send_method(
101             username => $self->{_login},
102             pin => $self->{_password},
103             mnumber => $args{to},
104             message => $args{text},
105             signature => $self->{_signature},
106             dlt_entity_id => $self->{_dlt_entity_id},
107             dlt_template_id => $self->{_dlt_template_id},
108 0           );
109             }
110              
111             # -----------------------------------------------------
112             # internal sanitization routines
113             # -----------------------------------------------------
114              
115             sub _MESSAGETEXT {
116 0     0     my ( $self, $text ) = @_;
117 2     2   1170 use bytes;
  2         27  
  2         11  
118 0 0         die "Message length over limit. Max length is 160 characters" unless ( length($text) <= 160 );
119             } # check for 160 char length of message text
120              
121             # As per National Numbering Plan 2003, Indian mobile phone numbers have to be in
122             # [9|8|7]XXXXXXXXX format. So we need to sanitize our input. The driver expects
123             # number string in 91XXXXXXXXXX format
124              
125             sub _TO {
126 0     0     my ( $self, $dest ) = @_;
127              
128 0           my $checkseries;
129             my $countrycode;
130              
131             # strip out any NaN characters
132 0           $dest =~ s/[^\d]//g;
133              
134             # strip leading zero as some have the habit of inputing numbers as 0XXXXXXXXXX
135 0           $dest =~ s/^0+//g;
136              
137             # check destination number length and format for well-formedness and fix common issues.
138 0 0 0       if ( length($dest) == 12 or length($dest) == 10 ) {
139 0 0         if ( length($dest) == 12 ) {
140 0           $countrycode = substr $dest, 0, 2;
141 0 0         die "Country code incorrect, needs to be 91 for India" unless ( $countrycode eq '91' );
142             }
143 0 0         if ( length($dest) == 10 ) {
144 0           $countrycode = "91";
145 0           $dest = $countrycode . $dest; #bring it up to 91XXXXXXXXXX
146             }
147              
148             # check for 9,8,7,6 series numbering under NNP 2003
149             # see https://en.wikipedia.org/wiki/Mobile_telephone_numbering_in_India
150             #
151 0           $checkseries = substr $dest, 2, 1;
152 0 0         die "Invalid phone number as per National Numbering Plan 2003" unless ( $checkseries =~ /[9|8|7|6]/ );
153             } else {
154 0           die "Invalid phone number format";
155             }
156 0           return $dest;
157             }
158              
159             sub _ERRORHANDLER {
160 0     0     my ( $self, $res ) = @_;
161              
162             # check for "~code=API000 " in the response string signifying a successful send
163              
164 0 0         if ( $res->content =~ /~code=API000 / ) {
165 0           return 1;
166             } else {
167 0           return;
168             }
169             }
170              
171             1;
172              
173             __END__