File Coverage

blib/lib/OpenTok/API.pm
Criterion Covered Total %
statement 22 24 91.6
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 30 32 93.7


line stmt bran cond sub pod time code
1             package OpenTok::API;
2              
3 1     1   26961 use 5.006;
  1         3  
  1         42  
4 1     1   6 use strict;
  1         1  
  1         33  
5 1     1   6 use warnings;
  1         5  
  1         34  
6              
7 1     1   1926 use Time::HiRes;
  1         2392  
  1         5  
8 1     1   1071 use MIME::Base64;
  1         1549  
  1         83  
9 1     1   803 use Digest::HMAC_SHA1 qw(hmac_sha1_hex);
  1         44383  
  1         57  
10              
11 1     1   17829 use LWP;
  1         162183  
  1         39  
12 1     1   579 use XML::XPath;
  0            
  0            
13              
14             use OpenTok::API::Session;
15             use OpenTok::API::Exceptions;
16              
17             =head1 NAME
18              
19             OpenTok::API - Perl SDK for OpenTok
20             http://www.tokbox.com/
21              
22             =head1 VERSION
23              
24             Version 0.03
25              
26             =cut
27              
28             our $VERSION = '0.03';
29             our $API_VERSION = 'tbpl-v0.03.2013-07-10';
30             our %API_SERVER = (
31             "development" => "https://staging.tokbox.com/hl",
32             "production" => "https://api.opentok.com/hl"
33             );
34             our %RoleConstants = (
35             "SUBSCRIBER" => "subscriber",
36             "PUBLISHER" => "publisher",
37             "MODERATOR" => "moderator",
38             );
39              
40             =head1 SYNOPSIS
41              
42             1. Generate Token
43              
44             use OpenTok::API;
45            
46             # Get your own API-keys from http://www.tokbox.com/opentok
47             my $ot = OpenTok::API->new(
48             'api_key' => $api_key,
49             'api_secret' => $api_secret,
50             'mode' => "development"|"production",
51             );
52            
53             2. Create new session
54              
55             my $session_id = $ot->create_session(
56             location => '',
57             'p2p.preference' => "enabled"|"disabled"
58             )->getSessionId();
59            
60             3. Generate a new token for session
61            
62             my $token = $ot->generate_token(
63             session_id => $session_id,
64             role => "publisher"|"subscriber"|"moderator"
65             );
66              
67             4. Now insert your $api_key, $session_id, and $token into your template using your favourite templating engine
68              
69             # TT example
70              
71             # In server side code
72             my $tt = Template->new(...});
73             my $vars = { api_key => $api_key, session_id => $session_id, token => $token };
74             $tt->process($template, $vars) || die $tt->error(), "\n";
75              
76             # In HTML (javascript part)
77             var apiKey = "[% api_key %]";
78             var sessionId = "[% session_id %]";
79             var token = "[% token %]";
80             ...
81             var session = TB.initSession(sessionId);
82             session.addEventListener("sessionConnected", sessionConnectedHandler);
83             session.addEventListener("streamCreated", streamCreatedHandler);
84             session.connect(apiKey,token);
85              
86              
87             =head1 SUBROUTINES/METHODS
88              
89             =head2 new
90              
91             Creates and returns a new OpenTok::API object
92              
93             my $ot = OpenTok::API->new(
94             'api_key' => $api_key,
95             'api_secret' => $api_secret,
96             'mode' => "development"|"production",
97             );
98              
99             =over 4
100              
101             =item * C<< api_key => string >>
102              
103             Sets your TokBox API Partner Key
104              
105             =item * C<< api_secret => string >>
106              
107             Sets your TokBox API Partner Secret
108              
109             =item * C<< mode => "development|"production" >>
110              
111             Set it to "production" when you launch your app in production. Default is "development".
112              
113             =back
114              
115             =cut
116              
117             sub new {
118             my ($class, %args) = @_;
119             my $self = {
120             api_key => exists $args{api_key} ? $args{api_key} : '_api_key_',
121             api_secret => exists $args{api_secret} ? $args{api_secret} : '_api_secret_',
122             api_mode => exists $args{mode} ? $args{mode} : 'development',
123             };
124            
125             bless $self, $class;
126            
127             return $self;
128             }
129              
130             =head2 generate_token
131              
132             Generates a token for specific session.
133              
134             my $token = $ot->generate_token(
135             session_id => $session_id,
136             role => "publisher"|"subscriber"|"moderator",
137             expire_time => (time()+24*3600),
138             );
139              
140             =over 4
141              
142             =item * C<< session_id => string >>
143              
144             If session_id is not blank, this token can only join the call with the specified session_id.
145              
146             =item * C<< role => "subscriber"|"publisher"|"moderator" >>
147              
148             One of the roles. Default is publisher, look in the documentation to learn more about roles.
149             http://www.tokbox.com/opentok/api/tools/as3/documentation/overview/token_creation.html
150              
151             =item * C<< expire_time => int >>
152              
153             Optional. The time when the token will expire, defined as an integer value for a Unix timestamp (in seconds).
154             If you do not specify this value, tokens expire in 24 hours after being created.
155             The expiration_time value, if specified, must be within 30 days of the creation time.
156              
157             =back
158              
159             =cut
160              
161             sub generate_token {
162             my $self = shift;
163             my $create_time = time();
164             my %arg = (
165             session_id => '',
166             role => $RoleConstants{PUBLISHER},
167             expire_time => ($create_time +24*3600),
168             @_,
169             );
170             my $nonce = rand();
171             my $query_string = "role=" . $arg{role} .
172             "&session_id=" . $arg{session_id} .
173             "&create_time=" . $create_time .
174             "&nonce=" . $nonce .
175             "&expire_time=" . $arg{expire_time} .
176             "&connection_data=";
177             my $signature = hmac_sha1_hex($query_string, $self->{api_secret});
178             return "T1==" . encode_base64("partner_id=".$self->{api_key}."&sdk_version=$API_VERSION&sig=$signature:$query_string",'');
179            
180             }
181              
182             =head2 create_session
183              
184             Creates and returns OpenTok::API::Session object
185              
186             my $session_id = $ot->create_session(
187             location => '',
188             'p2p.preference' => "enabled"|"disabled"
189             )->getSessionId();
190              
191             =over 4
192              
193             =item * C<< location => string >>
194              
195             An IP address that TokBox will use to situate the session in its global network.
196             In general, you should not specify a location hint; if no location hint is specified,
197             the session uses a media server based on the location of the first client connecting to the session.
198             Specify a location hint only if you know the general geographic region (and a representative IP address)
199             for the session and you think the first client connecting may not be in that region.
200              
201             =item * C<< 'p2p.preference' => 'enabled' >>
202              
203             The properties option includes any following key value pairs. Currently only the following property exists:
204              
205             p2p.preference (String) . Whether the session's streams will be transmitted directly between peers. You can set the following possible values:
206              
207             "disabled" (the default) . The session's streams will all be relayed using the OpenTok servers. More than two clients can connect to the session.
208              
209             "enabled" . The session will attempt to transmit streams directly between clients. If peer-to-peer streaming fails (either when streams are
210             initially published or during the course of a session), the session falls back to using the OpenTok servers for relaying streams.
211             (Peer-to-peer streaming uses UDP, which may be blocked by a firewall.) For a session created with peer-to-peer streaming enabled,
212             only two clients can connect to the session at a time. If an additional client attempts to connect,
213             the TB object on the client dispatches an exception event.
214             By removing the server, peer-to-peer streaming decreases latency and improves quality.
215              
216             Note that the properties object previously included settings for multiplexing and server-side echo suppression.
217             However, these features were deleted in OpenTok v0.91.48. (Server-side echo suppression was replaced with the
218             acoustic echo cancellation feature added in OpenTok v0.91.18.)
219              
220             =back
221              
222             =cut
223              
224             sub create_session {
225             my $self = shift;
226             my %arg = (
227             location => '',
228             api_key => $self->{api_key},
229             @_,
230             );
231             my $session_raw = $self->_do_request("/session/create", %arg);
232             my $session_xml;
233            
234             eval {
235             $session_xml = XML::XPath->new( xml => $session_raw ) or OpenTok::API::Exception->throw( error => "Failed to create session: Invalid response from server: $!" );
236             };
237            
238             return if (Exception::Class->caught('OpenTok::API::Exception'));
239            
240             if($session_xml->exists('/Errors')) {
241             my $err_msg = $session_xml->find('//@message');
242             $err_msg = 'Unknown error' unless $err_msg;
243            
244             OpenTok::API::Exception::Auth->throw(error => "Error " . $session_xml->find('//@code') ." ". $session_xml->find('local-name(//error/*[1])') . ": " . $err_msg );
245            
246             return;
247             }
248            
249             return OpenTok::API::Session->new( map { $_->getName => $_->string_value } $session_xml->find('//Session/*')->get_nodelist);
250            
251             }
252              
253             # private methods
254              
255             sub _do_request {
256             my $self = shift;
257             my $cmd = shift;
258             my %arg = (
259             @_,
260             );
261            
262             my $url = $API_SERVER{$self->{api_mode}}.$cmd;
263            
264             my $data = join '&', map { "$_=".$self->_urlencode($arg{$_}) } keys %arg;
265            
266             my $ua = LWP::UserAgent->new;
267             #$ua->agent("$0/0.1 " . $ua->agent);
268            
269             my $request = HTTP::Request->new(POST => $url);
270             $request->header('X-TB-PARTNER-AUTH' => $self->{api_key}.':'.$self->{api_secret});
271             $request->content_type('application/x-www-form-urlencoded');
272             $request->content($data);
273            
274             my $result = $ua->request($request);
275              
276             if ($result->is_success) {
277             return $result->content;
278             }
279             else {
280             OpenTok::API::Exception::Auth->throw( error => "Request error: ".$result->status_line );
281             return;
282             }
283              
284             }
285              
286             sub _urlencode {
287             my ($self, $data) = @_;
288              
289             $data =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg;
290             return $data;
291             }
292              
293             =head1 AUTHOR
294              
295             This version: Dr James Freeman, C<< >>
296             Original version: Maxim Nikolenko, C<< >>
297              
298             =head1 BUGS
299              
300             Please report any bugs or feature requests to C, or through
301             the web interface at L. I will be notified, and then you'll
302             automatically be notified of progress on your bug as I make changes.
303              
304             =head1 SUPPORT
305              
306             You can find documentation for this module with the perldoc command.
307              
308             perldoc OpenTok::API
309              
310             You can also look for information at:
311              
312             http://www.tokbox.com/opentok
313              
314             =over 4
315              
316             =item * RT: CPAN's request tracker (report bugs here)
317              
318             L
319              
320             =item * AnnoCPAN: Annotated CPAN documentation
321              
322             L
323              
324             =item * CPAN Ratings
325              
326             L
327              
328             =item * Search CPAN
329              
330             L
331              
332             =back
333              
334              
335             =head1 LICENSE AND COPYRIGHT
336              
337             Copyright 2011 Maxim Nikolenko.
338              
339             This module is released under the following license: BSD
340              
341              
342             =cut
343              
344             1; # End of OpenTok