| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
use warnings; |
|
3
|
1
|
|
|
1
|
|
90921
|
use strict; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
34
|
|
|
4
|
1
|
|
|
1
|
|
4
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
17
|
|
|
5
|
|
|
|
|
|
|
use WebService::Simple; |
|
6
|
1
|
|
|
1
|
|
426
|
use base 'WebService::Simple'; |
|
|
1
|
|
|
|
|
65689
|
|
|
|
1
|
|
|
|
|
9
|
|
|
7
|
1
|
|
|
1
|
|
35
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
113
|
|
|
8
|
|
|
|
|
|
|
use JSON (); |
|
9
|
1
|
|
|
1
|
|
1703
|
|
|
|
1
|
|
|
|
|
11393
|
|
|
|
1
|
|
|
|
|
281
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = '0.11'; |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
# overide our base modules WebService::Simple _agent() method with our own: |
|
13
|
|
|
|
|
|
|
|
|
14
|
1
|
|
|
1
|
|
12162
|
# similarly for the WebService::Simple built-in config(), which we overwrite like this: |
|
15
|
|
|
|
|
|
|
__PACKAGE__->config( |
|
16
|
|
|
|
|
|
|
base_url => 'https://api.twitch.tv/helix/', # needs a trailing slash |
|
17
|
|
|
|
|
|
|
response_parser => 'JSON', |
|
18
|
|
|
|
|
|
|
); |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# we wrap the underlying base's new() method to attach credentials (which are normally discarded) |
|
21
|
|
|
|
|
|
|
my $class = shift; |
|
22
|
|
|
|
|
|
|
my %args = @_; |
|
23
|
|
|
|
|
|
|
|
|
24
|
1
|
|
|
1
|
1
|
107
|
die "Net::Twitch::API: new: no access_token provided!" unless $args{access_token}; |
|
25
|
1
|
|
|
|
|
5
|
die "Net::Twitch::API: new: no client_id provided!" unless $args{client_id}; |
|
26
|
|
|
|
|
|
|
|
|
27
|
1
|
50
|
|
|
|
3
|
$args{croak} = 0; # WebService::Simple by default croaks() - which we do not want |
|
28
|
1
|
50
|
|
|
|
4
|
|
|
29
|
|
|
|
|
|
|
my $self = $class->SUPER::new(%args); |
|
30
|
1
|
|
|
|
|
2
|
|
|
31
|
|
|
|
|
|
|
$self->{access_token} = $args{access_token}; |
|
32
|
1
|
|
|
|
|
11
|
$self->{client_id} = $args{client_id}; |
|
33
|
|
|
|
|
|
|
|
|
34
|
1
|
|
|
|
|
28
|
return $self; |
|
35
|
1
|
|
|
|
|
2
|
} |
|
36
|
|
|
|
|
|
|
|
|
37
|
1
|
|
|
|
|
4
|
my $self = shift; |
|
38
|
|
|
|
|
|
|
my $params = shift || {}; |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
my $response = $self->get('/users', $params, |
|
41
|
0
|
|
|
0
|
1
|
|
'Authorization' => 'Bearer '. $self->{access_token}, |
|
42
|
0
|
|
0
|
|
|
|
'Client-Id' => $self->{client_id}, |
|
43
|
|
|
|
|
|
|
); |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
return $self->_responseParser($response,'getUsers'); |
|
46
|
|
|
|
|
|
|
} |
|
47
|
0
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
my $self = shift; |
|
49
|
0
|
|
|
|
|
|
my $response = shift; |
|
50
|
|
|
|
|
|
|
my $methodName = shift || '<empty methodName>'; |
|
51
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
## WebService::Simple doesn't wrap error responses, so handle this case here |
|
53
|
0
|
|
|
0
|
|
|
unless($response->is_success){ |
|
54
|
0
|
|
|
|
|
|
unless($response->content_length() ){ |
|
55
|
0
|
|
0
|
|
|
|
return { error => $methodName ." request failed!", status => $response->code, message => $response->message, response => $response }; |
|
56
|
|
|
|
|
|
|
} |
|
57
|
|
|
|
|
|
|
|
|
58
|
0
|
0
|
|
|
|
|
$response = WebService::Simple::Response->new_from_response( |
|
59
|
0
|
0
|
|
|
|
|
response => $response, |
|
60
|
0
|
|
|
|
|
|
parser => $self->response_parser |
|
61
|
|
|
|
|
|
|
); |
|
62
|
|
|
|
|
|
|
} |
|
63
|
0
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
my $result = {}; |
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
$result = $response->parse_response() if $response->content_length(); |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
return $result; |
|
69
|
0
|
|
|
|
|
|
} |
|
70
|
|
|
|
|
|
|
|
|
71
|
0
|
0
|
|
|
|
|
=pod |
|
72
|
|
|
|
|
|
|
|
|
73
|
0
|
|
|
|
|
|
=head1 NAME |
|
74
|
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
Net::Twitch::API - Helper methods for Twitch's "new" helix API |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
use Net::Twitch::API; |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
my $api = Net::Twitch::API->new( |
|
82
|
|
|
|
|
|
|
access_token => 'your-token', |
|
83
|
|
|
|
|
|
|
client_id => 'your-id', |
|
84
|
|
|
|
|
|
|
debug => 1, |
|
85
|
|
|
|
|
|
|
); |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
my $response = $api->getUsers({ login => 'twitchdev' }); |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
This module provides methods and helper wrappers to work with what Twitch "new" helix API. The I<new> API is |
|
92
|
|
|
|
|
|
|
prefixed with the I<helix> codename/namespace and the successor of the old I<kraken> API which was decommissioned |
|
93
|
|
|
|
|
|
|
on February 28, 2022. A little more about that on dev.twitch.tv L<"legacy v5 integrations" migration guide|https://dev.twitch.tv/docs/api/migration>. |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
Using this module to issue requests against Twitch's API requires you to register your "application" with Twitch |
|
96
|
|
|
|
|
|
|
first. Authentication then is either faciliated via L<OAuth 2.0|https://dev.twitch.tv/docs/authentication/getting-tokens-oauth> |
|
97
|
|
|
|
|
|
|
or L<OpenID Connect|https://dev.twitch.tv/docs/authentication/getting-tokens-oidc>. We here use the OAuth2 scheme. |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
Twitch uses several types of auth tokens. Use the twitch CLI client to obtain an "app access token". This type of |
|
100
|
|
|
|
|
|
|
token enables your app to make secure API requests that are not on behalf of a specific user. App access tokens are |
|
101
|
|
|
|
|
|
|
meant only for server-to-server API requests and should never be included in client code. Normally, such tokens |
|
102
|
|
|
|
|
|
|
would be programmatically refreshed at arbitrary intervals according to OAuth2 RFC but on Twitch app access tokens |
|
103
|
|
|
|
|
|
|
are valid for 60 days and cannot be refreshed. |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
This module uses Yosukebe's excellent L<WebService::Simple> as base calss. So look there for addditonal documentation. |
|
106
|
|
|
|
|
|
|
You might also note that Yosukebe himself recently switched over to the newer L<WebService::Client>, but that's a |
|
107
|
|
|
|
|
|
|
Moo based module. |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
=head2 new() |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
Calls underlying WebService::Simple's new(), with additional checks and defaults for Twitch. |
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
You must provide your I<access_token> and I<client_id>. |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
If I<debug> is set, the request URL will be dumped via warn() on get or post method calls. |
|
118
|
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
WebService::Simple by default croaks (dies) on a failed request. This module returns on error and success with a |
|
120
|
|
|
|
|
|
|
reference to a hash containing received data. The hash key I<error> is defined on unsuccessful requests. |
|
121
|
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
If you supply a Cache object to new(), each request is prepended by a cache look-up. Refer to L<WebService::Simple> |
|
123
|
|
|
|
|
|
|
for an example. |
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=head2 getUsers() |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
Expects a hashref. Users can be looked up either via their I<login> name (username / nickname) or via their numeric |
|
128
|
|
|
|
|
|
|
user I<id>. Twitch allows to ask for multiple names in one request. Current limit is 100. Use an arrayref of values |
|
129
|
|
|
|
|
|
|
instead of a scalar then. |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
Returns a hashref with hash-key I<data> holding a reference to an array of users. |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=head1 EXPORT |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
Nothing by default. |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=head1 CAVEATS |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
Note that Net::Twitch::API is a WIP module. Things are incomplete or may change without notice. |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
142
|
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
Official Twitch documents: |
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=over |
|
146
|
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=item * |
|
148
|
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
L<Getting Started|https://dev.twitch.tv/docs/api> walks you through basic setup of your app and helps with |
|
150
|
|
|
|
|
|
|
a first request. |
|
151
|
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=item * |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
L<Reference|https://dev.twitch.tv/docs/api/guide> gives an overview of core principles like pagination and rate |
|
155
|
|
|
|
|
|
|
limits. |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
=item * |
|
158
|
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
L<Reference|https://dev.twitch.tv/docs/api/reference> si the canonical Twitch API endpoints reference. A little |
|
160
|
|
|
|
|
|
|
more an be found in the L<api docs|https://github.com/twitchdev/twitch-cli/blob/main/docs/api.md> for the twitch-cli command-line client. |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=back |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
Within the Perl universe, Twitch related code can be found in outdated modules L<App::Twitch> and L<Net::Twitch::Oauth2> |
|
165
|
|
|
|
|
|
|
and Corion's non-API helper module L<WWW::Twitch|https://github.com/Corion/WWW-Twitch>. |
|
166
|
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=head1 AUTHOR |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
Clipland GmbH L<https://www.clipland.com/> |
|
170
|
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
This module was developed for L<"Sendung verpasst?"|https://mediatheksuche.de/> I<video> search engine L<MediathekSuche.de|https://mediatheksuche.de/>. |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
Copyright 2022 Clipland GmbH. All rights reserved. |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
This library is free software, dual-licensed under L<GPLv3|http://www.gnu.org/licenses/gpl>/L<AL2|http://opensource.org/licenses/Artistic-2.0>. |
|
178
|
|
|
|
|
|
|
You can redistribute it and/or modify it under the same terms as Perl itself. |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=cut |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
1; |