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   43083 use strict;
  4         10  
  4         110  
3 4     4   22 use warnings;
  4         8  
  4         152  
4             { our $VERSION = '0.009'; }
5              
6 4     4   853 use Ouch;
  4         3110  
  4         23  
7 4     4   733 use Mojo::URL;
  4         6396  
  4         83  
8 4     4   1104 use Log::Any qw< $log >;
  4         14651  
  4         25  
9 4     4   4538 use Scalar::Util qw< blessed weaken refaddr >;
  4         17  
  4         197  
10 4     4   949 use Bot::ChatBots::Weak;
  4         9  
  4         97  
11 4     4   931 use Try::Tiny;
  4         2444  
  4         183  
12              
13 4     4   22 use Moo::Role;
  4         32  
  4         38  
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 33 sub BUILD_code { return 204 }
51              
52 3     3 1 45 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   36 my $self = shift;
63             $self->app->hook(after_dispatch => sub {
64 7     7   1605 $self->_set_flags_rendered(@_);
65 3         33 });
66 3         58 return {};
67             }
68              
69             sub _track_flags {
70 7     7   20 my ($self, $c, $flags) = @_;
71 7         165 $self->_flags_tracker->{refaddr($c)} = $flags;
72 7         50 return $self;
73             }
74              
75             sub _set_flags_rendered {
76 7     7   26 my ($self, $c) = @_;
77 7         133 $self->_flags_tracker->{refaddr($c)}{rendered} = 1;
78 7         68 return $self;
79             }
80              
81             sub _forget_flags {
82 7     7   18 my ($self, $c) = @_;
83 7         112 my $rt = $self->_flags_tracker;
84 7         61 delete $rt->{refaddr($c)};
85 7         14 return $self;
86             }
87              
88             sub handler {
89 3     3 1 15 my $self = shift;
90 3 50 33     28 my $args = (@_ && ref($_[0])) ? $_[0] : {@_};
91              
92             return sub {
93 7     7   82914 my $c = shift;
94 7         34 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         20 my @updates;
99             try {
100 7         591 @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         65 };
106              
107 7         11477 my %flags = (rendered => 0);
108 7         36 $self->_track_flags($c => \%flags);
109 7         40 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         127 $self->_forget_flags($c);
122              
123             # did anyone set the flag? Otherwise stick to the safe side
124 7   66     114 return $flags{rendered} || $c->rendered($self->code);
125 3         22 };
126             } ## end sub handler
127              
128             sub install_route {
129 3     3 1 3340 my $self = shift;
130 3 50 33     26 my $args = (@_ && ref($_[0])) ? $_[0] : {@_};
131 3   33     73 my $method = lc($args->{method} // $self->method // 'post');
      50        
132 3   33     60 my $r = $args->{routes} // $self->app->routes;
133 3   33     116 my $p = $args->{path} // $self->path;
134 3   33     36 my $h = $args->{handler} // $self->handler($args);
135 3         32 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;