[2a42248] | 1 | package Facebook::Graph; |
---|
| 2 | BEGIN { |
---|
| 3 | $Facebook::Graph::VERSION = '1.0300'; |
---|
| 4 | } |
---|
| 5 | |
---|
| 6 | use Any::Moose; |
---|
| 7 | use MIME::Base64::URLSafe; |
---|
| 8 | use JSON; |
---|
[5ef98c7] | 9 | with 'Facebook::Graph::Role::Uri'; |
---|
[2a42248] | 10 | use Facebook::Graph::AccessToken; |
---|
| 11 | use Facebook::Graph::Authorize; |
---|
| 12 | use Facebook::Graph::Query; |
---|
| 13 | use Facebook::Graph::Picture; |
---|
| 14 | use Facebook::Graph::Publish::Post; |
---|
| 15 | use Facebook::Graph::Publish::Checkin; |
---|
| 16 | use Facebook::Graph::Publish::Like; |
---|
| 17 | use Facebook::Graph::Publish::Comment; |
---|
| 18 | use Facebook::Graph::Publish::Note; |
---|
| 19 | use Facebook::Graph::Publish::Link; |
---|
| 20 | use Facebook::Graph::Publish::Event; |
---|
| 21 | use Facebook::Graph::Publish::RSVPMaybe; |
---|
| 22 | use Facebook::Graph::Publish::RSVPAttending; |
---|
| 23 | use Facebook::Graph::Publish::RSVPDeclined; |
---|
[5ef98c7] | 24 | use URI::Encode qw(uri_decode); |
---|
| 25 | use AnyEvent::HTTP; |
---|
[2a42248] | 26 | use Ouch; |
---|
| 27 | |
---|
| 28 | has app_id => ( |
---|
| 29 | is => 'ro', |
---|
| 30 | ); |
---|
| 31 | |
---|
| 32 | has secret => ( |
---|
| 33 | is => 'ro', |
---|
| 34 | predicate => 'has_secret', |
---|
| 35 | ); |
---|
| 36 | |
---|
| 37 | has postback => ( |
---|
| 38 | is => 'ro', |
---|
| 39 | ); |
---|
| 40 | |
---|
| 41 | has access_token => ( |
---|
| 42 | is => 'rw', |
---|
| 43 | predicate => 'has_access_token', |
---|
| 44 | ); |
---|
| 45 | |
---|
| 46 | |
---|
| 47 | sub parse_signed_request { |
---|
| 48 | my ($self, $signed_request) = @_; |
---|
| 49 | require Digest::SHA; |
---|
| 50 | my ($encoded_sig, $payload) = split(/\./, $signed_request); |
---|
| 51 | |
---|
| 52 | my $sig = urlsafe_b64decode($encoded_sig); |
---|
| 53 | my $data = JSON->new->decode(urlsafe_b64decode($payload)); |
---|
| 54 | |
---|
| 55 | if (uc($data->{'algorithm'}) ne "HMAC-SHA256") { |
---|
| 56 | ouch '500', 'Unknown algorithm. Expected HMAC-SHA256'; |
---|
| 57 | } |
---|
| 58 | |
---|
| 59 | my $expected_sig = Digest::SHA::hmac_sha256($payload, $self->secret); |
---|
| 60 | if ($sig ne $expected_sig) { |
---|
| 61 | ouch '500', 'Bad Signed JSON signature!'; |
---|
| 62 | } |
---|
| 63 | return $data; |
---|
| 64 | } |
---|
| 65 | |
---|
| 66 | sub request_access_token { |
---|
[7777ac2] | 67 | my ($self, $code, $cb) = @_; |
---|
| 68 | Facebook::Graph::AccessToken->new( |
---|
[2a42248] | 69 | code => $code, |
---|
| 70 | postback => $self->postback, |
---|
| 71 | secret => $self->secret, |
---|
| 72 | app_id => $self->app_id, |
---|
[7777ac2] | 73 | )->request(sub { |
---|
| 74 | my ($response) = @_; |
---|
| 75 | $self->access_token($response->token); |
---|
| 76 | $cb->($response); |
---|
| 77 | }); |
---|
[2a42248] | 78 | } |
---|
| 79 | |
---|
| 80 | sub convert_sessions { |
---|
[7777ac2] | 81 | my ($self, $sessions, $cb) = @_; |
---|
| 82 | Facebook::Graph::Session->new( |
---|
[2a42248] | 83 | secret => $self->secret, |
---|
| 84 | app_id => $self->app_id, |
---|
| 85 | sessions => $sessions, |
---|
[7777ac2] | 86 | )->request($cb); # API change |
---|
[2a42248] | 87 | } |
---|
| 88 | |
---|
| 89 | sub authorize { |
---|
| 90 | my ($self) = @_; |
---|
| 91 | return Facebook::Graph::Authorize->new( |
---|
| 92 | app_id => $self->app_id, |
---|
| 93 | postback => $self->postback, |
---|
| 94 | ); |
---|
| 95 | } |
---|
| 96 | |
---|
[7777ac2] | 97 | # XXX error handling |
---|
| 98 | #sub fetch { |
---|
| 99 | # my ($self, $object_name, $cb) = @_; |
---|
| 100 | # $self->query->find($object_name)->request(sub { |
---|
| 101 | # my ($result) = @_; |
---|
| 102 | # $cb->($result->as_hashref); |
---|
| 103 | # }); |
---|
| 104 | #} |
---|
[2a42248] | 105 | |
---|
| 106 | sub query { |
---|
| 107 | my ($self) = @_; |
---|
| 108 | my %params; |
---|
| 109 | if ($self->has_access_token) { |
---|
| 110 | $params{access_token} = $self->access_token; |
---|
| 111 | } |
---|
| 112 | if ($self->has_secret) { |
---|
| 113 | $params{secret} = $self->secret; |
---|
| 114 | } |
---|
| 115 | return Facebook::Graph::Query->new(%params); |
---|
| 116 | } |
---|
| 117 | |
---|
[5ef98c7] | 118 | sub delete { |
---|
| 119 | my ($self, $id, $cb) = @_; |
---|
| 120 | my %query; |
---|
| 121 | if ($self->has_access_token) { |
---|
| 122 | $query{access_token} = uri_decode($self->access_token); |
---|
| 123 | } |
---|
| 124 | my $uri = $self->uri; |
---|
| 125 | $uri->path($id); |
---|
| 126 | $uri->query_form(%query); |
---|
| 127 | http_request(DELETE => $uri->as_string, sub { |
---|
| 128 | my ($response, $headers) = @_; |
---|
| 129 | my %params = ( |
---|
| 130 | response => $response, |
---|
| 131 | headers => $headers, |
---|
| 132 | uri => $uri |
---|
| 133 | ); |
---|
| 134 | if ($self->has_secret) { |
---|
| 135 | $params{secret} = $self->secret; |
---|
| 136 | } |
---|
| 137 | $cb->(Facebook::Graph::Response->new(%params)); |
---|
| 138 | }); |
---|
| 139 | () # return nothing |
---|
| 140 | } |
---|
| 141 | |
---|
[2a42248] | 142 | sub picture { |
---|
| 143 | my ($self, $object_name) = @_; |
---|
| 144 | return Facebook::Graph::Picture->new( object_name => $object_name ); |
---|
| 145 | } |
---|
| 146 | |
---|
| 147 | sub add_post { |
---|
| 148 | my ($self, $object_name) = @_; |
---|
| 149 | my %params; |
---|
| 150 | if ($object_name) { |
---|
| 151 | $params{object_name} = $object_name; |
---|
| 152 | } |
---|
| 153 | if ($self->has_access_token) { |
---|
| 154 | $params{access_token} = $self->access_token; |
---|
| 155 | } |
---|
| 156 | if ($self->has_secret) { |
---|
| 157 | $params{secret} = $self->secret; |
---|
| 158 | } |
---|
| 159 | return Facebook::Graph::Publish::Post->new( %params ); |
---|
| 160 | } |
---|
| 161 | |
---|
| 162 | sub add_checkin { |
---|
| 163 | my ($self, $object_name) = @_; |
---|
| 164 | my %params; |
---|
| 165 | if ($object_name) { |
---|
| 166 | $params{object_name} = $object_name; |
---|
| 167 | } |
---|
| 168 | if ($self->has_access_token) { |
---|
| 169 | $params{access_token} = $self->access_token; |
---|
| 170 | } |
---|
| 171 | if ($self->has_secret) { |
---|
| 172 | $params{secret} = $self->secret; |
---|
| 173 | } |
---|
| 174 | return Facebook::Graph::Publish::Checkin->new( %params ); |
---|
| 175 | } |
---|
| 176 | |
---|
| 177 | sub add_like { |
---|
| 178 | my ($self, $object_name) = @_; |
---|
| 179 | my %params = ( |
---|
| 180 | object_name => $object_name, |
---|
| 181 | ); |
---|
| 182 | if ($self->has_access_token) { |
---|
| 183 | $params{access_token} = $self->access_token; |
---|
| 184 | } |
---|
| 185 | if ($self->has_secret) { |
---|
| 186 | $params{secret} = $self->secret; |
---|
| 187 | } |
---|
| 188 | return Facebook::Graph::Publish::Like->new( %params ); |
---|
| 189 | } |
---|
| 190 | |
---|
| 191 | sub add_comment { |
---|
| 192 | my ($self, $object_name) = @_; |
---|
| 193 | my %params = ( |
---|
| 194 | object_name => $object_name, |
---|
| 195 | ); |
---|
| 196 | if ($self->has_access_token) { |
---|
| 197 | $params{access_token} = $self->access_token; |
---|
| 198 | } |
---|
| 199 | if ($self->has_secret) { |
---|
| 200 | $params{secret} = $self->secret; |
---|
| 201 | } |
---|
| 202 | return Facebook::Graph::Publish::Comment->new( %params ); |
---|
| 203 | } |
---|
| 204 | |
---|
| 205 | sub add_note { |
---|
| 206 | my ($self) = @_; |
---|
| 207 | my %params; |
---|
| 208 | if ($self->has_access_token) { |
---|
| 209 | $params{access_token} = $self->access_token; |
---|
| 210 | } |
---|
| 211 | if ($self->has_secret) { |
---|
| 212 | $params{secret} = $self->secret; |
---|
| 213 | } |
---|
| 214 | return Facebook::Graph::Publish::Note->new( %params ); |
---|
| 215 | } |
---|
| 216 | |
---|
| 217 | sub add_link { |
---|
| 218 | my ($self) = @_; |
---|
| 219 | my %params; |
---|
| 220 | if ($self->has_access_token) { |
---|
| 221 | $params{access_token} = $self->access_token; |
---|
| 222 | } |
---|
| 223 | if ($self->has_secret) { |
---|
| 224 | $params{secret} = $self->secret; |
---|
| 225 | } |
---|
| 226 | return Facebook::Graph::Publish::Link->new( %params ); |
---|
| 227 | } |
---|
| 228 | |
---|
| 229 | sub add_event { |
---|
| 230 | my ($self, $object_name) = @_; |
---|
| 231 | my %params; |
---|
| 232 | if ($object_name) { |
---|
| 233 | $params{object_name} = $object_name; |
---|
| 234 | } |
---|
| 235 | if ($self->has_access_token) { |
---|
| 236 | $params{access_token} = $self->access_token; |
---|
| 237 | } |
---|
| 238 | if ($self->has_secret) { |
---|
| 239 | $params{secret} = $self->secret; |
---|
| 240 | } |
---|
| 241 | return Facebook::Graph::Publish::Event->new( %params ); |
---|
| 242 | } |
---|
| 243 | |
---|
| 244 | sub rsvp_maybe { |
---|
| 245 | my ($self, $object_name) = @_; |
---|
| 246 | my %params = ( |
---|
| 247 | object_name => $object_name, |
---|
| 248 | ); |
---|
| 249 | if ($self->has_access_token) { |
---|
| 250 | $params{access_token} = $self->access_token; |
---|
| 251 | } |
---|
| 252 | if ($self->has_secret) { |
---|
| 253 | $params{secret} = $self->secret; |
---|
| 254 | } |
---|
| 255 | return Facebook::Graph::Publish::RSVPMaybe->new( %params ); |
---|
| 256 | } |
---|
| 257 | |
---|
| 258 | sub rsvp_attending { |
---|
| 259 | my ($self, $object_name) = @_; |
---|
| 260 | my %params = ( |
---|
| 261 | object_name => $object_name, |
---|
| 262 | ); |
---|
| 263 | if ($self->has_access_token) { |
---|
| 264 | $params{access_token} = $self->access_token; |
---|
| 265 | } |
---|
| 266 | if ($self->has_secret) { |
---|
| 267 | $params{secret} = $self->secret; |
---|
| 268 | } |
---|
| 269 | return Facebook::Graph::Publish::RSVPAttending->new( %params ); |
---|
| 270 | } |
---|
| 271 | |
---|
| 272 | sub rsvp_declined { |
---|
| 273 | my ($self, $object_name) = @_; |
---|
| 274 | my %params = ( |
---|
| 275 | object_name => $object_name, |
---|
| 276 | ); |
---|
| 277 | if ($self->has_access_token) { |
---|
| 278 | $params{access_token} = $self->access_token; |
---|
| 279 | } |
---|
| 280 | if ($self->has_secret) { |
---|
| 281 | $params{secret} = $self->secret; |
---|
| 282 | } |
---|
| 283 | return Facebook::Graph::Publish::RSVPDeclined->new( %params ); |
---|
| 284 | } |
---|
| 285 | |
---|
| 286 | |
---|
| 287 | |
---|
| 288 | no Any::Moose; |
---|
| 289 | __PACKAGE__->meta->make_immutable; |
---|
| 290 | |
---|
| 291 | =head1 NAME |
---|
| 292 | |
---|
| 293 | Facebook::Graph - A fast and easy way to integrate your apps with Facebook. |
---|
| 294 | |
---|
| 295 | =head1 VERSION |
---|
| 296 | |
---|
| 297 | version 1.0300 |
---|
| 298 | |
---|
| 299 | =head1 SYNOPSIS |
---|
| 300 | |
---|
| 301 | my $fb = Facebook::Graph->new; |
---|
| 302 | my $sarah_bownds = $fb->fetch('sarahbownds'); |
---|
| 303 | my $perl_page = $fb->fetch('16665510298'); |
---|
| 304 | |
---|
| 305 | Or better yet: |
---|
| 306 | |
---|
| 307 | my $sarah_bownds = $fb->query |
---|
| 308 | ->find('sarahbownds') |
---|
| 309 | ->include_metadata |
---|
| 310 | ->select_fields(qw( id name picture )) |
---|
| 311 | ->request |
---|
| 312 | ->as_hashref; |
---|
| 313 | |
---|
| 314 | my $sarahs_picture_uri = $fb->picture('sarahbownds')->get_large->uri_as_string; |
---|
| 315 | |
---|
| 316 | Or fetching a response from a URI you already have: |
---|
| 317 | |
---|
| 318 | my $response = $fb->query |
---|
| 319 | ->request('https://graph.facebook.com/btaylor') |
---|
| 320 | ->as_hashref; |
---|
| 321 | |
---|
| 322 | |
---|
| 323 | =head2 Building A Privileged App |
---|
| 324 | |
---|
| 325 | my $fb = Facebook::Graph->new( |
---|
| 326 | app_id => $facebook_application_id, |
---|
| 327 | secret => $facebook_application_secret, |
---|
| 328 | postback => 'https://www.yourapplication.com/facebook/oauth/postback', |
---|
| 329 | ); |
---|
| 330 | |
---|
| 331 | Get the user to authorize your app (only needed if you want to fetch non-public information or publish stuff): |
---|
| 332 | |
---|
| 333 | my $uri = $fb |
---|
| 334 | ->authorize |
---|
| 335 | ->extend_permissions(qw(offline_access publish_stream)) |
---|
| 336 | ->uri_as_string; |
---|
| 337 | |
---|
| 338 | # redirect the user's browser to $uri |
---|
| 339 | |
---|
| 340 | Handle the Facebook authorization code postback: |
---|
| 341 | |
---|
| 342 | my $q = Plack::Request->new($env); |
---|
| 343 | $fb->request_access_token($q->query_param('code')); |
---|
| 344 | |
---|
| 345 | Or if you already had the access token: |
---|
| 346 | |
---|
| 347 | $fb->access_token($token); |
---|
| 348 | |
---|
| 349 | Get some info: |
---|
| 350 | |
---|
| 351 | my $user = $fb->fetch('me'); |
---|
| 352 | my $friends = $fb->fetch('me/friends'); |
---|
| 353 | my $sarah_bownds = $fb->fetch('sarahbownds'); |
---|
| 354 | |
---|
| 355 | =head1 DESCRIPTION |
---|
| 356 | |
---|
| 357 | This is a Perl interface to the Facebook Graph API L<http://developers.facebook.com/docs/api>. With this module you can currently query public Facebook data, query privileged Facebook data, and build a privileged Facebook application. See the TODO for all that this module cannot yet do. |
---|
| 358 | |
---|
| 359 | For example code, see L<Facebook::Graph::Cookbook>. |
---|
| 360 | |
---|
| 361 | B<WARNING:> The work on this module has only just begun because the Graph API itself isn't very new, and I'm only working on it as I have some tuits. Therefore things are potentially subject to change drastically with each release. |
---|
| 362 | |
---|
| 363 | |
---|
| 364 | =head1 METHODS |
---|
| 365 | |
---|
| 366 | =head2 new ( [ params ] ) |
---|
| 367 | |
---|
| 368 | The constructor. |
---|
| 369 | |
---|
| 370 | =head3 params |
---|
| 371 | |
---|
| 372 | A hash of base parameters, just so you don't have to pass them around. If you only want to do public queries then these params are not needed. |
---|
| 373 | |
---|
| 374 | =over |
---|
| 375 | |
---|
| 376 | =item access_token |
---|
| 377 | |
---|
| 378 | An access token string used to make Facebook requests as a privileged user. Required if you want to make privileged queries or perform privileged actions on Facebook objects. |
---|
| 379 | |
---|
| 380 | =item app_id |
---|
| 381 | |
---|
| 382 | The application id that you get from Facebook after registering (L<http://developers.facebook.com/setup/>) your application on their site. Required if you'll be calling the C<request_access_token>, C<convert_sessions>, or C<authorize> methods. |
---|
| 383 | |
---|
| 384 | =item secret |
---|
| 385 | |
---|
| 386 | The application secret that you get from Facebook after registering your application. Required if you'll be calling the C<request_access_token> or C<convert_sessions> methods. |
---|
| 387 | |
---|
| 388 | =item postback |
---|
| 389 | |
---|
| 390 | The URI that Facebook should post your authorization code back to. Required if you'll be calling the C<request_access_token> or C<authorize> methods. |
---|
| 391 | |
---|
| 392 | B<NOTE:> It must be a sub URI of the URI that you put in the Application Settings > Connect > Connect URL field of your application's profile on Facebook. |
---|
| 393 | |
---|
| 394 | =back |
---|
| 395 | |
---|
| 396 | |
---|
| 397 | =head2 authorize ( ) |
---|
| 398 | |
---|
| 399 | Creates a L<Facebook::Graph::Authorize> object, which can be used to get permissions from a user for your application. |
---|
| 400 | |
---|
| 401 | |
---|
| 402 | =head2 request_access_token ( code ) |
---|
| 403 | |
---|
| 404 | Creates a L<Facebook::Graph::AccessToken> object and fetches an access token from Facebook, which will allow everything you do with Facebook::Graph to work within user privileges rather than through the public interface. Returns a L<Facebook::Graph::AccessToken::Response> object, and also sets the C<access_token> property in the Facebook::Graph object. |
---|
| 405 | |
---|
| 406 | =head3 code |
---|
| 407 | |
---|
| 408 | An authorization code string that you should have gotten by going through the C<authorize> process. |
---|
| 409 | |
---|
| 410 | |
---|
| 411 | =head2 query ( ) |
---|
| 412 | |
---|
| 413 | Creates a L<Facebook::Graph::Query> object, which can be used to fetch and search data from Facebook. |
---|
| 414 | |
---|
| 415 | |
---|
| 416 | =head2 fetch ( id ) |
---|
| 417 | |
---|
| 418 | Returns a hash reference of an object from facebook. A quick way to grab an object from Facebook. These two statements are identical: |
---|
| 419 | |
---|
| 420 | my $sarah = $fb->fetch('sarahbownds'); |
---|
| 421 | |
---|
| 422 | my $sarah = $fb->query->find('sarahbownds')->request->as_hashref; |
---|
| 423 | |
---|
| 424 | =head3 id |
---|
| 425 | |
---|
| 426 | An profile id like C<sarahbownds> or an object id like C<16665510298> for the Perl page. |
---|
| 427 | |
---|
| 428 | |
---|
| 429 | =head2 picture ( id ) |
---|
| 430 | |
---|
| 431 | Returns a L<Facebook::Graph::Picture> object, which can be used to generate the URLs of the pictures of any object on Facebook. |
---|
| 432 | |
---|
| 433 | =head3 id |
---|
| 434 | |
---|
| 435 | An profile id like C<sarahbownds> or an object id like C<16665510298> for the Perl page. |
---|
| 436 | |
---|
| 437 | |
---|
| 438 | |
---|
| 439 | =head2 add_post ( [ id ] ) |
---|
| 440 | |
---|
| 441 | Creates a L<Facebook::Graph::Publish::Post> object, which can be used to publish data to a user's feed/wall. |
---|
| 442 | |
---|
| 443 | =head3 id |
---|
| 444 | |
---|
| 445 | Optionally provide an object id to place it on. Requires that you have administrative access to that page/object. |
---|
| 446 | |
---|
| 447 | |
---|
| 448 | =head2 add_checkin ( [ id ] ) |
---|
| 449 | |
---|
| 450 | Creates a L<Facebook::Graph::Publish::Checkin> object, which can be used to publish a checkin to a location. |
---|
| 451 | |
---|
| 452 | =head3 id |
---|
| 453 | |
---|
| 454 | Optionally provide an user id to check in. Requires that you have administrative access to that user. |
---|
| 455 | |
---|
| 456 | |
---|
| 457 | =head2 add_like ( id ) |
---|
| 458 | |
---|
| 459 | Creates a L<Facebook::Graph::Publish::Like> object to tell everyone about a post you like. |
---|
| 460 | |
---|
| 461 | =head3 id |
---|
| 462 | |
---|
| 463 | The id of a post you like. |
---|
| 464 | |
---|
| 465 | |
---|
| 466 | =head2 add_comment ( id ) |
---|
| 467 | |
---|
| 468 | Creates a L<Facebook::Graph::Publish::Comment> object that you can use to comment on a note. |
---|
| 469 | |
---|
| 470 | =head3 id |
---|
| 471 | |
---|
| 472 | The id of the post you want to comment on. |
---|
| 473 | |
---|
| 474 | |
---|
| 475 | =head2 add_note ( ) |
---|
| 476 | |
---|
| 477 | Creates a L<Facebook::Graph::Publish::Note> object, which can be used to publish notes. |
---|
| 478 | |
---|
| 479 | |
---|
| 480 | =head2 add_link ( ) |
---|
| 481 | |
---|
| 482 | Creates a L<Facebook::Graph::Publish::Link> object, which can be used to publish links. |
---|
| 483 | |
---|
| 484 | |
---|
| 485 | =head2 add_event ( [id] ) |
---|
| 486 | |
---|
| 487 | Creates a L<Facebook::Graph::Publish::Event> object, which can be used to publish events. |
---|
| 488 | |
---|
| 489 | =head3 id |
---|
| 490 | |
---|
| 491 | Optionally provide an object id to place it on. Requires that you have administrative access to that page/object. |
---|
| 492 | |
---|
| 493 | |
---|
| 494 | |
---|
| 495 | =head2 rsvp_maybe ( id ) |
---|
| 496 | |
---|
| 497 | RSVP as 'maybe' to an event. |
---|
| 498 | |
---|
| 499 | =head3 id |
---|
| 500 | |
---|
| 501 | The id of an event. |
---|
| 502 | |
---|
| 503 | =head2 rsvp_attending ( id ) |
---|
| 504 | |
---|
| 505 | RSVP as 'attending' to an event. |
---|
| 506 | |
---|
| 507 | =head3 id |
---|
| 508 | |
---|
| 509 | The id of an event. |
---|
| 510 | |
---|
| 511 | =head2 rsvp_declined ( id ) |
---|
| 512 | |
---|
| 513 | RSVP as 'declined' to an event. |
---|
| 514 | |
---|
| 515 | =head3 id |
---|
| 516 | |
---|
| 517 | The id of an event. |
---|
| 518 | |
---|
| 519 | |
---|
| 520 | |
---|
| 521 | =head2 convert_sessions ( sessions ) |
---|
| 522 | |
---|
| 523 | A utility method to convert old sessions into access tokens that can be used with the Graph API. Returns an array reference of hash references of access tokens. |
---|
| 524 | |
---|
| 525 | [ |
---|
| 526 | { |
---|
| 527 | "access_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx", |
---|
| 528 | "expires": 1271649600, |
---|
| 529 | }, |
---|
| 530 | ... |
---|
| 531 | ] |
---|
| 532 | |
---|
| 533 | See also L<Facebook::Graph::Session>. |
---|
| 534 | |
---|
| 535 | =head3 sessions |
---|
| 536 | |
---|
| 537 | An array reference of session ids from the old Facebook API. |
---|
| 538 | |
---|
| 539 | |
---|
| 540 | =head2 parse_signed_request ( signed_request ) |
---|
| 541 | |
---|
| 542 | Allows the decoding of signed requests for canvas applications to ensure data passed back from Facebook isn't tampered with. You can read more about this at L<http://developers.facebook.com/docs/authentication/canvas>. |
---|
| 543 | |
---|
| 544 | =head3 signed_request |
---|
| 545 | |
---|
| 546 | A signature string passed from Facebook. To capture a signed request your app must be displayed within the Facebook canvas page and then you must pull the query parameter called C<signed_request> from the query string. |
---|
| 547 | |
---|
| 548 | B<NOTE:> To get this passed to your app you must enable it in your migration settings for your app (L<http://www.facebook.com/developers/>). |
---|
| 549 | |
---|
| 550 | =head1 EXCEPTIONS |
---|
| 551 | |
---|
| 552 | This module throws exceptions when it encounters a problem. It uses L<Ouch> to throw the exception, and the Exception typically takes 3 parts: code, message, and a data portion that is the URI that was originally requested. For example: |
---|
| 553 | |
---|
| 554 | eval { $fb->call_some_method }; |
---|
| 555 | if (kiss 500) { |
---|
| 556 | say "error: ". $@->message; |
---|
| 557 | say "uri: ".$@->data; |
---|
| 558 | } |
---|
| 559 | else { |
---|
| 560 | throw $@; # rethrow the error |
---|
| 561 | } |
---|
| 562 | |
---|
| 563 | |
---|
| 564 | =head1 TODO |
---|
| 565 | |
---|
| 566 | I still need to add publishing albums/photos, deleting of content, impersonation, and analytics to have a feature complete API. In addition, the module could use a lot more tests. |
---|
| 567 | |
---|
| 568 | |
---|
| 569 | =head1 PREREQS |
---|
| 570 | |
---|
| 571 | L<Any::Moose> |
---|
| 572 | L<JSON> |
---|
[7777ac2] | 573 | L<AnyEvent::HTTP> |
---|
[2a42248] | 574 | L<Mozilla::CA> |
---|
| 575 | L<URI> |
---|
| 576 | L<DateTime> |
---|
| 577 | L<DateTime::Format::Strptime> |
---|
| 578 | L<MIME::Base64::URLSafe> |
---|
| 579 | L<URI::Encode> |
---|
| 580 | L<Ouch> |
---|
| 581 | |
---|
| 582 | =head2 Optional |
---|
| 583 | |
---|
| 584 | L<Digest::SHA> is used for signed requests. If you don't plan on using the signed request feature, then you do not need to install Digest::SHA. |
---|
| 585 | |
---|
| 586 | =head1 SUPPORT |
---|
| 587 | |
---|
| 588 | =over |
---|
| 589 | |
---|
| 590 | =item Repository |
---|
| 591 | |
---|
| 592 | L<http://github.com/rizen/Facebook-Graph> |
---|
| 593 | |
---|
| 594 | =item Bug Reports |
---|
| 595 | |
---|
| 596 | L<http://github.com/rizen/Facebook-Graph/issues> |
---|
| 597 | |
---|
| 598 | =back |
---|
| 599 | |
---|
| 600 | |
---|
| 601 | =head1 SEE ALSO |
---|
| 602 | |
---|
| 603 | If you're looking for a fully featured Facebook client in Perl I highly recommend L<WWW::Facebook::API>. It does just about everything, it just uses the old Facebook API. |
---|
| 604 | |
---|
| 605 | =head1 AUTHOR |
---|
| 606 | |
---|
| 607 | JT Smith <jt_at_plainblack_dot_com> |
---|
| 608 | |
---|
| 609 | =head1 LEGAL |
---|
| 610 | |
---|
| 611 | Facebook::Graph is Copyright 2010 Plain Black Corporation (L<http://www.plainblack.com>) and is licensed under the same terms as Perl itself. |
---|
| 612 | |
---|
| 613 | =cut |
---|