m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

Mojoliciousの学習(TwitterAPIを使用)

Twitter Developerでアプリケーションを登録

URLにアクセスする

https://dev.twitter.com/

サインインして、「My applications」を選択

f:id:m_shige1979:20131027160619j:plain

「Create a new application」をクリック

f:id:m_shige1979:20131027160628j:plain

Name、Desctiption、Websiteを設定する

f:id:m_shige1979:20131027160649j:plain
f:id:m_shige1979:20131027160703j:plain

作成されたことを確認

f:id:m_shige1979:20131027160713j:plain

TwitterAPI実装

設定ファイル(app.conf)
{
    secret => "なんかのパスワード",
    consumer_key => "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    consumer_secret => "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv",
    title => "Mojoliciousのテストサイト",
    description => "m_shige1979がなんかいろいろやる目的のテストサイト",
    github => "https://github.com/mshige1979/heroku-perl-test01",
    
};
事前
# 設定ファイルを読み込み
my $config = plugin('Config', {file => 'app.conf'});

## Twitterのモジュール設定
my $nt = Net::Twitter->new(
    traits => [qw/API::RESTv1_1/],
    consumer_key => $config->{consumer_key},
    consumer_secret => $config->{consumer_secret},
);

# なんかよくわからんけどクッキーのセキュアにするとかなんとか
app->secret($config->{secret});

ここで設定ファイルから共通データを読み込み、予めTwitterのオブジェクトを取得

ログイン処理
# Twitterでログイン
get '/twitter/login' => sub {

    # パラメータを取得
    my $self = shift;
    
    # リクエスト取得
    my $url = $nt->get_authorization_url(
        callback => $self->req->url->base . '/twitter/callback'
    );

    # セッションデータへ保存
    $self->session(token => $nt->request_token);
    $self->session(token_secret => $nt->request_token_secret);
 
    # リダイレクト
    $self->redirect_to($url);

};

ここの画面でTwitterの画面へ遷移

ログアウト処理
# Twitterでログアウト
get '/twitter/logout' => sub {
    # パラメータを取得
    my $self    = shift;
    
    # セッションを開放
    $self->session(expires => 1);
    
    # リダイレクト
    $self->redirect_to('/twitter/');

};

認証した情報を消す

コールバック処理
get '/twitter/callback' => sub {

    # パラメータを取得
    my $self = shift;
    
    # deniedがない場合に処理を実施
    unless ( $self->req->param('denied') ) {
         
        my $token = $self->session('token');        
        my $token_secret = $self->session('token_secret');

        # セッションよりトークンを取得して設定
        $nt->request_token($token);
        $nt->request_token_secret($token_secret);
 
        my $verifier = $self->req->param('oauth_verifier');
        my ($access_token, $access_token_secret, $user_id, $screen_name) = $nt->request_access_token(verifier => $verifier);

        # アクセストークンをセッションへ保存
        $self->session(access_token => $access_token);
        $self->session(access_token_secret => $access_token_secret);
        $self->session(screen_name => $screen_name);

    }

    # Twitterのページへリダイレクト
    $self->redirect_to('/twitter/');

};

Twitterの画面から遷移されるので、正しく遷移した場合に実行してアクセストークンをセッションへ保存してメインの画面へ遷移

ログインボタンを表示するページ
# twitter画面
get '/twitter/' => sub {
    
    # パラメータを取得
    my $self = shift;

    # tweet用
    my $screen_name;
    my $tweets;

    # アクセストークンチェック
    if($self->session('access_token')){
        # セッション用アクセストークンを取得
        my $access_token = $self->session('access_token');
        my $access_token_secret = $self->session('access_token_secret');
        
        # 取得したアクセストークンを設定
        $nt->access_token($access_token);
        $nt->access_token_secret($access_token_secret);
        
        my %arg;
        $arg{'count'} = 200;

        # ホームタイムラインを取得して配列に格納
        my $list = [];
        for my $tweet (@{$nt->home_timeline({%arg})}){
            my $tweetData = {};
            
            # パラメータ設定
            $tweetData->{id} =  $tweet->{id};
            $tweetData->{text} =  $tweet->{text};
            $tweetData->{created_at} =  $tweet->{created_at};
            $tweetData->{profile_image_url} = $tweet->{user}->{profile_image_url};
            $tweetData->{screen_name} = $tweet->{user}->{screen_name};
            $tweetData->{in_reply_to_status_id} = $tweet->{in_reply_to_status_id};
            $tweetData->{source} = $tweet->{source};
            $tweetData->{name} = $tweet->{user}->{name};            

            if($tweet->{retweeted_status}){
                
                my $retweeted = $tweet->{retweeted_status};

                $tweetData->{retweete} = {};
                $tweetData->{retweete}->{status} = "1";
                $tweetData->{retweete}->{profile_image_url} = $retweeted->{user}->{profile_image_url};
                $tweetData->{retweete}->{name} = $retweeted->{user}->{name};
                $tweetData->{retweete}->{screen_name} = $retweeted->{user}->{screen_name};
                $tweetData->{retweete}->{text} = $retweeted->{text};

            }

            # 配列に設定
            push @$list, $tweetData;
        }

        # 認証情報がある場合に表示
        $screen_name = $self->session('screen_name');
        $tweets = $list;

    }

    # 変数をセット
    my $sub_title = 'Twitterテストページ';

    # テンプレート変数をセット
    $self->stash('title', $config->{title});
    $self->stash('description', $config->{description});
    $self->stash('github', $config->{github});
    $self->stash('subTitle', $sub_title);

    $self->stash('screen_name', $screen_name);
    $self->stash('tweets', $tweets);

    # twitterを割り当て
    $self->render('twitter');
};

ここでホームタイムラインを取得する

確認

TOP

f:id:m_shige1979:20131027162413j:plain

初期画面

f:id:m_shige1979:20131027162421j:plain

ログインしてTwitterの連携ページ

f:id:m_shige1979:20131027162429j:plain

連携後のページ

f:id:m_shige1979:20131027162435j:plain

いろいろ困ったこと

httpsのページへ遷移できなかった

一応、「cpanm LWP::Protocol::https」、「cpanm Crypt::SSLeay」で対応

「401 unauthorized」が出てTwitterの連携ページへ遷移しない

原因として考えられることは不明だったけど多分
タイムスタンプが古かったのかな?環境はVMWareでやってて毎回休止状態からの復旧だったので
あとはURL関連かも

まとめ

TwitterAPIでの結果が401だけだったので対策を見つけるのにかなりの時間を要した。。。
もっと明確なエラーメッセージが欲しかったと思う。

認証の動きがちょっとややこしいけどコレで認証関連の動きがわかった。

リストとか配列はほとんどリファレンスしか
使っていないけどとりあえず使っているうちに慣れてくると思うのでやり続けよう。