File Coverage

blib/lib/Bot/ChatBots/Role/WebHook.pm
Criterion Covered Total %
statement 63 70 90.0
branch 2 8 25.0
condition 9 23 39.1
subroutine 19 21 90.4
pod 6 6 100.0
total 99 128 77.3


line stmt bran cond sub pod time code
1             package Bot::ChatBots::Role::WebHook;
2 4     4   36862 use strict;
  4         10  
  4         98  
3 4     4   15 use warnings;
  4         8  
  4         139  
4             { our $VERSION = '0.014'; }
5              
6 4     4   762 use Ouch;
  4         2817  
  4         18  
7 4     4   643 use Mojo::URL;
  4         6029  
  4         42  
8 4     4   1010 use Log::Any qw< $log >;
  4         13458  
  4         23  
9 4     4   4106 use Scalar::Util qw< blessed weaken refaddr >;
  4         9  
  4         204  
10 4     4   803 use Bot::ChatBots::Weak;
  4         8  
  4         85  
11 4     4   853 use Try::Tiny;
  4         2114  
  4         170  
12              
13 4     4   22 use Moo::Role;
  4         21  
  4         26  
14              
15             with 'Bot::ChatBots::Role::Source';
16             requires 'process_updates';
17              
18             has app => (
19             is => 'ro',
20             lazy => 1,
21             weak_ref => 1,
22             );
23              
24             has code => (
25             is => 'ro',
26             lazy => 1,
27             builder => 'BUILD_code',
28             );
29              
30             has method => (
31             is => 'ro',
32             lazy => 1,
33             builder => 'BUILD_method',
34             );
35              
36             has path => (
37             is => 'ro',
38             lazy => 1,
39             builder => 'BUILD_path',
40             );
41              
42             has _flags_tracker => (
43             is => 'ro',
44             lazy => 1,
45             builder => '_BUILD_flags_tracker',
46             );
47              
48             has url => (is => 'ro');
49              
50 2     2 1 24 sub BUILD_code { return 204 }
51              
52 3     3 1 35 sub BUILD_method { return 'post' }
53              
54             sub BUILD_path {
55 0     0 1 0 my $self = shift;
56 0 0       0 defined(my $url = $self->url)
57             or ouch 500, 'undefined path and url for WebHook';
58 0         0 return Mojo::URL->new($url)->path->to_string;
59             } ## end sub BUILD_path
60              
61             sub _BUILD_flags_tracker {
62 3     3   29 my $self = shift;
63             $self->app->hook(after_dispatch => sub {
64 7     7   1402 $self->_set_flags_rendered(@_);
65 3         29 });
66 3         56 return {};
67             }
68              
69             sub _track_flags {
70 7     7   16 my ($self, $c, $flags) = @_;
71 7         151 $self->_flags_tracker->{refaddr($c)} = $flags;
72 7         35 return $self;
73             }
74              
75             sub _set_flags_rendered {
76 7     7   14 my ($self, $c) = @_;
77 7         125 $self->_flags_tracker->{refaddr($c)}{rendered} = 1;
78 7         61 return $self;
79             }
80              
81             sub _forget_flags {
82 7     7   15 my ($self, $c) = @_;
83 7         106 my $rt = $self->_flags_tracker;
84 7         55 delete $rt->{refaddr($c)};
85 7         11 return $self;
86             }
87              
88             sub handler {
89 3     3 1 7 my $self = shift;
90 3 50 33     29 my $args = (@_ && ref($_[0])) ? $_[0] : {@_};
91              
92             return sub {
93 7     7   97763 my $c = shift;
94 7         33 my $c_address = refaddr $c;
95              
96             # whatever happens, the bot "cannot" fail or the platform will hammer
97             # us with the same update over and over
98 7         11 my @updates;
99             try {
100 7         531 @updates = $self->parse_request($c->req);
101             }
102             catch {
103 0         0 $log->error(bleep $_);
104 0 0       0 die $_ if $self->should_rethrow($args);
105 7         82 };
106              
107 7         10404 my %flags = (rendered => 0);
108 7         27 $self->_track_flags($c => \%flags);
109 7         33 my @retval = $self->process_updates(
110             refs => {
111             app => $self->app,
112             controller => $c,
113             stash => $c->stash,
114             },
115             source_pairs => {
116             flags => \%flags,
117             },
118             updates => \@updates,
119             %$args, # may override it all!
120             );
121 7         116 $self->_forget_flags($c);
122              
123             # did anyone set the flag? Otherwise stick to the safe side
124 7   66     102 return $flags{rendered} || $c->rendered($self->code);
125 3         21 };
126             } ## end sub handler
127              
128             sub install_route {
129 3     3 1 3181 my $self = shift;
130 3 50 33     18 my $args = (@_ && ref($_[0])) ? $_[0] : {@_};
131 3   33     69 my $method = lc($args->{method} // $self->method // 'post');
      50        
132 3   33     45 my $r = $args->{routes} // $self->app->routes;
133 3   33     96 my $p = $args->{path} // $self->path;
134 3   33     31 my $h = $args->{handler} // $self->handler($args);
135 3         27 return $r->$method($p => $h);
136             } ## end sub install_route
137              
138             sub parse_request { # most APIs rely on JSON... let's leverage this
139 0     0 1   my ($self, $req) = @_;
140 0           return $req->json;
141             }
142              
143             1;