File Coverage

blib/lib/Log/Dispatch/Twilio.pm
Criterion Covered Total %
statement 66 68 97.0
branch 8 10 80.0
condition 6 8 75.0
subroutine 12 12 100.0
pod 2 2 100.0
total 94 100 94.0


line stmt bran cond sub pod time code
1              
2             use strict;
3 1     1   301876 use warnings;
  1         6  
  1         25  
4 1     1   5 use base qw(Log::Dispatch::Output);
  1         1  
  1         23  
5 1     1   4 use HTTP::Status qw(:is);
  1         1  
  1         369  
6 1     1   28724 use List::Util qw(min);
  1         3850  
  1         153  
7 1     1   7 use POSIX qw(ceil);
  1         2  
  1         48  
8 1     1   5 use WWW::Twilio::API;
  1         2  
  1         7  
9 1     1   1658 use namespace::clean;
  1         33151  
  1         34  
10 1     1   7  
  1         2  
  1         9  
11             our $VERSION = '0.04';
12             our $MAX_TWILIO_LENGTH = 160; # max length of SMS message allowed by Twilio
13              
14             my $proto = shift;
15             my $class = ref($proto) || $proto;
16 10     10 1 27659 my $self = bless {}, $class;
17 10   33     36 $self->_basic_init(@_);
18 10         18 $self->_twilio_init(@_);
19 10         36 return $self;
20 10         804 }
21 6         14  
22             my $self = shift;
23             my %args = @_;
24              
25 10     10   17 # Grab and store required Twilio specific parameters
26 10         23 foreach my $p (qw( account_sid auth_token from to )) {
27             unless ($args{$p}) {
28             die __PACKAGE__ . " requires '$p' parameter.\n";
29 10         21 }
30 34 100       60 $self->{$p} = $args{$p};
31 4         32 }
32              
33 30         61 # Additional parameters
34             my $max = $args{max_messages} || 1;
35             if ($max <= 0) {
36             die __PACKAGE__ . " requires 'max_messages' to be >= 1.\n";
37 6   100     21 }
38 6 50       11 $self->{max_messages} = $max;
39 0         0 }
40              
41 6         13 my $self = shift;
42             my %msg = @_;
43              
44             my $twilio = WWW::Twilio::API->new(
45 2     2 1 5063 AccountSid => $self->{account_sid},
46 2         5 AuthToken => $self->{auth_token},
47             );
48              
49             my @to_send = $self->_expand_message($msg{message});
50             foreach my $entry (@to_send) {
51 2         10 my $res = $twilio->POST('Messages',
52             From => $self->{from},
53 2         49 To => $self->{to},
54 2         5 Body => $entry,
55             );
56              
57             unless ($res) {
58 2         6 warn "Unable to send log message via Twilio; $!\n";
59             }
60              
61 2 50       21 unless (is_success($res->{code})) {
62 0         0 warn "Failed to send log message via Twilio; "
63             . $res->{content} . "\n";
64             }
65 2 100       8 }
66             }
67 1         14  
68             my $self = shift;
69             my $msg = shift;
70             my $max = $self->{max_messages};
71             my @results;
72              
73 7     7   8789 # If its a long message, *and* we're configured for multiple messages,
74 7         8 # generate multiple messages.
75 7         9 my $msg_length = length($msg);
76 7         12 if (($max > 1) && ($msg_length > $MAX_TWILIO_LENGTH)) {
77             # Figure out how many messages we're actually going to generate
78             my $max_prefix_length = length("$max/$max: ");
79             my $how_much = $MAX_TWILIO_LENGTH - $max_prefix_length;
80 7         9 my $num_messages = min($max, ceil($msg_length / $how_much));
81 7 100 100     22  
82             # Create entries w/prefixes
83 2         5 for my $idx (1 .. $num_messages) {
84 2         4 my $prefix = "$idx/$num_messages: ";
85 2         12 my $entry = substr($msg, 0, $how_much, '');
86             $entry =~ s{^\s+|\s+$}{}g; # trim leading/trailing ws
87             push @results, $prefix . $entry;
88 2         8 }
89 5         8 }
90 5         9 # Otherwise, its just a single message.
91 5         15 else {
92 5         13 my $entry = substr($msg, 0, $MAX_TWILIO_LENGTH, '');
93             $entry =~ s{^\s+|\s+$}{}g; # trim leading/trailing ws
94             push @results, $entry;
95             }
96              
97 5         15 return @results;
98 5         20 }
99 5         10  
100             1;
101              
102 7         19 =for stopwords SMS Auth
103              
104             =head1 NAME
105              
106             Log::Dispatch::Twilio - Log output via Twilio SMS Message
107              
108             =head1 SYNOPSIS
109              
110             use Log::Dispatch;
111              
112             my $logger = Log::Dispatch->new(
113             outputs => [
114             [ 'Twilio',
115             min_level => 'emergency',
116             account_sid => '<your-twilio-account-sid>',
117             auth_token => '<your-twilio-auth-token>',
118             from => '<number-to-send-msg-from>',
119             to => '<number-to-send-msg-to>',
120             ],
121             ],
122             );
123              
124             =head1 DESCRIPTION
125              
126             This module provides a C<Log::Dispatch> output that sends log messages via
127             Twilio.
128              
129             While you probably don't want I<every> logged message from your application to
130             go out via Twilio, I find it particularly useful to set it up as part of my
131             C<Log::Dispatch> configuration for critical/emergency errors. In the event
132             that something dire happens, I'll receive an SMS message through Twilio right
133             away.
134              
135             =head2 Required Options
136              
137             When adding Twilio output to your L<Log::Dispatch> configuration, the following
138             options are required:
139              
140             =over
141              
142             =item account_sid
143              
144             Your Twilio "Account Sid".
145              
146             =item auth_token
147              
148             Your Twilio "Auth Token".
149              
150             =item from
151              
152             The telephone number from which the SMS messages will appear to be sent from.
153              
154             This number must be a number attached to your Twilio account.
155              
156             =item to
157              
158             The telephone number to which the SMS messages will be sent to.
159              
160             =back
161              
162             =head2 Additional Options
163              
164             =over
165              
166             =item max_messages (default 1)
167              
168             Maximum number of SMS messages that can be generated from a single logged
169             item. Defaults to 1.
170              
171             =back
172              
173             =head1 METHODS
174              
175             =over
176              
177             =item new
178              
179             Constructor.
180              
181             Implemented as per the L<Log::Dispatch::Output> interface.
182              
183             =item log_message
184              
185             Logs message, by sending it as an SMS message to the configured number via the
186             Twilio API.
187              
188             Implemented as per the L<Log::Dispatch::Output> interface.
189              
190             =back
191              
192             =head1 AUTHOR
193              
194             Graham TerMarsch (cpan@howlingfrog.com)
195              
196             =head1 COPYRIGHT
197              
198             Copyright (C) 2012, Graham TerMarsch. All Rights Reserved.
199              
200             This is free software, you can redistribute it and/or modify it under the
201             Artistic-2.0 license.
202              
203             =head1 SEE ALSO
204              
205             L<Log::Dispatch>,
206             L<http://www.twilio.com/>.
207              
208             =cut