File Coverage

blib/lib/LINE/Bot/API.pm
Criterion Covered Total %
statement 335 361 92.8
branch 22 34 64.7
condition 7 14 50.0
subroutine 87 91 95.6
pod 52 58 89.6
total 503 558 90.1


line stmt bran cond sub pod time code
1             package LINE::Bot::API;
2 52     52   7202967 use strict;
  52         151  
  52         2032  
3 52     52   273 use warnings;
  52         135  
  52         3772  
4             our $VERSION = '1.21';
5              
6 52     52   27917 use LINE::Bot::API::Builder::SendMessage;
  52         200  
  52         1988  
7 52     52   19421 use LINE::Bot::API::Client;
  52         160  
  52         1794  
8 52     52   29142 use LINE::Bot::API::Event;
  52         204  
  52         2289  
9 52     52   19332 use LINE::Bot::API::Response::Common;
  52         143  
  52         1495  
10 52     52   25202 use LINE::Bot::API::Response::Content;
  52         177  
  52         1844  
11 52     52   25112 use LINE::Bot::API::Response::Count;
  52         1409  
  52         2486  
12 52     52   25359 use LINE::Bot::API::Response::FriendDemographics;
  52         179  
  52         1858  
13 52     52   26788 use LINE::Bot::API::Response::NumberOfSentMessages;
  52         163  
  52         1779  
14 52     52   25187 use LINE::Bot::API::Response::NumberOfMessageDeliveries;
  52         170  
  52         1956  
15 52     52   25506 use LINE::Bot::API::Response::Profile;
  52         167  
  52         1940  
16 52     52   24607 use LINE::Bot::API::Response::GroupMemberProfile;
  52         162  
  52         1752  
17 52     52   24236 use LINE::Bot::API::Response::GroupSummary;
  52         194  
  52         1917  
18 52     52   24916 use LINE::Bot::API::Response::RoomMemberProfile;
  52         165  
  52         1989  
19 52     52   24280 use LINE::Bot::API::Response::IssueLinkToken;
  52         217  
  52         1840  
20 52     52   24282 use LINE::Bot::API::Response::RichMenu;
  52         177  
  52         1950  
21 52     52   23894 use LINE::Bot::API::Response::RichMenuList;
  52         167  
  52         1734  
22 52     52   24232 use LINE::Bot::API::Response::TargetLimit;
  52         184  
  52         1690  
23 52     52   26312 use LINE::Bot::API::Response::TotalUsage;
  52         158  
  52         1700  
24 52     52   24078 use LINE::Bot::API::Response::Token;
  52         183  
  52         1890  
25 52     52   25576 use LINE::Bot::API::Response::NumberOfFollowers;
  52         196  
  52         1788  
26 52     52   23883 use LINE::Bot::API::Response::UserInteractionStatistics;
  52         276  
  52         1913  
27 52     52   24173 use LINE::Bot::API::Response::BotInfo;
  52         201  
  52         4234  
28 52     52   25580 use LINE::Bot::API::Response::WebhookInformation;
  52         168  
  52         1951  
29 52     52   26538 use LINE::Bot::API::Response::WebhookTest;
  52         199  
  52         1777  
30 52     52   23490 use LINE::Bot::API::Response::Followers;
  52         168  
  52         2577  
31              
32             use constant {
33 52         5983 DEFAULT_MESSAGING_API_ENDPOINT => 'https://api.line.me/v2/bot/',
34             DEFAULT_SOCIAL_API_ENDPOINT => 'https://api.line.me/v2/oauth/',
35             DEFAULT_CONTENT_API_ENDPOINT => 'https://api-data.line.me/v2/bot/',
36             DEFAULT_OAUTH2_API_ENDPOINT => 'https://api.line.me/oauth2/v2.1/',
37 52     52   356 };
  52         123  
38 52     52   20081 use Furl;
  52         214951  
  52         2233  
39 52     52   341 use Carp 'croak';
  52         86  
  52         3340  
40 52     52   27679 use URI;
  52         258490  
  52         1886  
41 52     52   433 use URI::Escape;
  52         95  
  52         3791  
42 52     52   20158 use URI::QueryParam;
  52         6420  
  52         232791  
43              
44             sub new {
45 40     40 1 8997386 my($class, %args) = @_;
46              
47 40         499 my $client = LINE::Bot::API::Client->new(%args);
48              
49             bless {
50             client => $client,
51             channel_secret => $args{channel_secret},
52             channel_access_token => $args{channel_access_token},
53             messaging_api_endpoint => $args{messaging_api_endpoint} // DEFAULT_MESSAGING_API_ENDPOINT,
54             social_api_endpoint => $args{social_api_endpoint} // DEFAULT_SOCIAL_API_ENDPOINT,
55             content_api_endpoint => $args{content_api_endpoint} // DEFAULT_CONTENT_API_ENDPOINT,
56 40   50     3943 oauth_api_endpoint => $args{oauth_api_endpoint} // DEFAULT_OAUTH2_API_ENDPOINT,
      50        
      50        
      50        
57             }, $class;
58             }
59              
60             sub request {
61 82     82 0 344 my ($self, $method, $path, @payload) = @_;
62              
63             return $self->{client}->$method(
64 82         953 $self->{messaging_api_endpoint} . $path,
65             @payload,
66             );
67             }
68              
69             sub request_content {
70 0     0 0 0 my ($self, $method, $path, @payload) = @_;
71              
72             return $self->{client}->$method(
73 0         0 $self->{content_api_endpoint} . $path,
74             @payload,
75             );
76             }
77              
78             sub reply_message {
79 11     11 1 41 my($self, $reply_token, $messages) = @_;
80              
81 11         75 my $res = $self->request(
82             post => 'message/reply',
83             +{
84             replyToken => $reply_token,
85             messages => $messages,
86             }
87             );
88              
89 11         45 LINE::Bot::API::Response::Common->new(%{ $res });
  11         86  
90             }
91              
92             sub push_message {
93 25     25 1 98 my($self, $to_id, $messages, $options) = @_;
94              
95 25         65 my @headers = ();
96 25 100 66     163 if ($options && defined($options->{'retry_key'})) {
97 1         7 push @headers, 'X-Line-Retry-Key' => $options->{'retry_key'};
98             }
99              
100 25         173 my $res = $self->request(
101             post => 'message/push',
102             \@headers,
103             +{
104             to => $to_id,
105             messages => $messages,
106             }
107             );
108 25         95 LINE::Bot::API::Response::Common->new(%{ $res });
  25         278  
109             }
110              
111             sub multicast {
112 1     1 1 3 my($self, $to_ids, $messages, $options) = @_;
113              
114 1         3 my @headers = ();
115 1 50 33     20 if ($options && defined($options->{'retry_key'})) {
116 0         0 push @headers, 'X-Line-Retry-Key' => $options->{'retry_key'};
117             }
118              
119 1         9 my $res = $self->request(
120             post => 'message/multicast',
121             \@headers,
122             +{
123             to => $to_ids,
124             messages => $messages,
125             }
126             );
127 1         4 LINE::Bot::API::Response::Common->new(%{ $res });
  1         13  
128             }
129              
130             sub broadcast {
131 2     2 1 7 my($self, $messages, $options) = @_;
132              
133 2         4 my @headers = ();
134 2 100       8 if (defined($options->{'retry_key'})) {
135 1         3 push @headers, 'X-Line-Retry-Key' => $options->{'retry_key'};
136             }
137              
138 2         10 my $res = $self->request(
139             post => 'message/broadcast',
140             \@headers,
141             +{
142             messages => $messages,
143             }
144             );
145 2         6 LINE::Bot::API::Response::Common->new(%{ $res });
  2         22  
146             }
147              
148             sub get_message_content {
149 0     0 1 0 my($self, $message_id, %options) = @_;
150 0         0 my $res = $self->request_content(
151             'contents_download' => "message/$message_id/content",
152             %options
153             );
154 0         0 LINE::Bot::API::Response::Content->new(%{ $res });
  0         0  
155             }
156              
157             sub get_profile {
158 1     1 1 40 my($self, $user_id) = @_;
159 1         6 my $res = $self->request(get => "profile/$user_id");
160 1         3 LINE::Bot::API::Response::Profile->new(%{ $res });
  1         19  
161             }
162              
163             sub get_group_member_profile {
164 1     1 1 38 my($self, $group_id, $user_id) = @_;
165 1         6 my $res = $self->request(get => "group/$group_id/member/$user_id");
166 1         3 LINE::Bot::API::Response::GroupMemberProfile->new(%{ $res });
  1         21  
167             }
168              
169             sub get_room_member_profile {
170 1     1 1 36 my($self, $room_id, $user_id) = @_;
171 1         6 my $res = $self->request(get => "room/$room_id/member/$user_id");
172 1         2 LINE::Bot::API::Response::RoomMemberProfile->new(%{ $res });
  1         20  
173             }
174              
175             sub leave_room {
176 0     0 1 0 my($self, $room_id) = @_;
177 0         0 my $res = $self->request(post => "room/$room_id/leave", +{});
178 0         0 LINE::Bot::API::Response::Common->new(%{ $res });
  0         0  
179             }
180              
181             sub leave_group {
182 0     0 1 0 my($self, $group_id) = @_;
183 0         0 my $res = $self->request(post => "group/$group_id/leave", +{});
184 0         0 LINE::Bot::API::Response::Common->new(%{ $res });
  0         0  
185             }
186              
187             sub get_friend_demographics {
188 1     1 1 31 my($self) = @_;
189 1         5 my $res = $self->request(get => "insight/demographic");
190 1         2 LINE::Bot::API::Response::FriendDemographics->new(%{ $res });
  1         16  
191             }
192              
193             sub get_target_limit_for_additional_messages {
194 1     1 1 36 my($self, $date) = @_;
195 1         8 my $res = $self->request(get => "message/quota");
196 1         3 LINE::Bot::API::Response::TargetLimit->new(%{ $res });
  1         16  
197             }
198              
199             sub get_number_of_messages_sent_this_month {
200 1     1 1 38 my($self, $date) = @_;
201 1         7 my $res = $self->request(get => "message/quota/consumption");
202 1         2 LINE::Bot::API::Response::TotalUsage->new(%{ $res });
  1         22  
203             }
204              
205             sub get_number_of_sent_reply_messages {
206 1     1 1 59 my($self, $date) = @_;
207 1         7 my $res = $self->request(get => "message/delivery/reply?date=${date}");
208 1         3 LINE::Bot::API::Response::NumberOfSentMessages->new(%{ $res });
  1         22  
209             }
210              
211             sub get_number_of_sent_push_messages {
212 1     1 1 1011 my($self, $date) = @_;
213 1         9 my $res = $self->request(get => "message/delivery/push?date=${date}", +{});
214 1         3 LINE::Bot::API::Response::NumberOfSentMessages->new(%{ $res });
  1         8  
215             }
216              
217             sub get_number_of_sent_multicast_messages {
218 1     1 1 1012 my($self, $date) = @_;
219 1         8 my $res = $self->request(get => "message/delivery/multicast?date=${date}", +{});
220 1         4 LINE::Bot::API::Response::NumberOfSentMessages->new(%{ $res });
  1         10  
221             }
222              
223             sub get_number_of_send_broadcast_messages {
224 1     1 1 989 my($self, $date) = @_;
225 1         9 my $res = $self->request(get => "message/delivery/broadcast?date=${date}", +{});
226 1         3 LINE::Bot::API::Response::NumberOfSentMessages->new(%{ $res });
  1         10  
227             }
228              
229             sub get_number_of_message_deliveries {
230 1     1 1 28 my($self, $opts) = @_;
231 1 50       4 my $date = $opts->{date} or croak "get_number_of_message_deliveries: Missing a `date` parameter.";
232              
233 1         4 my $res = $self->request(get => "insight/message/delivery?date=${date}", +{});
234 1         2 LINE::Bot::API::Response::NumberOfMessageDeliveries->new(%{ $res });
  1         14  
235             }
236              
237             sub get_member_in_room_count {
238 1     1 1 2356 my ($self, $room_id) = @_;
239              
240 1         8 my $res = $self->request(get => "room/${room_id}/members/count", +{});
241 1         3 LINE::Bot::API::Response::Count->new(%{ $res });
  1         18  
242             }
243              
244             sub get_member_in_group_count {
245 1     1 1 1958 my ($self, $group_id) = @_;
246              
247 1         7 my $res = $self->request(get => "group/${group_id}/members/count", +{});
248 1         3 LINE::Bot::API::Response::Count->new(%{ $res });
  1         19  
249             }
250              
251             sub get_group_summary {
252 1     1 1 2011 my ($self, $group_id) = @_;
253              
254 1         8 my $res = $self->request(get => "group/${group_id}/summary", +{});
255 1         4 LINE::Bot::API::Response::GroupSummary->new(%{ $res });
  1         23  
256             }
257              
258             sub validate_signature {
259 2     2 1 4608 my($self, $json, $signature) = @_;
260 2         14 LINE::Bot::API::Event->validate_signature($json, $self->{channel_secret}, $signature);
261             }
262              
263             sub parse_events_from_json {
264 1     1 1 3655 my($self, $json) = @_;
265 1         5 LINE::Bot::API::Event->parse_events_json($json);
266             }
267              
268             sub issue_link_token {
269 1     1 0 29 my($self, $user_id) = @_;
270 1         5 my $res = $self->request(post => "user/${user_id}/linkToken", +{});
271 1         2 LINE::Bot::API::Response::IssueLinkToken->new(%{ $res });
  1         15  
272             }
273              
274             sub create_rich_menu {
275 1     1 1 1792 my ($self, $rich_menu) = @_;
276 1         6 my $res = $self->request(post => "richmenu", $rich_menu);
277 1         2 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         23  
278             }
279              
280             sub get_rich_menu {
281 1     1 1 3796 my ($self, $rich_menu_id) = @_;
282 1         7 my $res = $self->request(get => "richmenu/${rich_menu_id}");
283 1         3 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         12  
284             }
285              
286             sub delete_rich_menu {
287 1     1 1 5055 my ($self, $rich_menu_id) = @_;
288 1         9 my $res = $self->request(delete => "richmenu/${rich_menu_id}");
289 1         4 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         13  
290             }
291              
292             sub get_rich_menu_list {
293 1     1 1 5399 my ($self) = @_;
294 1         8 my $res = $self->request(get => "richmenu/list");
295 1         4 LINE::Bot::API::Response::RichMenuList->new(%{ $res });
  1         56  
296             }
297              
298             sub set_default_rich_menu {
299 1     1 1 5566 my ($self, $rich_menu_id) = @_;
300 1         10 my $res = $self->request(post => "user/all/richmenu/${rich_menu_id}", +{});
301 1         4 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         15  
302             }
303              
304             sub get_default_rich_menu_id {
305 1     1 1 5518 my ($self) = @_;
306 1         8 my $res = $self->request(get => "user/all/richmenu");
307 1         3 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         13  
308             }
309              
310             sub cancel_default_rich_menu {
311 1     1 1 5544 my ($self) = @_;
312 1         9 my $res = $self->request(delete => "user/all/richmenu");
313 1         4 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         11  
314             }
315              
316             sub link_rich_menu_to_user {
317 1     1 1 5373 my ($self, $user_id, $rich_menu_id) = @_;
318 1         10 my $res = $self->request(post => "user/${user_id}/richmenu/${rich_menu_id}", +{});
319 1         6 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         11  
320             }
321              
322             sub link_rich_menu_to_multiple_users {
323 1     1 1 5484 my ($self, $user_ids, $rich_menu_id) = @_;
324 1         12 my $res = $self->request(post => "richmenu/bulk/link", +{
325             richMenuId => $rich_menu_id,
326             userIds => $user_ids,
327             });
328 1         5 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         12  
329             }
330              
331             sub get_rich_menu_id_of_user {
332 1     1 1 5616 my ($self, $user_id, $rich_menu_id) = @_;
333 1         10 my $res = $self->request(get => "user/${user_id}/richmenu");
334 1         4 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         12  
335             }
336              
337             sub unlink_rich_menu_from_user {
338 1     1 1 9961 my ($self, $user_id) = @_;
339 1         11 my $res = $self->request(delete => "user/${user_id}/richmenu");
340 1         4 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         12  
341             }
342              
343             sub unlink_rich_menu_from_multiple_users {
344 1     1 1 5563 my ($self, $user_ids) = @_;
345 1         9 my $res = $self->request(post => "richmenu/bulk/unlink", +{
346             userIds => $user_ids,
347             });
348 1         5 LINE::Bot::API::Response::RichMenu->new(%{ $res });
  1         11  
349             }
350              
351             sub upload_rich_menu_image {
352 1     1 0 2042 my ($self, $rich_menu_id, $content_type, $file_path) = @_;
353              
354 1 50       6 if (!$content_type) {
355 0         0 croak 'Need content_type';
356             }
357              
358             my $res = $self->{client}->post_image(
359 1         15 $self->{content_api_endpoint} . "richmenu/$rich_menu_id/content",
360             [
361             'Content-Type' => $content_type,
362             ],
363             $file_path
364             );
365              
366 1 50       7 if ($res->{http_status} eq '200') {
367 1         2 return LINE::Bot::API::Response::Token->new(%{ $res });
  1         20  
368             } else {
369 0         0 return LINE::Bot::API::Response::Error->new(%{ $res });
  0         0  
370             }
371              
372             }
373              
374             sub download_rich_menu_image {
375 1     1 0 1721 my ($self, $rich_menu_id) = @_;
376              
377             return $self->{client}->get_content(
378 1         10 $self->{content_api_endpoint} . "richmenu/$rich_menu_id/content"
379             );
380             }
381              
382             sub validate_rich_menu_object {
383 1     1 1 5735 my ($self, $rich_menu) = @_;
384 1         7 my $res = $self->request(post => "richmenu/validate", $rich_menu);
385 1         3 LINE::Bot::API::Response::Common->new(%{ $res });
  1         11  
386             }
387              
388             sub issue_channel_access_token {
389 1     1 1 1444 my ($self, $opts) = @_;
390              
391             my $res = $self->{client}->post_form(
392             $self->{social_api_endpoint} . 'accessToken',
393             [
394             grant_type => 'client_credentials',
395             client_id => $opts->{client_id},
396             client_secret => $opts->{client_secret},
397 1         8 ]
398             );
399              
400 1 50       5 if ($res->{http_status} eq '200') {
401 1         1 return LINE::Bot::API::Response::Token->new(%{ $res });
  1         19  
402             } else {
403 0         0 return LINE::Bot::API::Response::Error->new(%{ $res });
  0         0  
404             }
405             }
406              
407             sub issue_channel_access_token_v2_1 {
408 1     1 1 3093 my ($self, $opts) = @_;
409              
410             my $res = $self->{client}->post_form(
411             $self->{oauth_api_endpoint} . 'token',
412             undef,
413             [
414             grant_type => 'client_credentials',
415             client_assertion_type => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
416             client_assertion => $opts->{jwt},
417 1         12 ]
418             );
419              
420 1 50       6 if ($res->{http_status} eq '200') {
421 1         2 return LINE::Bot::API::Response::Token->new(%{ $res });
  1         8  
422             } else {
423 0         0 return LINE::Bot::API::Response::Error->new(%{ $res });
  0         0  
424             }
425             }
426              
427             sub get_valid_channel_access_token_v2_1 {
428 1     1 1 3423 my ($self, $opts) = @_;
429              
430 1         9 my $jwt = uri_escape($opts->{jwt});
431 1         63 my $assertion_type = uri_escape('urn:ietf:params:oauth:client-assertion-type:jwt-bearer');
432              
433             my $res = $self->{client}->get(
434 1         37 $self->{oauth_api_endpoint} . 'tokens/kid' . "?client_assertion_type=$assertion_type&client_assertion=$jwt",
435             );
436              
437 1 50       6 if ($res->{http_status} eq '200') {
438 1         2 return LINE::Bot::API::Response::Token->new(%{ $res });
  1         8  
439             } else {
440 0         0 return LINE::Bot::API::Response::Error->new(%{ $res });
  0         0  
441             }
442             }
443              
444             sub revoke_channel_access_token {
445 2     2 1 6949 my ($self, $opts) = @_;
446              
447             my $res = $self->{client}->post_form(
448             $self->{social_api_endpoint} . 'revoke',
449             [
450             access_token => $opts->{access_token},
451 2         18 ]
452             );
453              
454 2 100       11 if ($res->{http_status} eq '200') {
455 1         2 return LINE::Bot::API::Response::Common->new(%{ $res });
  1         8  
456             } else {
457 1         3 return LINE::Bot::API::Response::Error->new(%{ $res });
  1         24  
458             }
459             }
460              
461             sub get_number_of_followers {
462 1     1 1 40 my ($self, $opts) = @_;
463 1 50       5 my $date = $opts->{date} or croak "get_number_of_followers: Missing a `date` parameter.";
464              
465 1         7 my $res = $self->request(get => "insight/followers?date=${date}");
466 1         2 LINE::Bot::API::Response::NumberOfFollowers->new(%{ $res });
  1         19  
467             }
468              
469             sub get_user_interaction_statistics {
470 1     1 1 46 my ($self, $opts) = @_;
471 1 50       5 my $requestId = $opts->{requestId} or croak "get_user_interaction_statistics: Missing a `requestId` parameter.";
472              
473 1         7 my $res = $self->request(get => "insight/message/event?requestId=${requestId}");
474 1         2 LINE::Bot::API::Response::UserInteractionStatistics->new(%{ $res });
  1         22  
475             }
476              
477             sub get_bot_info {
478 1     1 0 47 my ($self) = @_;
479 1         6 my $res = $self->request(get => "info");
480 1         3 LINE::Bot::API::Response::BotInfo->new(%{ $res });
  1         21  
481             }
482              
483             sub set_webhook_url {
484 1     1 1 31 my ($self, $opts) = @_;
485 1 50       4 defined($opts->{endpoint}) or croak "set_webhook_url: Missing a mandatory parameter: `endpoint`";
486              
487             my $res = $self->request(
488             'put' => "channel/webhook/endpoint",
489             [],
490             +{ endpoint => $opts->{endpoint} },
491 1         5 );
492              
493 1 50       5 if ($res->{http_status} eq '200') {
494 1         2 return LINE::Bot::API::Response::Common->new(%{ $res });
  1         9  
495             } else {
496 0         0 return LINE::Bot::API::Response::Error->new(%{ $res });
  0         0  
497             }
498             }
499              
500             sub get_webhook_endpoint_information {
501 1     1 1 27 my ($self) = @_;
502 1         3 my $res = $self->request(get => "channel/webhook/endpoint");
503 1         2 LINE::Bot::API::Response::WebhookInformation->new(%{ $res });
  1         13  
504             }
505              
506             sub test_webhook_endpoint {
507 1     1 1 33 my ($self, $opts) = @_;
508              
509 1         2 my $req_body = {};
510 1 50       4 if ($opts->{'endpoint'}) {
511 1         2 $req_body->{'endpoint'} = $opts->{'endpoint'};
512             }
513              
514 1         4 my $res = $self->request(
515             'post' => "channel/webhook/endpoint",
516             [],
517             $req_body,
518             );
519              
520 1         2 LINE::Bot::API::Response::WebhookTest->new(%{ $res });
  1         14  
521             }
522              
523             sub validate_reply_message_objects {
524 1     1 1 2 my($self, $messages) = @_;
525              
526 1         105 my $res = $self->request(
527             post => 'message/validate/reply',
528             +{
529             messages => $messages,
530             }
531             );
532              
533 1         3 LINE::Bot::API::Response::Common->new(%{ $res });
  1         12  
534             }
535              
536             sub validate_push_message_objects {
537 1     1 1 3 my($self, $messages) = @_;
538              
539 1         8 my $res = $self->request(
540             post => 'message/validate/push',
541             +{
542             messages => $messages,
543             }
544             );
545              
546 1         3 LINE::Bot::API::Response::Common->new(%{ $res });
  1         8  
547             }
548              
549             sub validate_multicast_message_objects {
550 1     1 1 3 my($self, $messages) = @_;
551              
552 1         6 my $res = $self->request(
553             post => 'message/validate/multicast',
554             +{
555             messages => $messages,
556             }
557             );
558              
559 1         3 LINE::Bot::API::Response::Common->new(%{ $res });
  1         10  
560             }
561              
562             sub validate_narrowcast_message_objects {
563 1     1 1 4 my($self, $messages) = @_;
564              
565 1         7 my $res = $self->request(
566             post => 'message/validate/narrowcast',
567             +{
568             messages => $messages,
569             }
570             );
571              
572 1         2 LINE::Bot::API::Response::Common->new(%{ $res });
  1         8  
573             }
574              
575             sub validate_broadcast_message_objects {
576 1     1 1 4 my($self, $messages) = @_;
577              
578 1         6 my $res = $self->request(
579             post => 'message/validate/broadcast',
580             +{
581             messages => $messages,
582             }
583             );
584              
585 1         2 LINE::Bot::API::Response::Common->new(%{ $res });
  1         7  
586             }
587              
588             sub get_followers {
589 4     4 1 17081 my ($self, $opts) = @_;
590 4         42 my $uri = URI->new('followers/ids');
591              
592 4 100       5923 exists $opts->{'limit'} and $uri->query_param(limit => $opts->{'limit'});
593 4 100       422 exists $opts->{'start'} and $uri->query_param(start => $opts->{'start'});
594              
595 4         374 my $res = $self->request(get => $uri->as_string);
596              
597 4         10 LINE::Bot::API::Response::Followers->new(%{ $res });
  4         43  
598             }
599              
600             1;
601              
602             __END__