File Coverage

blib/lib/App/MonM/Notifier.pm
Criterion Covered Total %
statement 27 79 34.1
branch 0 20 0.0
condition 0 19 0.0
subroutine 9 13 69.2
pod 4 4 100.0
total 40 135 29.6


line stmt bran cond sub pod time code
1             package App::MonM::Notifier; # $Id: Notifier.pm 78 2022-09-16 08:22:04Z abalama $
2 1     1   51625 use warnings;
  1         8  
  1         27  
3 1     1   4 use strict;
  1         1  
  1         14  
4 1     1   516 use utf8;
  1         11  
  1         4  
5              
6             =encoding utf-8
7              
8             =head1 NAME
9              
10             App::MonM::Notifier - extension for the monm notifications
11              
12             =head1 VERSION
13              
14             Version 1.04
15              
16             =head1 SYNOPSIS
17              
18             use App::MonM::QNotifier;
19              
20             =head1 DESCRIPTION
21              
22             This is an extension for the monm notifications with guaranteed delivery
23              
24             =head2 new
25              
26             my $notifier = App::MonM::Notifier->new(
27             config => $app->configobj,
28             );
29              
30             =head2 notify
31              
32             $notifier->notify(
33             to => ['@FooGroup, @BarGroup, testuser, foo@example.com, 11231230002'],
34             subject => "Test message",
35             message => "Text of test message",
36             before => sub {
37             my $self = shift; # App::MonM::QNotifier object (this)
38             my $message = shift; # App::MonM::Message object
39              
40             warn ( $self->error ) if $self->error;
41              
42             # ...
43              
44             return 1;
45             },
46             after => sub {
47             my $self = shift; # App::MonM::QNotifier object (this)
48             my $message = shift; # App::MonM::Message object
49             my $sent = shift; # Status of sending
50              
51             warn ( $self->error ) if $self->error;
52              
53             die ( $self->channel->error ) unless $sent;
54              
55             # ...
56              
57             return 1;
58             },
59             ) or die($notifier->error);
60              
61             Sends message (text of message) to recipients list
62              
63             The callback function "before" calls before the message sending. Must be return the true value.
64             The callback function "after" calls after the message sending. Must be return the true value
65              
66             =head2 remind
67              
68             Tries to send postponed messages
69              
70             =head2 store
71              
72             my $store = $notifier->store();
73              
74             Returns store object
75              
76             =head1 CONFIGURATION
77              
78             Example of configuration section:
79              
80             UseMonotifier yes
81            
82             File /tmp/monotifier.db
83             Expires 1h
84             MaxTime 1m
85            
86              
87             =head1 HISTORY
88              
89             See C file
90              
91             =head1 DEPENDENCIES
92              
93             L
94              
95             =head1 TO DO
96              
97             See C file
98              
99             =head1 BUGS
100              
101             * none noted
102              
103             =head1 SEE ALSO
104              
105             L
106              
107             =head1 AUTHOR
108              
109             Serż Minus (Sergey Lepenkov) L Eabalama@cpan.orgE
110              
111             =head1 COPYRIGHT
112              
113             Copyright (C) 1998-2022 D&D Corporation. All Rights Reserved
114              
115             =head1 LICENSE
116              
117             This program is free software; you can redistribute it and/or
118             modify it under the same terms as Perl itself.
119              
120             See C file and L
121              
122             =cut
123              
124 1     1   40 use vars qw/$VERSION/;
  1         1  
  1         46  
125             $VERSION = '1.04';
126              
127 1     1   329 use parent qw/App::MonM::QNotifier/;
  1         203  
  1         4  
128              
129 1     1   418275 use CTK::ConfGenUtil;
  1         2  
  1         54  
130              
131 1     1   5 use App::MonM::Util qw/getExpireOffset parsewords merge/;
  1         2  
  1         47  
132 1     1   439 use App::MonM::Notifier::Store;
  1         3  
  1         80  
133              
134             use constant {
135 1         661 NODE_NAME => 'notifier',
136             NODE_NAME_ALIAS => 'monotifier',
137 1     1   8 };
  1         2  
138              
139             sub new {
140 0     0 1   my $class = shift;
141 0           my %args = @_;
142 0           my $self = $class->SUPER::new(%args);
143              
144             # Store
145 0   0       my $store_conf = hash($self->config->conf(NODE_NAME) || $self->config->conf(NODE_NAME_ALIAS));
146 0   0       $store_conf->{expires} = getExpireOffset(lvalue($store_conf, "expires") || lvalue($store_conf, "expire") || 0);
147 0   0       $store_conf->{maxtime} = getExpireOffset(lvalue($store_conf, "maxtime") || 0);
148 0           my $store = App::MonM::Notifier::Store->new(%$store_conf);
149 0           $self->{store} = $store;
150             #print App::MonM::Util::explain($store);
151              
152 0           return $self;
153             }
154             sub store {
155 0     0 1   my $self = shift;
156 0           return $self->{store};
157             }
158             sub notify { # send message to recipients list
159 0     0 1   my $self = shift;
160 0           my %args = @_;
161 0           $self->error("");
162 0           my $before = $args{before}; # The callback for before sending
163 0           my $after = $args{after}; # The callback for after sending
164 0           my @channels = $self->getChanelsBySendTo(array($args{to}));
165 0           my $store = $self->store;
166              
167             # Create messages and send its
168 0           foreach my $ch (@channels) {
169             #print App::MonM::Util::explain($ch);
170             my $message = App::MonM::Message->new(
171             to => lvalue($ch, "to"),
172             cc => lvalue($ch, "cc"),
173             bcc => lvalue($ch, "bcc"),
174             from => lvalue($ch, "from"),
175             subject => $args{subject} // '', # Message subject
176 0   0       body => $args{message} // '', # Message body
      0        
177             headers => hash($ch, "headers"),
178             contenttype => lvalue($ch, "contenttype"), # optional
179             charset => lvalue($ch, "charset"), # optional
180             encoding => lvalue($ch, "encoding"), # optional
181             attachment => node($ch, "attachment"),
182             );
183              
184             # Enqueue
185             my $newid = $store->enqueue(
186             to => lvalue($ch, "to") || lvalue($ch, "recipient") || "anonymous",
187             channel => $ch->{chname},
188             subject => $args{subject} // '',
189 0   0       message => $args{message} // '',
      0        
      0        
190             attributes => $ch, # Channel attributes
191             );
192 0           $self->error($store->error);
193              
194             # Run before callback
195 0 0         if (ref($before) eq 'CODE') {
196 0 0         &$before($self, $message) or next;
197             }
198              
199             # Send message
200 0           my $sent = $self->channel->sendmsg($message, $ch);
201              
202             # ReQueue or DeQueue
203 0 0         if ($newid) {
204 0 0         if ($sent) { # SENT
205 0           $store->dequeue(
206             id => $newid
207             );
208             } else { # FAIL (NOT SENT)
209 0           $store->requeue(
210             id => $newid,
211             code => 1, # Notifier Level
212             error => $self->channel->error,
213             );
214             }
215 0           $self->error($store->error);
216             }
217              
218             # Run after callback
219 0 0         if (ref($after) eq 'CODE') {
220 0 0         &$after($self, $message, $sent) or next;
221             }
222             }
223              
224             # returns status of operation
225 0           return 1;
226             }
227             sub remind { # tries to send postponed messages
228 0     0 1   my $self = shift;
229 0           $self->error("");
230 0           my $store = $self->store;
231              
232             # Cleanup first
233 0 0         unless ($store->cleanup) {
234 0   0       $self->error($store->error || "Can't cleanup store");
235 0           return 0;
236             }
237              
238 0           while (my $entity = $store->retrieve) {
239 0 0         last if $store->error;
240 0           my $id = $entity->{id};
241 0           my $ch = hash($entity, "attributes");
242             #print App::MonM::Util::explain($entity);
243              
244             # Create message
245             my $message = App::MonM::Message->new(
246             to => lvalue($ch, "to"),
247             cc => lvalue($ch, "cc"),
248             bcc => lvalue($ch, "bcc"),
249             from => lvalue($ch, "from"),
250             subject => $entity->{subject},
251             body => $entity->{message},
252 0           headers => hash($ch, "headers"),
253             contenttype => lvalue($ch, "contenttype"), # optional
254             charset => lvalue($ch, "charset"), # optional
255             encoding => lvalue($ch, "encoding"), # optional
256             attachment => node($ch, "attachment"),
257             );
258              
259             # Send message
260 0           my $sent = $self->channel->sendmsg($message, $ch);
261              
262             # ReQueue or DeQueue
263 0 0         if ($sent) { # SENT
264 0           $store->dequeue( id => $id );
265             } else { # FAIL (NOT SENT)
266 0           $store->requeue( id => $id,
267             code => 2, # Notifier Level (remind)
268             error => $self->channel->error,
269             );
270             }
271             }
272              
273             # Set errors
274 0 0         if ($store->error) {
275 0           $self->error($store->error);
276 0           return 0;
277             }
278              
279 0           return 1;
280             }
281              
282             1;
283              
284             __END__