File Coverage

blib/lib/Log/Dispatch/Twilio.pm
Criterion Covered Total %
statement 21 65 32.3
branch 0 10 0.0
condition 0 8 0.0
subroutine 7 11 63.6
pod 2 2 100.0
total 30 96 31.2


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