File Coverage

blib/lib/Slack/WebHook.pm
Criterion Covered Total %
statement 92 98 93.8
branch 27 40 67.5
condition 6 16 37.5
subroutine 22 23 95.6
pod 7 8 87.5
total 154 185 83.2


line stmt bran cond sub pod time code
1             # Copyright (c) 2019, cPanel, LLC.
2             # All rights reserved.
3             # http://cpanel.net
4             #
5             # This is free software; you can redistribute it and/or modify it under the
6             # same terms as Perl itself. See L.
7              
8             package Slack::WebHook;
9              
10 1     1   224682 use strict;
  1         8  
  1         29  
11 1     1   5 use warnings;
  1         2  
  1         36  
12              
13             # ABSTRACT: Slack WebHook with preset layout & colors for sending slack notifications
14              
15             BEGIN {
16              
17 1     1   22 our $VERSION = '0.001'; # VERSION: generated by DZP::OurPkgVersion
18             }
19              
20 1         7 use Simple::Accessor qw{
21             url
22             _http
23             _started_at
24 1     1   442 };
  1         722  
25              
26 1     1   737 use HTTP::Tiny;
  1         42233  
  1         43  
27 1     1   447 use JSON::MaybeXS;
  1         5588  
  1         75  
28              
29 1     1   8 use constant SLACK_COLOR_START => '#2b3bd9'; # blue
  1         2  
  1         54  
30 1     1   6 use constant SLACK_COLOR_OK => '#2eb886'; # green
  1         2  
  1         46  
31 1     1   6 use constant SLACK_COLOR_INFO => '#4b42f4'; # blue
  1         2  
  1         54  
32 1     1   7 use constant SLACK_COLOR_ERROR => '#cc0000'; # red
  1         2  
  1         46  
33 1     1   5 use constant SLACK_COLOR_WARNING => '#f5ca46'; # yellowish
  1         2  
  1         889  
34              
35             sub _build_url {
36 1     1   145 die q[Missing URL, please set it using Slack::WebHook->new( url => ... )];
37             }
38              
39             sub _build__http {
40 2     2   41 return HTTP::Tiny->new;
41             }
42              
43             sub post {
44 3     3 1 9176 my ( $self, @opts ) = @_;
45              
46 3 50       12 die "post method only takes one argument: txt or hash ref"
47             if scalar @opts > 1;
48              
49 3         6 my $txt_or_ref = $opts[0];
50 3 100       24 my $data = ref $txt_or_ref ? $txt_or_ref : { text => $txt_or_ref };
51              
52 3         8 return $self->_http_post($data);
53             }
54              
55             sub post_start {
56 2     2 1 6184 my ( $self, @args ) = @_;
57              
58 2         11 $self->_started_at( scalar time() );
59              
60 2         71 return $self->_notify(
61             { color => SLACK_COLOR_START },
62             @args
63             );
64             }
65              
66             sub post_end {
67 2     2 1 6201 my ( $self, @args ) = @_;
68              
69 2   50     7 my $delta = int( ( time() - ( $self->_started_at() // 0 ) ) );
70              
71 2         18 my $timestr = '';
72              
73 2         8 my $hours = int( $delta / 3600 );
74 2 100       6 if ($hours) {
75 1         3 $delta -= $hours * 3600;
76 1 50       4 $timestr .= " " if length $timestr;
77 1 50       5 $timestr .= "$hours hour" . ( $hours > 1 ? 's' : '' );
78             }
79 2         6 my $minutes = int( $delta / 60 );
80 2 100       6 if ($minutes) {
81 1         2 $delta -= $minutes * 60;
82 1 50       3 $timestr .= " " if length $timestr;
83 1 50       6 $timestr .= "$minutes minute" . ( $minutes > 1 ? 's' : '' );
84             }
85 2         3 my $seconds = $delta;
86             {
87 2 100       3 $timestr .= " " if length $timestr;
  2         7  
88 2 50       7 $timestr .= "$seconds second" . ( $seconds > 1 ? 's' : '' );
89             }
90              
91 2 50       13 return $self->_notify(
92             { color => SLACK_COLOR_OK,
93             $delta > 0 ? ( post_text => "\n_run time: ${timestr}_" ) : ()
94             },
95             @args
96             );
97             }
98              
99             sub post_ok {
100 2     2 1 5295 my ( $self, @args ) = @_;
101              
102 2         10 return $self->_notify(
103             { color => SLACK_COLOR_OK },
104             @args
105             );
106              
107             # could also work
108             #return $self->notify_slack( @args );
109             }
110              
111             sub post_warning {
112 2     2 1 6176 my ( $self, @args ) = @_;
113              
114 2         10 return $self->_notify(
115             { color => SLACK_COLOR_WARNING },
116             @args
117             );
118             }
119              
120             sub post_error {
121 2     2 1 6105 my ( $self, @args ) = @_;
122              
123 2         10 return $self->_notify(
124             { color => SLACK_COLOR_ERROR },
125             @args
126             );
127             }
128              
129             sub post_info {
130 0     0 1 0 my ( $self, @args ) = @_;
131              
132 0         0 return $self->_notify(
133             { color => SLACK_COLOR_INFO },
134             @args
135             );
136             }
137              
138             sub _notify {
139 10     10   27 my ( $self, $defaults, @args ) = @_;
140              
141 10 50       32 die("defaults should be a Hash Ref") unless ref $defaults eq 'HASH';
142 10         14 my @user;
143              
144 10         17 my $nb_args = scalar @args;
145              
146 10 100       22 if ( $nb_args <= 1 ) {
147 5         11 @user = ( text => $args[0] );
148             }
149             else {
150              
151 5 50       16 if ( $nb_args % 2 ) {
152 0         0 my (@caller) = caller(1);
153 0   0     0 my $called_by = $caller[3] // 'unknown';
154              
155 0         0 die q[Invalid number of args from $called_by];
156             }
157              
158 5         11 @user = @args;
159             }
160              
161 10         39 return $self->notify_slack( %$defaults, @user );
162             }
163              
164             sub notify_slack {
165 10     10 0 24 my ( $self, @args ) = @_;
166              
167 10         19 my ( $color, $title, $text );
168              
169 10         13 my $nb_args = scalar @args;
170 10 50       21 die q[No arguments to notify_slack] unless $nb_args;
171              
172 10 50       21 if ( $nb_args == 1 ) {
173 0         0 $text = $args[0];
174             }
175             else {
176 10 50       22 die q[Invalid number of arguments] if $nb_args % 2;
177 10         30 my %opts = @args;
178              
179 10         17 $color = $opts{color};
180 10         15 $title = $opts{title}; # can be undefined
181 10   66     27 $text = $opts{text} // $opts{body} // $opts{content} // '';
      33        
      0        
182              
183 10 100       40 $text .= $opts{post_text} if defined $opts{post_text};
184             }
185              
186             # title can be undefined
187 10   50     20 $color //= SLACK_COLOR_OK;
188 10   50     20 $text //= '';
189              
190 10 100       42 my $data = {
191             attachments => [
192             { defined $title ? ( title => $title ) : (),
193             color => $color,
194             text => $text,
195             mrkdwn_in => [qw/text title/],
196             }
197             ]
198             };
199              
200 10         27 return $self->_http_post($data);
201             }
202              
203             sub _http_post {
204 13     13   29 my ( $self, $data ) = @_;
205              
206 13 50       34 die unless ref $data eq 'HASH';
207              
208 13         34 return $self->_http->post_form(
209             $self->url,
210             { payload => encode_json($data) },
211             );
212              
213             }
214              
215             1;
216              
217             __END__