TwiterとOAuthとperlでの実装

UmakatterにOAuthを利用した機能を組み込みました。
TwitterのOAuthなのですが、Net::Twitter を利用すると本当に簡単に実現できます。こんなコードです。

OAuthアカウント作成

http://twitter.com/oauth_clients にて、アカウントを作成してください。

Net::Twitter::OAuthじゃなくてNet::Twitter::Role::OAuthの方の PODを読むと吉

Net::Twitter::Role::OAuth に書いてある通りにやると、とても簡単に実装できます。(Typoがいくつかあるので注意)

OAuth認証へのリダイレクトしょり

こんな感じで、リダイレクトする前に、token, token_secretをユーザのクッキーに保存しておきます。

    my $nt = Net::Twitter->new( %{$config->twitter_oauth} );
    my $url = $nt->get_authorization_url(callback => $config->twitter_oauth->{callback} );

      $c->response->cookies->{oauth} = {
          value => {
              token => $nt->request_token,
              token_secret => $nt->request_token_secret,
          },
      };
      $c->response->redirect( $url );

設定

twitter_oauth : 
    traits :
        -'API::REST'
        - 'OAuth'
    consumer_key    : "YOUR-CONSUMER-KEY"
    consumer_secret : "YOUR-CONSUMER-SECRET"
    callback        : http://umakatter.lazy-people.org/twitter/oauth/callback/

コールバック受け口

こんな感じ。エラー処理がない気がするけど気にしない方向で。これでおわり。

ユーザの、access_token , access_token_secret を手に入れると、
このユーザになりすまして色々できるようになります。とても便利だけど怖くもありますね。

    my $config = Umakatter::Config->instance();

    my %cookie = $c->request->cookies->{oauth}->value;
    my $verifier = $c->req->params->{oauth_verifier};

    my $nt = Net::Twitter->new( %{$config->twitter_oauth} );
    $nt->request_token($cookie{token});
    $nt->request_token_secret($cookie{token_secret});

    my($access_token, $access_token_secret) = $nt->request_access_token(verifier => $verifier);
    $nt->access_token($access_token);
    $nt->access_token_secret($access_token_secret);

    my $res = $nt->verify_credentials();
        my $twitter = {
            icon => $res->{profile_image_url},
            screen_name => $res->{screen_name},
        };

    # we do not want to store token in database for security reason.
    # just put it in session.
    my $user = $c->model('DB::Twitter')->find_or_create(
            {
                name => $twitter->{screen_name},
                icon => $twitter->{icon},
                count => 0,
                created_at => \'NOW()',
            },
            {
                key => 'name'
            }
    );

    $c->session->{twitter} = {
        name         => $user->name,
        icon         => $user->icon,
        icon_mini    => $user->icon_mini,
        access_token => $access_token,
        access_token_secret => $access_token_secret,
    };

    $c->res->redirect('/');

使ってる所

こんな感じ。

    my $ut = Umakatter::Twitter->new(  $c->session->{twitter} );
    my $status_id = $ut->shout( $restaurant_name , $content , $url );
package Umakatter::Twitter;
use Umakatter::Class;
use Umakatter::Config;
use Encode;

has 'nt' => (
    is => 'rw',
);
has 'access_token' => (
    is => 'rw',
);
has 'access_token_secret' => (
    is => 'rw',
);
has 'profile' => (
    is => 'rw',
    lazy_build => 1,
);

sub _build_profile {
    my $self = shift;
    warn 'profile';
    $self->nt->verify_credentials ;
}
sub BUILD {
    my $self = shift;
    my $config = Umakatter::Config->instance();
    my $nt = Net::Twitter->new( %{$config->twitter_oauth} );
    $nt->access_token( $self->access_token );
    $nt->access_token_secret( $self->access_token_secret );
    $self->nt( $nt );
}

sub shout {
    my $self    = shift;
    my $restaurant_name = shift;
    my $content = shift;
    my $url     = shift;
    my $str =  $restaurant_name. 'は旨い! ' . $content .' ' . $url;
    $str = Encode::decode( 'utf-8', $str );
    my $res = $self->nt->update( $str ) ;
    return $res->{id};
}

__UMAKATTER__;

まとめ

OAuthはとてもパワフルで、気軽に許可すると怖いと思いました。
ソースはここで公開しています。

練習がてらUmakatterディレクションをしたい方を募集しています。

興味のある方は、irc.lazy-people.org#project or irc.lazy-people.org#umakatter まで。