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   5013579 use strict;
  46         433  
  46         1410  
3 46     46   243 use warnings;
  46         83  
  46         1904  
4             our $VERSION = '1.19';
5              
6 46     46   20966 use LINE::Bot::API::Builder::SendMessage;
  46         178  
  46         1462  
7 46     46   14625 use LINE::Bot::API::Client;
  46         120  
  46         1246  
8 46     46   20429 use LINE::Bot::API::Event;
  46         128  
  46         1441  
9 46     46   15068 use LINE::Bot::API::Response::Common;
  46         113  
  46         1109  
10 46     46   19479 use LINE::Bot::API::Response::Content;
  46         125  
  46         1294  
11 46     46   19329 use LINE::Bot::API::Response::Count;
  46         1247  
  46         2254  
12 46     46   19375 use LINE::Bot::API::Response::FriendDemographics;
  46         120  
  46         1263  
13 46     46   19135 use LINE::Bot::API::Response::NumberOfSentMessages;
  46         125  
  46         1299  
14 46     46   19881 use LINE::Bot::API::Response::NumberOfMessageDeliveries;
  46         137  
  46         1289  
15 46     46   19696 use LINE::Bot::API::Response::Profile;
  46         119  
  46         1410  
16 46     46   19660 use LINE::Bot::API::Response::GroupMemberProfile;
  46         133  
  46         1267  
17 46     46   19601 use LINE::Bot::API::Response::GroupSummary;
  46         128  
  46         1249  
18 46     46   19340 use LINE::Bot::API::Response::RoomMemberProfile;
  46         131  
  46         1318  
19 46     46   19352 use LINE::Bot::API::Response::IssueLinkToken;
  46         121  
  46         1392  
20 46     46   19515 use LINE::Bot::API::Response::RichMenu;
  46         129  
  46         1289  
21 46     46   19584 use LINE::Bot::API::Response::RichMenuList;
  46         123  
  46         1392  
22 46     46   19534 use LINE::Bot::API::Response::TargetLimit;
  46         146  
  46         1279  
23 46     46   19129 use LINE::Bot::API::Response::TotalUsage;
  46         143  
  46         1248  
24 46     46   19028 use LINE::Bot::API::Response::Token;
  46         130  
  46         1787  
25 46     46   19776 use LINE::Bot::API::Response::NumberOfFollowers;
  46         125  
  46         1262  
26 46     46   19498 use LINE::Bot::API::Response::UserInteractionStatistics;
  46         128  
  46         1783  
27              
28             use constant {
29 46         4512 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   281 };
  46         82  
34 46     46   16768 use Furl;
  46         168124  
  46         1293  
35 46     46   283 use Carp 'croak';
  46         86  
  46         2177  
36 46     46   16249 use URI::Escape;
  46         53693  
  46         141500  
37              
38             sub new {
39 34     34 1 4283 my($class, %args) = @_;
40              
41 34         358 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     2700 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 239 my ($self, $method, $path, @payload) = @_;
56              
57             return $self->{client}->$method(
58 68         500 $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 46 my($self, $reply_token, $messages) = @_;
74              
75 11         62 my $res = $self->request(
76             post => 'message/reply',
77             +{
78             replyToken => $reply_token,
79             messages => $messages,
80             }
81             );
82              
83 11         46 LINE::Bot::API::Response::Common->new(%{ $res });
  11         88  
84             }
85              
86             sub push_message {
87 25     25 1 75 my($self, $to_id, $messages, $options) = @_;
88              
89 25         49 my @headers = ();
90 25 100 66     124 if ($options && defined($options->{'retry_key'})) {
91 1         5 push @headers, 'X-Line-Retry-Key' => $options->{'retry_key'};
92             }
93              
94 25         144 my $res = $self->request(
95             post => 'message/push',
96             \@headers,
97             +{
98             to => $to_id,
99             messages => $messages,
100             }
101             );
102 25         75 LINE::Bot::API::Response::Common->new(%{ $res });
  25         213  
103             }
104              
105             sub multicast {
106 1     1 1 3 my($self, $to_ids, $messages, $options) = @_;
107              
108 1         2 my @headers = ();
109 1 50 33     6 if ($options && defined($options->{'retry_key'})) {
110 0         0 push @headers, 'X-Line-Retry-Key' => $options->{'retry_key'};
111             }
112              
113 1         7 my $res = $self->request(
114             post => 'message/multicast',
115             \@headers,
116             +{
117             to => $to_ids,
118             messages => $messages,
119             }
120             );
121 1         3 LINE::Bot::API::Response::Common->new(%{ $res });
  1         11  
122             }
123              
124             sub broadcast {
125 2     2 1 7 my($self, $messages, $options) = @_;
126              
127 2         5 my @headers = ();
128 2 100       9 if (defined($options->{'retry_key'})) {
129 1         3 push @headers, 'X-Line-Retry-Key' => $options->{'retry_key'};
130             }
131              
132 2         11 my $res = $self->request(
133             post => 'message/broadcast',
134             \@headers,
135             +{
136             messages => $messages,
137             }
138             );
139 2         6 LINE::Bot::API::Response::Common->new(%{ $res });
  2         43  
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 28 my($self, $user_id) = @_;
153 1         5 my $res = $self->request(get => "profile/$user_id");
154 1         3 LINE::Bot::API::Response::Profile->new(%{ $res });
  1         15  
155             }
156              
157             sub get_group_member_profile {
158 1     1 1 28 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         14  
161             }
162              
163             sub get_room_member_profile {
164 1     1 1 30 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         17  
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 42 my($self) = @_;
183 1         5 my $res = $self->request(get => "insight/demographic");
184 1         3 LINE::Bot::API::Response::FriendDemographics->new(%{ $res });
  1         17  
185             }
186              
187             sub get_target_limit_for_additional_messages {
188 1     1 1 37 my($self, $date) = @_;
189 1         8 my $res = $self->request(get => "message/quota");
190 1         3 LINE::Bot::API::Response::TargetLimit->new(%{ $res });
  1         16  
191             }
192              
193             sub get_number_of_messages_sent_this_month {
194 1     1 1 37 my($self, $date) = @_;
195 1         5 my $res = $self->request(get => "message/quota/consumption");
196 1         2 LINE::Bot::API::Response::TotalUsage->new(%{ $res });
  1         19  
197             }
198              
199             sub get_number_of_sent_reply_messages {
200 1     1 1 28 my($self, $date) = @_;
201 1         5 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 718 my($self, $date) = @_;
207 1         7 my $res = $self->request(get => "message/delivery/push?date=${date}", +{});
208 1         3 LINE::Bot::API::Response::NumberOfSentMessages->new(%{ $res });
  1         6  
209             }
210              
211             sub get_number_of_sent_multicast_messages {
212 1     1 1 717 my($self, $date) = @_;
213 1         7 my $res = $self->request(get => "message/delivery/multicast?date=${date}", +{});
214 1         3 LINE::Bot::API::Response::NumberOfSentMessages->new(%{ $res });
  1         6  
215             }
216              
217             sub get_number_of_send_broadcast_messages {
218 1     1 1 686 my($self, $date) = @_;
219 1         7 my $res = $self->request(get => "message/delivery/broadcast?date=${date}", +{});
220 1         3 LINE::Bot::API::Response::NumberOfSentMessages->new(%{ $res });
  1         7  
221             }
222              
223             sub get_number_of_message_deliveries {
224 1     1 1 34 my($self, $opts) = @_;
225 1 50       4 my $date = $opts->{date} or croak "get_number_of_message_deliveries: Missing a `date` parameter.";
226              
227 1         6 my $res = $self->request(get => "insight/message/delivery?date=${date}", +{});
228 1         4 LINE::Bot::API::Response::NumberOfMessageDeliveries->new(%{ $res });
  1         19  
229             }
230              
231             sub get_member_in_room_count {
232 1     1 1 1358 my ($self, $room_id) = @_;
233              
234 1         6 my $res = $self->request(get => "room/${room_id}/members/count", +{});
235 1         2 LINE::Bot::API::Response::Count->new(%{ $res });
  1         14  
236             }
237              
238             sub get_member_in_group_count {
239 1     1 1 1726 my ($self, $group_id) = @_;
240              
241 1         5 my $res = $self->request(get => "group/${group_id}/members/count", +{});
242 1         2 LINE::Bot::API::Response::Count->new(%{ $res });
  1         14  
243             }
244              
245             sub get_group_summary {
246 1     1 1 1301 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         15  
250             }
251              
252             sub validate_signature {
253 2     2 1 5361 my($self, $json, $signature) = @_;
254 2         14 LINE::Bot::API::Event->validate_signature($json, $self->{channel_secret}, $signature);
255             }
256              
257             sub parse_events_from_json {
258 1     1 1 4211 my($self, $json) = @_;
259 1         5 LINE::Bot::API::Event->parse_events_json($json);
260             }
261              
262             sub issue_link_token {
263 1     1 0 32 my($self, $user_id) = @_;
264 1         9 my $res = $self->request(post => "user/${user_id}/linkToken", +{});
265 1         3 LINE::Bot::API::Response::IssueLinkToken->new(%{ $res });
  1         18  
266             }
267              
268             sub create_rich_menu {
269 1     1 1 1619 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         17  
272             }
273              
274             sub get_rich_menu {
275 1     1 1 3971 my ($self, $rich_menu_id) = @_;
276 1         5 my $res = $self->request(get => "richmenu/${rich_menu_id}");
277 1         2 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         6  
278             }
279              
280             sub delete_rich_menu {
281 1     1 1 3595 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 3521 my ($self) = @_;
288 1         4 my $res = $self->request(get => "richmenu/list");
289 1         3 LINE::Bot::API::Response::RichMenuList->new(%{ $res });
  1         14  
290             }
291              
292             sub set_default_rich_menu {
293 1     1 1 3688 my ($self, $rich_menu_id) = @_;
294 1         6 my $res = $self->request(post => "user/all/richmenu/${rich_menu_id}", +{});
295 1         4 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         6  
296             }
297              
298             sub get_default_rich_menu_id {
299 1     1 1 3482 my ($self) = @_;
300 1         5 my $res = $self->request(get => "user/all/richmenu");
301 1         3 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         7  
302             }
303              
304             sub cancel_default_rich_menu {
305 1     1 1 3501 my ($self) = @_;
306 1         5 my $res = $self->request(delete => "user/all/richmenu");
307 1         3 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         6  
308             }
309              
310             sub link_rich_menu_to_user {
311 1     1 1 3515 my ($self, $user_id, $rich_menu_id) = @_;
312 1         7 my $res = $self->request(post => "user/${user_id}/richmenu/${rich_menu_id}", +{});
313 1         3 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         6  
314             }
315              
316             sub link_rich_menu_to_multiple_users {
317 1     1 1 3550 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         6  
323             }
324              
325             sub get_rich_menu_id_of_user {
326 1     1 1 3580 my ($self, $user_id, $rich_menu_id) = @_;
327 1         6 my $res = $self->request(get => "user/${user_id}/richmenu");
328 1         2 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         7  
329             }
330              
331             sub unlink_rich_menu_from_user {
332 1     1 1 3460 my ($self, $user_id) = @_;
333 1         6 my $res = $self->request(delete => "user/${user_id}/richmenu");
334 1         3 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         7  
335             }
336              
337             sub unlink_rich_menu_from_multiple_users {
338 1     1 1 3493 my ($self, $user_ids) = @_;
339 1         5 my $res = $self->request(post => "richmenu/bulk/unlink", +{
340             userIds => $user_ids,
341             });
342 1         3 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         8  
343             }
344              
345             sub upload_rich_menu_image {
346 1     1 0 2048 my ($self, $rich_menu_id, $content_type, $file_path) = @_;
347              
348 1 50       13 if (!$content_type) {
349 0         0 croak 'Need content_type';
350             }
351              
352             my $res = $self->{client}->post_image(
353 1         16 $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         2 return LINE::Bot::API::Response::Token->new(%{ $res });
  1         17  
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 1695 my ($self, $rich_menu_id) = @_;
370              
371             return $self->{client}->get_content(
372 1         28 $self->{content_api_endpoint} . "richmenu/$rich_menu_id/content"
373             );
374             }
375              
376             sub issue_channel_access_token {
377 1     1 1 1673 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         8 ]
386             );
387              
388 1 50       7 if ($res->{http_status} eq '200') {
389 1         2 return LINE::Bot::API::Response::Token->new(%{ $res });
  1         19  
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 3272 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         9 ]
406             );
407              
408 1 50       7 if ($res->{http_status} eq '200') {
409 1         2 return LINE::Bot::API::Response::Token->new(%{ $res });
  1         6  
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 3952 my ($self, $opts) = @_;
417              
418 1         7 my $jwt = uri_escape($opts->{jwt});
419 1         45 my $assertion_type = uri_escape('urn:ietf:params:oauth:client-assertion-type:jwt-bearer');
420              
421             my $res = $self->{client}->get(
422 1         42 $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         5  
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 7590 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         15 ]
440             );
441              
442 2 100       11 if ($res->{http_status} eq '200') {
443 1         2 return LINE::Bot::API::Response::Common->new(%{ $res });
  1         36  
444             } else {
445 1         2 return LINE::Bot::API::Response::Error->new(%{ $res });
  1         14  
446             }
447             }
448              
449             sub get_number_of_followers {
450 1     1 1 33 my ($self, $opts) = @_;
451 1 50       6 my $date = $opts->{date} or croak "get_number_of_followers: Missing a `date` parameter.";
452              
453 1         5 my $res = $self->request(get => "insight/followers?date=${date}");
454 1         3 LINE::Bot::API::Response::NumberOfFollowers->new(%{ $res });
  1         17  
455             }
456              
457             sub get_user_interaction_statistics {
458 1     1 1 39 my ($self, $opts) = @_;
459 1 50       4 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         3 LINE::Bot::API::Response::UserInteractionStatistics->new(%{ $res });
  1         16  
463             }
464              
465             1;
466             __END__