File Coverage

blib/lib/LINE/Bot/API/Client/Furl.pm
Criterion Covered Total %
statement 91 100 91.0
branch 10 18 55.5
condition 6 14 42.8
subroutine 19 20 95.0
pod 0 10 0.0
total 126 162 77.7


line stmt bran cond sub pod time code
1             package LINE::Bot::API::Client::Furl;
2 51     51   368 use strict;
  51         120  
  51         2244  
3 51     51   299 use warnings;
  51         139  
  51         3837  
4              
5 51     51   464 use Carp qw/ carp croak /;
  51         106  
  51         4425  
6 51     51   48257 use File::Temp;
  51         1123936  
  51         5762  
7 51     51   1924 use Furl::HTTP;
  51         855  
  51         3871  
8 51     51   324 use Furl::Headers;
  51         239  
  51         1605  
9 51     51   341 use JSON::XS;
  51         227  
  51         3278  
10              
11 51     51   8987 use LINE::Bot::API;
  51         152  
  51         1602  
12 51     51   611 use LINE::Bot::API::Client;
  51         107  
  51         69399  
13              
14             our @CARP_NOT = qw( LINE::Bot::API::Client::Furl LINE::Bot::API::Client LINE::Bot::API);
15             my $JSON = JSON::XS->new->utf8;
16              
17             sub __decode_response_body {
18 102     102   775 my ($response_body) = @_;
19              
20 102 50       746 unless ($response_body) {
21 0         0 croak 'LINE Messaging API error: response body is empty.';
22             }
23              
24 102         651 my ($ret, $error);
25             eval {
26 102         1020 $ret = $JSON->decode($response_body);
27 102         464 1;
28 102 50       262 } or do {
29 0         0 $error = $@;
30             };
31              
32 102 50       378 if ($error) {
33 0         0 croak 'LINE Messaging API error: ' . $error . '. response_body=' . $response_body;
34             }
35              
36 102         294 return $ret;
37             }
38              
39             sub new {
40 52     52 0 274 my($class, %args) = @_;
41              
42 52   50     424 $args{http_client} ||= +{};
43 52   33     427 $args{http_client}{agent} ||= "LINE::Bot::API/$LINE::Bot::API::VERSION";
44 52   50     313 $args{http_client}{timeout} ||= 3;
45             bless {
46             channel_secret => $args{channel_secret},
47             channel_access_token => $args{channel_access_token},
48             furl => Furl::HTTP->new(
49 52         122 %{ $args{http_client} }
  52         583  
50             ),
51             }, $class;
52             }
53              
54             sub credentials {
55 99     99 0 283 my $self = shift;
56             (
57 99         1307 'Authorization', "Bearer $self->{channel_access_token}"
58             );
59             }
60              
61             sub get {
62 32     32 0 97 my($self, $url) = @_;
63              
64             my($res_minor_version, $res_status, $res_msg, $res_headers, $res_content) = $self->{furl}->get(
65 32         204 $url,
66             [
67             $self->credentials,
68             ],
69             );
70              
71 32         84404 my $ret = __decode_response_body($res_content);
72 32         108 $ret->{http_status} = $res_status;
73 32         203 $ret;
74             }
75              
76             sub get_content {
77 1     1 0 11 my($self, $url) = @_;
78              
79             my($res_minor_version, $res_status, $res_msg, $res_headers, $res_content) = $self->{furl}->get(
80 1         9 $url,
81             [
82             $self->credentials,
83             ],
84             );
85              
86 1         1608 $res_content;
87             }
88              
89             sub post {
90 59     59 0 133 my($self, $url, $headers, $data);
91              
92 59 100       336 if (@_ == 3) {
    50          
93 28         81 ($self, $url, $data) = @_;
94 28         71 $headers = [];
95             } elsif (@_ == 4) {
96 31         90 ($self, $url, $headers, $data) = @_;
97             }
98              
99 59         886 my $json = $JSON->encode($data);
100             my($res_minor_version, $res_status, $res_msg, $res_headers, $res_content) = $self->{furl}->post(
101 59         368 $url,
102             [
103             @$headers,
104             $self->credentials,
105             'Content-Type' => 'application/json',
106             'Content-Length' => length($json),
107             ],
108             $json,
109             );
110              
111 59         393961 my $ret = __decode_response_body($res_content);
112 59         161 $ret->{http_status} = $res_status;
113 59         503 $ret->{http_headers} = Furl::Headers->new($res_headers);
114 59         2673 $ret;
115             }
116              
117             sub post_form {
118 4     4 0 14 my ($self, $url, $headers, $data) = @_;
119              
120 4 100       16 if (@_ == 3) {
    50          
121 3         6 ($self, $url, $data) = @_;
122             } elsif (@_ == 4) {
123 1         3 ($self, $url, $headers, $data) = @_;
124             }
125 4   100     15 $headers //= [];
126              
127             my($res_minor_version, $res_status, $res_msg, $res_headers, $res_content) = $self->{furl}->post(
128 4         34 $url,
129             [ @$headers, 'Content-Type' => 'application/x-www-form-urlencoded' ],
130             $data,
131             );
132              
133 4         6533 my $ret = __decode_response_body($res_content);
134 4         10 $ret->{http_status} = $res_status;
135 4         17 $ret;
136             }
137              
138             sub post_image {
139 1     1 0 4 my ($self, $url, $headers, $filePath) = @_;
140              
141 1   50     4 $headers //= [];
142              
143 1 50       68 open my $fh, '<', $filePath
144             or croak 'Failed to open file.';
145              
146             my($res_minor_version, $res_status, $res_msg, $res_headers, $res_content) = $self->{furl}->post(
147 1         12 $url,
148             [
149             @$headers,
150             $self->credentials,
151             ],
152             $fh,
153             );
154              
155 1         7362 close $fh;
156              
157 1         7 my $ret = __decode_response_body($res_content);
158 1         4 $ret->{http_status} = $res_status;
159 1         10 $ret;
160             }
161              
162             sub put {
163 2     2 0 4 my($self, $url, $data) = @_;
164              
165 2         15 my $json = $JSON->encode($data);
166             my($res_minor_version, $res_status, $res_msg, $res_headers, $res_content) = $self->{furl}->put(
167 2         9 $url,
168             [
169             $self->credentials,
170             'Content-Type' => 'application/json',
171             'Content-Length' => length($json),
172             ],
173             $json,
174             );
175              
176 2         12900 my $ret = __decode_response_body($res_content);
177 2         5 $ret->{http_status} = $res_status;
178 2         20 $ret->{http_headers} = Furl::Headers->new($res_headers);
179 2         72 $ret;
180             }
181              
182             sub delete {
183 4     4 0 18 my($self, $url) = @_;
184              
185             my($res_minor_version, $res_status, $res_msg, $res_headers, $res_content) = $self->{furl}->delete(
186 4         32 $url,
187             [
188             $self->credentials,
189             ],
190             );
191              
192 4         10282 my $ret = __decode_response_body($res_content);
193 4         18 $ret->{http_status} = $res_status;
194 4         28 $ret;
195             }
196              
197             sub contents_download {
198 0     0 0   my($self, $url, %options) = @_;
199              
200 0   0       my $fh = CORE::delete($options{fh}) || File::Temp->new(%options);
201              
202             my($res_minor_version, $res_status, $res_msg, $res_headers, $res_content) = $self->{furl}->request(
203 0           method => 'GET',
204             url => $url,
205             write_file => $fh,
206             headers => [
207             $self->credentials,
208             ],
209             );
210 0 0         unless ($res_status eq '200') {
211 0           carp "LINE Messaging API contents_download error: $res_status $url\n\tcontent=$res_content";
212             }
213              
214             +{
215 0           http_status => $res_status,
216             fh => $fh,
217             headers => $res_headers,
218             };
219             }
220              
221             1;