File Coverage

blib/lib/WWW/Notifo.pm
Criterion Covered Total %
statement 78 81 96.3
branch 14 14 100.0
condition 4 6 66.6
subroutine 21 22 95.4
pod 3 3 100.0
total 120 126 95.2


line stmt bran cond sub pod time code
1             package WWW::Notifo;
2              
3 2     2   114509 use warnings;
  2         7  
  2         77  
4 2     2   13 use strict;
  2         9  
  2         68  
5              
6 2     2   12 use Carp;
  2         10  
  2         275  
7 2     2   1651 use JSON;
  2         43238  
  2         12  
8 2     2   3532 use Data::Dumper;
  2         20494  
  2         186  
9 2     2   2257 use LWP::UserAgent;
  2         141428  
  2         73  
10 2     2   870 use MIME::Base64;
  2         793  
  2         168  
11              
12 2     2   14 use base qw( Exporter );
  2         4  
  2         278  
13              
14             our @EXPORT_OK = qw( notifo );
15              
16             =head1 NAME
17              
18             WWW::Notifo - Interface to notifo.com notification service
19              
20             =head1 VERSION
21              
22             This document describes WWW::Notifo version 0.09
23              
24             =cut
25              
26             our $VERSION = '0.09';
27              
28             =head1 SYNOPSIS
29              
30             use WWW::Notifo;
31             my $notifo = WWW::Notifo->new( username => 'foo', secret => 'xabc123' );
32            
33             # Subscribe a user...
34             my $status = $notifo->subscribe_user( username => 'bar' );
35            
36             # Send a notification
37             my $status = $notifo->send_notification(
38             to => 'someone',
39             msg => 'Hello!',
40             label => 'JAPH',
41             title => 'Boo',
42             uri => 'http://example.com/'
43             );
44              
45             =head1 DESCRIPTION
46              
47             Notifo (L) is a web based notification service that
48             can send push messages to mobile deviceas.
49              
50             From L:
51              
52             What Can I Do With Notifo?
53              
54             If you are a User, you can subscribe to receive notifications from
55             your favorite services that integrate with Notifo. On Notifo's site
56             you can set timers, send yourself messages, set stock alerts, and
57             Google Voice SMS alerts. More built-in services will be released in
58             the near future.
59              
60             If you are a Service, you can integrate with Notifo's API and start
61             sending mobile notifications to your users within a few hours. No need
62             to spend time or resources developing mobile applications just so you
63             can reach your users!
64              
65             =cut
66              
67 2     2   26 use constant API => 'https://api.notifo.com/v1';
  2         4  
  2         132  
68              
69 2     2   1647 use accessors::ro qw( username secret last );
  2         4159  
  2         21  
70              
71             BEGIN {
72 2     2   17 my %meth = (
73             subscribe_user => {
74             required => [qw( username )],
75             optional => [],
76             },
77             send_notification => {
78             required => [qw( to msg )],
79             optional => [qw( label title uri )],
80             },
81             );
82 2         7 for my $m ( keys %meth ) {
83 2     2   361 no strict 'refs';
  2         3  
  2         142  
84 4         1431 *{$m} = sub {
85 6     6   2405 shift->_api( $m, @{ $meth{$m} }{ 'required', 'optional' }, @_ );
  6         27  
86 4         17 };
87             }
88             }
89              
90             sub _need {
91 11     11   29 my ( $need, $optional, @args ) = @_;
92 11 100       169 croak "Expected a number of key => value pairs"
93             if @args % 2;
94 10         64 my %args = @args;
95 10         21 my @missing = grep { !defined $args{$_} } @$need;
  17         44  
96 10 100       236 croak "Missing options: ", join( ', ', sort @missing )
97             if @missing;
98 9 100       26 if ( defined $optional ) {
99 8         12 my %ok = map { $_ => 1 } @$need, @$optional;
  30         59  
100 8         20 my @extra = grep { !$ok{$_} } keys %args;
  22         43  
101 8 100       380 croak "Illegal otions: ", join( ', ', sort @extra ) if @extra;
102             }
103 7         39 return %args;
104             }
105              
106             =head2 C<< new >>
107              
108             Create a new C object. In common with all methods exposed
109             by the module accepts a number of key => value pairs. The C
110             and C options are mandatory:
111              
112             my $notifo = WWW::Notifo->new(
113             username => 'alice',
114             secret => 'x3122b4c4d3bad5e8d7397f0501b617ce60afe5d'
115             );
116              
117             =cut
118              
119             sub new {
120 4     4 1 8038 my $class = shift;
121 4         14 return bless { _need( [ 'secret', 'username' ], [], @_ ) }, $class;
122             }
123              
124             =head2 API Calls
125              
126             API calls provide access to the Notifo API.
127              
128             On success they return a reference to a hash containing the response
129             from notifo.com. On errors an exception will be thrown. In the case of
130             an error the response hash can be retrieved by calling C.
131              
132             =head3 C<< subscribe_user >>
133              
134             Service providers must call this method when users want to subscribe to
135             notifo alerts. This method will send a confirmation message to the user
136             where they can complete the opt-in process. The service provider will
137             not be able to send notifications to the user until this subscribe/opt-
138             in process has been completed.
139              
140             Users sending notifications to themselves with their User account do not
141             need to use this method. Since a User account can only send
142             notifications to itself, it is already implicitly subscribed. Only
143             Service accounts need to use this method to subscribe other users.
144              
145             my $resp = $notifo->subscribe_user(
146             username => 'hexten'
147             );
148              
149             =head3 C<< send_notification >>
150              
151             Once a user has subscribed to notifo alerts, service providers can call
152             this method to send notifications to specific users. The C and
153             C parameters are required. The C parameter is optional, and </td> </tr> <tr> <td class="h" > <a name="154">154</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> can be thought of as a description of the type of notification being </td> </tr> <tr> <td class="h" > <a name="155">155</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sent (almost like the subject of an email). The C<uri> parameter is used </td> </tr> <tr> <td class="h" > <a name="156">156</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> to specify what URI (web address, app uri, etc) will be loaded when the </td> </tr> <tr> <td class="h" > <a name="157">157</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> user opens the notification. If omitted, the default service provider </td> </tr> <tr> <td class="h" > <a name="158">158</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> URL is used. </td> </tr> <tr> <td class="h" > <a name="159">159</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="160">160</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $resp = $notifo->send_notification( </td> </tr> <tr> <td class="h" > <a name="161">161</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> to => 'hexten', </td> </tr> <tr> <td class="h" > <a name="162">162</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> msg => 'Testing...', </td> </tr> <tr> <td class="h" > <a name="163">163</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> label => 'Test', </td> </tr> <tr> <td class="h" > <a name="164">164</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> title => 'Hoot', </td> </tr> <tr> <td class="h" > <a name="165">165</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> uri => 'http://hexten.net/' </td> </tr> <tr> <td class="h" > <a name="166">166</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ); </td> </tr> <tr> <td class="h" > <a name="167">167</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="168">168</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =head3 C<< api >> </td> </tr> <tr> <td class="h" > <a name="169">169</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="170">170</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> API entry points other than C<subscribe_user> and C<send_notification> </td> </tr> <tr> <td class="h" > <a name="171">171</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> (of which there are currently none) can be accessed directly by calling </td> </tr> <tr> <td class="h" > <a name="172">172</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> C<api>. For example, the above send_notification example can also be </td> </tr> <tr> <td class="h" > <a name="173">173</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> written as: </td> </tr> <tr> <td class="h" > <a name="174">174</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="175">175</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $resp = $notifo->api( </td> </tr> <tr> <td class="h" > <a name="176">176</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> 'send_notification', </td> </tr> <tr> <td class="h" > <a name="177">177</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> to => 'hexten', </td> </tr> <tr> <td class="h" > <a name="178">178</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> msg => 'Testing...', </td> </tr> <tr> <td class="h" > <a name="179">179</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> label => 'Test', </td> </tr> <tr> <td class="h" > <a name="180">180</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> title => 'Hoot', </td> </tr> <tr> <td class="h" > <a name="181">181</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> uri => 'http://hexten.net/' </td> </tr> <tr> <td class="h" > <a name="182">182</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ); </td> </tr> <tr> <td class="h" > <a name="183">183</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="184">184</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =head3 C<< last >> </td> </tr> <tr> <td class="h" > <a name="185">185</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="186">186</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> Get the most recent response (a hash ref). Useful in the case of an HTTP </td> </tr> <tr> <td class="h" > <a name="187">187</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> error (which throws an exception). </td> </tr> <tr> <td class="h" > <a name="188">188</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="189">189</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =cut </td> </tr> <tr> <td class="h" > <a name="190">190</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="191">191</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub _api { </td> </tr> <tr> <td class="h" > <a name="192">192</a> </td> <td class="c3" > 7 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-WWW-Notifo-pm--subroutine.html#192-1"> 7 </a> </td> <td >   </td> <td > 25 </td> <td class="s"> my ( $self, $method, $need, $optional, @args ) = @_; </td> </tr> <tr> <td class="h" > <a name="193">193</a> </td> <td class="c3" > 7 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 20 </td> <td class="s"> my %args = _need( $need, $optional, @args ); </td> </tr> <tr> <td class="h" > <a name="194">194</a> </td> <td class="c3" > 6 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 18 </td> <td class="s"> my $resp </td> </tr> <tr> <td class="h" > <a name="195">195</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> = $self->_ua->post( join( '/', API, $method ), Content => \%args ); </td> </tr> <tr> <td class="h" > <a name="196">196</a> </td> <td class="c3" > 6 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 8953 </td> <td class="s"> my $rd = $self->{last} = eval { JSON->new->decode( $resp->content ) }; </td> </tr> <tr> <td class="h" > <a > </a> </td> <td class="c3" > 6 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 31 </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="197">197</a> </td> <td class="c3" > 6 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 119 </td> <td class="s"> my $err = $@; </td> </tr> <tr> <td class="h" > <a name="198">198</a> </td> <td class="c3" > 6 </td> <td class="c3" > <a href="blib-lib-WWW-Notifo-pm--branch.html#198-1"> 100 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 22 </td> <td class="s"> if ( $resp->is_error ) { </td> </tr> <tr> <td class="h" > <a name="199">199</a> </td> <td class="c3" > 2 </td> <td class="c3" > <a href="blib-lib-WWW-Notifo-pm--branch.html#199-1"> 100 </a> </td> <td class="c0" > <a href="blib-lib-WWW-Notifo-pm--condition.html#199-1"> 66 </a> </td> <td >   </td> <td >   </td> <td > 23 </td> <td class="s"> croak join ' ', @{$rd}{ 'response_code', 'response_message' } </td> </tr> <tr> <td class="h" > <a > </a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 111 </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="200">200</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> if !$err && $rd->{status} eq 'error'; </td> </tr> <tr> <td class="h" > <a name="201">201</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 4 </td> <td class="s"> croak $resp->status_line; </td> </tr> <tr> <td class="h" > <a name="202">202</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="203">203</a> </td> <td class="c3" > 4 </td> <td class="c3" > <a href="blib-lib-WWW-Notifo-pm--branch.html#203-1"> 100 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 140 </td> <td class="s"> croak $err if $err; # Only report errors parsing JSON we have a 200 </td> </tr> <tr> <td class="h" > <a name="204">204</a> </td> <td class="c3" > 3 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 69 </td> <td class="s"> return $rd; </td> </tr> <tr> <td class="h" > <a name="205">205</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="206">206</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="207">207</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub api { </td> </tr> <tr> <td class="h" > <a name="208">208</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-WWW-Notifo-pm--subroutine.html#208-1"> 1 </a> </td> <td class="c3" > <a href="blib-lib-WWW-Notifo-pm--subroutine.html#208-1"> 1 </a> </td> <td > 6 </td> <td class="s"> my ( $self, $method, @args ) = @_; </td> </tr> <tr> <td class="h" > <a name="209">209</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 4 </td> <td class="s"> return $self->_api( $method, [], undef, @args ); </td> </tr> <tr> <td class="h" > <a name="210">210</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="211">211</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="212">212</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub _make_ua { </td> </tr> <tr> <td class="h" > <a name="213">213</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-WWW-Notifo-pm--subroutine.html#213-1"> 1 </a> </td> <td >   </td> <td > 2 </td> <td class="s"> my $self = shift; </td> </tr> <tr> <td class="h" > <a name="214">214</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 10 </td> <td class="s"> my $ua = LWP::UserAgent->new; </td> </tr> <tr> <td class="h" > <a name="215">215</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 3667 </td> <td class="s"> $ua->agent( join ' ', __PACKAGE__, $VERSION ); </td> </tr> <tr> <td class="h" > <a name="216">216</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> $ua->add_handler( </td> </tr> <tr> <td class="h" > <a name="217">217</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> request_send => sub { </td> </tr> <tr> <td class="h" > <a name="218">218</a> </td> <td class="c3" > 6 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-WWW-Notifo-pm--subroutine.html#218-1"> 6 </a> </td> <td >   </td> <td > 18687 </td> <td class="s"> shift->header( Authorization => $self->_auth_header ); </td> </tr> <tr> <td class="h" > <a name="219">219</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="220">220</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 65 </td> <td class="s"> ); </td> </tr> <tr> <td class="h" > <a name="221">221</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 34 </td> <td class="s"> return $ua; </td> </tr> <tr> <td class="h" > <a name="222">222</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="223">223</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="224">224</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub _auth_header { </td> </tr> <tr> <td class="h" > <a name="225">225</a> </td> <td class="c3" > 6 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-WWW-Notifo-pm--subroutine.html#225-1"> 6 </a> </td> <td >   </td> <td > 8 </td> <td class="s"> my $self = shift; </td> </tr> <tr> <td class="h" > <a name="226">226</a> </td> <td class="c3" > 6 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 22 </td> <td class="s"> return 'Basic ' </td> </tr> <tr> <td class="h" > <a name="227">227</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> . encode_base64( join( ':', $self->username, $self->secret ), '' ); </td> </tr> <tr> <td class="h" > <a name="228">228</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="229">229</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="230">230</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub _ua { </td> </tr> <tr> <td class="h" > <a name="231">231</a> </td> <td class="c3" > 7 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-WWW-Notifo-pm--subroutine.html#231-1"> 7 </a> </td> <td >   </td> <td > 26 </td> <td class="s"> my $self = shift; </td> </tr> <tr> <td class="h" > <a name="232">232</a> </td> <td class="c3" > 7 </td> <td >   </td> <td class="c0" > <a href="blib-lib-WWW-Notifo-pm--condition.html#232-1"> 66 </a> </td> <td >   </td> <td >   </td> <td > 58 </td> <td class="s"> return $self->{_ua} ||= $self->_make_ua; </td> </tr> <tr> <td class="h" > <a name="233">233</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="234">234</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="235">235</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =head2 Procedural Interface </td> </tr> <tr> <td class="h" > <a name="236">236</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="237">237</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> The following convenience subroutine may be exported: </td> </tr> <tr> <td class="h" > <a name="238">238</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="239">239</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =head3 C<< notifo >> </td> </tr> <tr> <td class="h" > <a name="240">240</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="241">241</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> Send a notification. </td> </tr> <tr> <td class="h" > <a name="242">242</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="243">243</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> notifo( </td> </tr> <tr> <td class="h" > <a name="244">244</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> username => 'alice', </td> </tr> <tr> <td class="h" > <a name="245">245</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> secret => 'x3122b4c4d3bad5e8d7397f0501b617ce60afe5d', </td> </tr> <tr> <td class="h" > <a name="246">246</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> to => 'hexten', </td> </tr> <tr> <td class="h" > <a name="247">247</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> msg => 'Testing...', </td> </tr> <tr> <td class="h" > <a name="248">248</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> label => 'Test', </td> </tr> <tr> <td class="h" > <a name="249">249</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> title => 'Hoot', </td> </tr> <tr> <td class="h" > <a name="250">250</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> uri => 'http://hexten.net/' </td> </tr> <tr> <td class="h" > <a name="251">251</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ); </td> </tr> <tr> <td class="h" > <a name="252">252</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="253">253</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =cut </td> </tr> <tr> <td class="h" > <a name="254">254</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="255">255</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub notifo { </td> </tr> <tr> <td class="h" > <a name="256">256</a> </td> <td class="c0" > 0 </td> <td >   </td> <td >   </td> <td class="c0" > <a href="blib-lib-WWW-Notifo-pm--subroutine.html#256-1"> 0 </a> </td> <td class="c3" > <a href="blib-lib-WWW-Notifo-pm--subroutine.html#256-1"> 1 </a> </td> <td >   </td> <td class="s"> my %opt = _need( [], undef, @_ ); </td> </tr> <tr> <td class="h" > <a name="257">257</a> </td> <td class="c0" > 0 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> return WWW::Notifo->new( map { $_ => delete $opt{$_} } </td> </tr> <tr> <td class="h" > <a > </a> </td> <td class="c0" > 0 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="258">258</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> qw( username secret ) )->send_notification( %opt ); </td> </tr> <tr> <td class="h" > <a name="259">259</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="260">260</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="261">261</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> 1; </td> </tr> <tr> <td class="h" > <a name="262">262</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> __END__ </td> </tr> </table> </body> </html>