File Coverage

blib/lib/LINE/Bot/API.pm
Criterion Covered Total %
statement 265 289 91.7
branch 15 24 62.5
condition 7 14 50.0
subroutine 70 74 94.5
pod 42 47 89.3
total 399 448 89.0


line stmt bran cond sub pod time code
1             package LINE::Bot::API;
2 46     46   5058919 use strict;
  46         472  
  46         1390  
3 46     46   257 use warnings;
  46         94  
  46         1870  
4             our $VERSION = '1.18';
5              
6 46     46   20718 use LINE::Bot::API::Builder::SendMessage;
  46         123  
  46         1415  
7 46     46   13922 use LINE::Bot::API::Client;
  46         120  
  46         1309  
8 46     46   19358 use LINE::Bot::API::Event;
  46         141  
  46         1462  
9 46     46   14638 use LINE::Bot::API::Response::Common;
  46         174  
  46         1170  
10 46     46   18386 use LINE::Bot::API::Response::Content;
  46         142  
  46         1284  
11 46     46   18416 use LINE::Bot::API::Response::Count;
  46         2184  
  46         3386  
12 46     46   18653 use LINE::Bot::API::Response::FriendDemographics;
  46         175  
  46         1293  
13 46     46   18261 use LINE::Bot::API::Response::NumberOfSentMessages;
  46         145  
  46         1306  
14 46     46   18851 use LINE::Bot::API::Response::NumberOfMessageDeliveries;
  46         131  
  46         1291  
15 46     46   18709 use LINE::Bot::API::Response::Profile;
  46         142  
  46         1408  
16 46     46   18469 use LINE::Bot::API::Response::GroupMemberProfile;
  46         132  
  46         1283  
17 46     46   18361 use LINE::Bot::API::Response::GroupSummary;
  46         136  
  46         1317  
18 46     46   18608 use LINE::Bot::API::Response::RoomMemberProfile;
  46         151  
  46         1356  
19 46     46   18585 use LINE::Bot::API::Response::IssueLinkToken;
  46         129  
  46         1329  
20 46     46   18464 use LINE::Bot::API::Response::RichMenu;
  46         127  
  46         1345  
21 46     46   19487 use LINE::Bot::API::Response::RichMenuList;
  46         148  
  46         1345  
22 46     46   18459 use LINE::Bot::API::Response::TargetLimit;
  46         131  
  46         1339  
23 46     46   18511 use LINE::Bot::API::Response::TotalUsage;
  46         161  
  46         1318  
24 46     46   18439 use LINE::Bot::API::Response::Token;
  46         118  
  46         1433  
25 46     46   18642 use LINE::Bot::API::Response::NumberOfFollowers;
  46         134  
  46         1673  
26 46     46   18632 use LINE::Bot::API::Response::UserInteractionStatistics;
  46         137  
  46         1897  
27              
28             use constant {
29 46         4588 DEFAULT_MESSAGING_API_ENDPOINT => 'https://api.line.me/v2/bot/',
30             DEFAULT_SOCIAL_API_ENDPOINT => 'https://api.line.me/v2/oauth/',
31             DEFAULT_CONTENT_API_ENDPOINT => 'https://api-data.line.me/v2/bot/',
32             DEFAULT_OAUTH2_API_ENDPOINT => 'https://api.line.me/oauth2/v2.1/',
33 46     46   303 };
  46         85  
34 46     46   16420 use Furl;
  46         168964  
  46         1350  
35 46     46   292 use Carp 'croak';
  46         98  
  46         2261  
36 46     46   15821 use URI::Escape;
  46         56373  
  46         145409  
37              
38             sub new {
39 34     34 1 4546 my($class, %args) = @_;
40              
41 34         360 my $client = LINE::Bot::API::Client->new(%args);
42              
43             bless {
44             client => $client,
45             channel_secret => $args{channel_secret},
46             channel_access_token => $args{channel_access_token},
47             messaging_api_endpoint => $args{messaging_api_endpoint} // DEFAULT_MESSAGING_API_ENDPOINT,
48             social_api_endpoint => $args{social_api_endpoint} // DEFAULT_SOCIAL_API_ENDPOINT,
49             content_api_endpoint => $args{content_api_endpoint} // DEFAULT_CONTENT_API_ENDPOINT,
50 34   50     2855 oauth_api_endpoint => $args{oauth_api_endpoint} // DEFAULT_OAUTH2_API_ENDPOINT,
      50        
      50        
      50        
51             }, $class;
52             }
53              
54             sub request {
55 68     68 0 222 my ($self, $method, $path, @payload) = @_;
56              
57             return $self->{client}->$method(
58 68         514 $self->{messaging_api_endpoint} . $path,
59             @payload,
60             );
61             }
62              
63             sub request_content {
64 0     0 0 0 my ($self, $method, $path, @payload) = @_;
65              
66             return $self->{client}->$method(
67 0         0 $self->{content_api_endpoint} . $path,
68             @payload,
69             );
70             }
71              
72             sub reply_message {
73 11     11 1 54 my($self, $reply_token, $messages) = @_;
74              
75 11         66 my $res = $self->request(
76             post => 'message/reply',
77             +{
78             replyToken => $reply_token,
79             messages => $messages,
80             }
81             );
82              
83 11         44 LINE::Bot::API::Response::Common->new(%{ $res });
  11         69  
84             }
85              
86             sub push_message {
87 25     25 1 78 my($self, $to_id, $messages, $options) = @_;
88              
89 25         46 my @headers = ();
90 25 100 66     116 if ($options && defined($options->{'retry_key'})) {
91 1         6 push @headers, 'X-Line-Retry-Key' => $options->{'retry_key'};
92             }
93              
94 25         139 my $res = $self->request(
95             post => 'message/push',
96             \@headers,
97             +{
98             to => $to_id,
99             messages => $messages,
100             }
101             );
102 25         71 LINE::Bot::API::Response::Common->new(%{ $res });
  25         211  
103             }
104              
105             sub multicast {
106 1     1 1 5 my($self, $to_ids, $messages, $options) = @_;
107              
108 1         2 my @headers = ();
109 1 50 33     5 if ($options && defined($options->{'retry_key'})) {
110 0         0 push @headers, 'X-Line-Retry-Key' => $options->{'retry_key'};
111             }
112              
113 1         8 my $res = $self->request(
114             post => 'message/multicast',
115             \@headers,
116             +{
117             to => $to_ids,
118             messages => $messages,
119             }
120             );
121 1         51 LINE::Bot::API::Response::Common->new(%{ $res });
  1         20  
122             }
123              
124             sub broadcast {
125 2     2 1 8 my($self, $messages, $options) = @_;
126              
127 2         33 my @headers = ();
128 2 100       10 if (defined($options->{'retry_key'})) {
129 1         3 push @headers, 'X-Line-Retry-Key' => $options->{'retry_key'};
130             }
131              
132 2         12 my $res = $self->request(
133             post => 'message/broadcast',
134             \@headers,
135             +{
136             messages => $messages,
137             }
138             );
139 2         8 LINE::Bot::API::Response::Common->new(%{ $res });
  2         17  
140             }
141              
142             sub get_message_content {
143 0     0 1 0 my($self, $message_id, %options) = @_;
144 0         0 my $res = $self->request_content(
145             'contents_download' => "message/$message_id/content",
146             %options
147             );
148 0         0 LINE::Bot::API::Response::Content->new(%{ $res });
  0         0  
149             }
150              
151             sub get_profile {
152 1     1 1 35 my($self, $user_id) = @_;
153 1         7 my $res = $self->request(get => "profile/$user_id");
154 1         3 LINE::Bot::API::Response::Profile->new(%{ $res });
  1         20  
155             }
156              
157             sub get_group_member_profile {
158 1     1 1 31 my($self, $group_id, $user_id) = @_;
159 1         6 my $res = $self->request(get => "group/$group_id/member/$user_id");
160 1         3 LINE::Bot::API::Response::GroupMemberProfile->new(%{ $res });
  1         19  
161             }
162              
163             sub get_room_member_profile {
164 1     1 1 27 my($self, $room_id, $user_id) = @_;
165 1         7 my $res = $self->request(get => "room/$room_id/member/$user_id");
166 1         2 LINE::Bot::API::Response::RoomMemberProfile->new(%{ $res });
  1         16  
167             }
168              
169             sub leave_room {
170 0     0 1 0 my($self, $room_id) = @_;
171 0         0 my $res = $self->request(post => "room/$room_id/leave", +{});
172 0         0 LINE::Bot::API::Response::Common->new(%{ $res });
  0         0  
173             }
174              
175             sub leave_group {
176 0     0 1 0 my($self, $group_id) = @_;
177 0         0 my $res = $self->request(post => "group/$group_id/leave", +{});
178 0         0 LINE::Bot::API::Response::Common->new(%{ $res });
  0         0  
179             }
180              
181             sub get_friend_demographics {
182 1     1 1 41 my($self) = @_;
183 1         4 my $res = $self->request(get => "insight/demographic");
184 1         2 LINE::Bot::API::Response::FriendDemographics->new(%{ $res });
  1         19  
185             }
186              
187             sub get_target_limit_for_additional_messages {
188 1     1 1 38 my($self, $date) = @_;
189 1         4 my $res = $self->request(get => "message/quota");
190 1         3 LINE::Bot::API::Response::TargetLimit->new(%{ $res });
  1         18  
191             }
192              
193             sub get_number_of_messages_sent_this_month {
194 1     1 1 33 my($self, $date) = @_;
195 1         5 my $res = $self->request(get => "message/quota/consumption");
196 1         3 LINE::Bot::API::Response::TotalUsage->new(%{ $res });
  1         19  
197             }
198              
199             sub get_number_of_sent_reply_messages {
200 1     1 1 38 my($self, $date) = @_;
201 1         8 my $res = $self->request(get => "message/delivery/reply?date=${date}");
202 1         3 LINE::Bot::API::Response::NumberOfSentMessages->new(%{ $res });
  1         18  
203             }
204              
205             sub get_number_of_sent_push_messages {
206 1     1 1 651 my($self, $date) = @_;
207 1         8 my $res = $self->request(get => "message/delivery/push?date=${date}", +{});
208 1         4 LINE::Bot::API::Response::NumberOfSentMessages->new(%{ $res });
  1         7  
209             }
210              
211             sub get_number_of_sent_multicast_messages {
212 1     1 1 628 my($self, $date) = @_;
213 1         7 my $res = $self->request(get => "message/delivery/multicast?date=${date}", +{});
214 1         4 LINE::Bot::API::Response::NumberOfSentMessages->new(%{ $res });
  1         7  
215             }
216              
217             sub get_number_of_send_broadcast_messages {
218 1     1 1 820 my($self, $date) = @_;
219 1         7 my $res = $self->request(get => "message/delivery/broadcast?date=${date}", +{});
220 1         4 LINE::Bot::API::Response::NumberOfSentMessages->new(%{ $res });
  1         7  
221             }
222              
223             sub get_number_of_message_deliveries {
224 1     1 1 38 my($self, $opts) = @_;
225 1 50       5 my $date = $opts->{date} or croak "get_number_of_message_deliveries: Missing a `date` parameter.";
226              
227 1         7 my $res = $self->request(get => "insight/message/delivery?date=${date}", +{});
228 1         3 LINE::Bot::API::Response::NumberOfMessageDeliveries->new(%{ $res });
  1         22  
229             }
230              
231             sub get_member_in_room_count {
232 1     1 1 1629 my ($self, $room_id) = @_;
233              
234 1         7 my $res = $self->request(get => "room/${room_id}/members/count", +{});
235 1         3 LINE::Bot::API::Response::Count->new(%{ $res });
  1         17  
236             }
237              
238             sub get_member_in_group_count {
239 1     1 1 1681 my ($self, $group_id) = @_;
240              
241 1         7 my $res = $self->request(get => "group/${group_id}/members/count", +{});
242 1         3 LINE::Bot::API::Response::Count->new(%{ $res });
  1         18  
243             }
244              
245             sub get_group_summary {
246 1     1 1 1510 my ($self, $group_id) = @_;
247              
248 1         6 my $res = $self->request(get => "group/${group_id}/summary", +{});
249 1         2 LINE::Bot::API::Response::GroupSummary->new(%{ $res });
  1         16  
250             }
251              
252             sub validate_signature {
253 2     2 1 6465 my($self, $json, $signature) = @_;
254 2         17 LINE::Bot::API::Event->validate_signature($json, $self->{channel_secret}, $signature);
255             }
256              
257             sub parse_events_from_json {
258 1     1 1 5182 my($self, $json) = @_;
259 1         7 LINE::Bot::API::Event->parse_events_json($json);
260             }
261              
262             sub issue_link_token {
263 1     1 0 33 my($self, $user_id) = @_;
264 1         7 my $res = $self->request(post => "user/${user_id}/linkToken", +{});
265 1         7 LINE::Bot::API::Response::IssueLinkToken->new(%{ $res });
  1         18  
266             }
267              
268             sub create_rich_menu {
269 1     1 1 1687 my ($self, $rich_menu) = @_;
270 1         5 my $res = $self->request(post => "richmenu", $rich_menu);
271 1         3 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         19  
272             }
273              
274             sub get_rich_menu {
275 1     1 1 4042 my ($self, $rich_menu_id) = @_;
276 1         5 my $res = $self->request(get => "richmenu/${rich_menu_id}");
277 1         4 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         6  
278             }
279              
280             sub delete_rich_menu {
281 1     1 1 3616 my ($self, $rich_menu_id) = @_;
282 1         6 my $res = $self->request(delete => "richmenu/${rich_menu_id}");
283 1         2 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         6  
284             }
285              
286             sub get_rich_menu_list {
287 1     1 1 3540 my ($self) = @_;
288 1         4 my $res = $self->request(get => "richmenu/list");
289 1         3 LINE::Bot::API::Response::RichMenuList->new(%{ $res });
  1         17  
290             }
291              
292             sub set_default_rich_menu {
293 1     1 1 3702 my ($self, $rich_menu_id) = @_;
294 1         7 my $res = $self->request(post => "user/all/richmenu/${rich_menu_id}", +{});
295 1         3 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         41  
296             }
297              
298             sub get_default_rich_menu_id {
299 1     1 1 3594 my ($self) = @_;
300 1         4 my $res = $self->request(get => "user/all/richmenu");
301 1         3 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         5  
302             }
303              
304             sub cancel_default_rich_menu {
305 1     1 1 3502 my ($self) = @_;
306 1         5 my $res = $self->request(delete => "user/all/richmenu");
307 1         4 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         6  
308             }
309              
310             sub link_rich_menu_to_user {
311 1     1 1 3518 my ($self, $user_id, $rich_menu_id) = @_;
312 1         7 my $res = $self->request(post => "user/${user_id}/richmenu/${rich_menu_id}", +{});
313 1         4 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         7  
314             }
315              
316             sub link_rich_menu_to_multiple_users {
317 1     1 1 3529 my ($self, $user_ids, $rich_menu_id) = @_;
318 1         6 my $res = $self->request(post => "richmenu/bulk/link", +{
319             richMenuId => $rich_menu_id,
320             userIds => $user_ids,
321             });
322 1         4 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         7  
323             }
324              
325             sub get_rich_menu_id_of_user {
326 1     1 1 3634 my ($self, $user_id, $rich_menu_id) = @_;
327 1         6 my $res = $self->request(get => "user/${user_id}/richmenu");
328 1         4 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         6  
329             }
330              
331             sub unlink_rich_menu_from_user {
332 1     1 1 3526 my ($self, $user_id) = @_;
333 1         7 my $res = $self->request(delete => "user/${user_id}/richmenu");
334 1         2 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         6  
335             }
336              
337             sub unlink_rich_menu_from_multiple_users {
338 1     1 1 3610 my ($self, $user_ids) = @_;
339 1         6 my $res = $self->request(post => "richmenu/bulk/unlink", +{
340             userIds => $user_ids,
341             });
342 1         4 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         6  
343             }
344              
345             sub upload_rich_menu_image {
346 1     1 0 1723 my ($self, $rich_menu_id, $content_type, $file_path) = @_;
347              
348 1 50       6 if (!$content_type) {
349 0         0 croak 'Need content_type';
350             }
351              
352             my $res = $self->{client}->post_image(
353 1         11 $self->{content_api_endpoint} . "richmenu/$rich_menu_id/content",
354             [
355             'Content-Type' => $content_type,
356             ],
357             $file_path
358             );
359              
360 1 50       7 if ($res->{http_status} eq '200') {
361 1         3 return LINE::Bot::API::Response::Token->new(%{ $res });
  1         19  
362             } else {
363 0         0 return LINE::Bot::API::Response::Error->new(%{ $res });
  0         0  
364             }
365              
366             }
367              
368             sub download_rich_menu_image {
369 1     1 0 1992 my ($self, $rich_menu_id) = @_;
370              
371             return $self->{client}->get_content(
372 1         11 $self->{content_api_endpoint} . "richmenu/$rich_menu_id/content"
373             );
374             }
375              
376             sub issue_channel_access_token {
377 1     1 1 1668 my ($self, $opts) = @_;
378              
379             my $res = $self->{client}->post_form(
380             $self->{social_api_endpoint} . 'accessToken',
381             [
382             grant_type => 'client_credentials',
383             client_id => $opts->{client_id},
384             client_secret => $opts->{client_secret},
385 1         9 ]
386             );
387              
388 1 50       5 if ($res->{http_status} eq '200') {
389 1         3 return LINE::Bot::API::Response::Token->new(%{ $res });
  1         18  
390             } else {
391 0         0 return LINE::Bot::API::Response::Error->new(%{ $res });
  0         0  
392             }
393             }
394              
395             sub issue_channel_access_token_v2_1 {
396 1     1 1 3388 my ($self, $opts) = @_;
397              
398             my $res = $self->{client}->post_form(
399             $self->{oauth_api_endpoint} . 'token',
400             undef,
401             [
402             grant_type => 'client_credentials',
403             client_assertion_type => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
404             client_assertion => $opts->{jwt},
405 1         10 ]
406             );
407              
408 1 50       6 if ($res->{http_status} eq '200') {
409 1         3 return LINE::Bot::API::Response::Token->new(%{ $res });
  1         7  
410             } else {
411 0         0 return LINE::Bot::API::Response::Error->new(%{ $res });
  0         0  
412             }
413             }
414              
415             sub get_valid_channel_access_token_v2_1 {
416 1     1 1 4183 my ($self, $opts) = @_;
417              
418 1         7 my $jwt = uri_escape($opts->{jwt});
419 1         60 my $assertion_type = uri_escape('urn:ietf:params:oauth:client-assertion-type:jwt-bearer');
420              
421             my $res = $self->{client}->get(
422 1         53 $self->{oauth_api_endpoint} . 'tokens/kid' . "?client_assertion_type=$assertion_type&client_assertion=$jwt",
423             );
424              
425 1 50       7 if ($res->{http_status} eq '200') {
426 1         4 return LINE::Bot::API::Response::Token->new(%{ $res });
  1         6  
427             } else {
428 0         0 return LINE::Bot::API::Response::Error->new(%{ $res });
  0         0  
429             }
430             }
431              
432             sub revoke_channel_access_token {
433 2     2 1 7637 my ($self, $opts) = @_;
434              
435             my $res = $self->{client}->post_form(
436             $self->{social_api_endpoint} . 'revoke',
437             [
438             access_token => $opts->{access_token},
439 2         13 ]
440             );
441              
442 2 100       10 if ($res->{http_status} eq '200') {
443 1         3 return LINE::Bot::API::Response::Common->new(%{ $res });
  1         6  
444             } else {
445 1         3 return LINE::Bot::API::Response::Error->new(%{ $res });
  1         16  
446             }
447             }
448              
449             sub get_number_of_followers {
450 1     1 1 40 my ($self, $opts) = @_;
451 1 50       4 my $date = $opts->{date} or croak "get_number_of_followers: Missing a `date` parameter.";
452              
453 1         8 my $res = $self->request(get => "insight/followers?date=${date}");
454 1         3 LINE::Bot::API::Response::NumberOfFollowers->new(%{ $res });
  1         20  
455             }
456              
457             sub get_user_interaction_statistics {
458 1     1 1 35 my ($self, $opts) = @_;
459 1 50       5 my $requestId = $opts->{requestId} or croak "get_user_interaction_statistics: Missing a `requestId` parameter.";
460              
461 1         6 my $res = $self->request(get => "insight/message/event?requestId=${requestId}");
462 1         2 LINE::Bot::API::Response::UserInteractionStatistics->new(%{ $res });
  1         18  
463             }
464              
465             1;
466             __END__