アプリ開発

Twitterで指定したハッシュタグのツイートのタイムラインを表示する方法

twitterタイムライン

私が作ったwebサービスで、twitterでシェアする場合にハッシュタグをつけて、サイト上で、そのハッシュタグがついたツイートのタイムラインを表示するようにしました。

本記事では、特定のハッシュタグに紐づいたツイートのタイムラインを表示する方法について記載します。

 開発者の申請をする。

以前は、ハッシュタグに紐づいたツイートのタイムラインをページに埋め込むことができるウィジェットが提供されており、簡単に設置できましたが、2018年に廃止されてしまいました。

現在(2020年3月)は「https://publish.twitter.com/」のページで、タイムラインを埋め込んだソースを生成するサービスが提供されています。

しかし、このページでは「あるユーザーのツイートのタイムライン」や「”いいね”をしたツイートのタイムライン」などは表示できるのですが「あるハッシュタグに紐づいたツイートのタイムライン」を表示する機能は提供されていません。

結局、現状では「あるハッシュタグに紐づいたツイート」を表示するためには、「Twitter Developer(開発者)」として承認してもらって、APIを使用してプログラムで実現するしかありません。

Twitter Developerとして承認してもらうためには、「https://developer.twitter.com/」のページから申請します。

以下、具体的な申請方法は省略します(気が向いたら別途記事を書きます)が、皆さんが(私もでしたが)この申請に怖気付く理由の一つが英語で理由を書かなくては行けない事です。

しかも200文字以上で記載する欄や100文字以上で記載する欄など、かなり詳細な使用目的を書く必要があります。

しかし、私の経験からすると、文法とか滅茶苦茶のかなり適当な英語でも大丈夫でした。

どれくらい適当かと言うと、以下ぐらい適当な文章でもOKです。

I am managing web service and I want user to share page on my web site with partiular hashtag and I want to show timeline of this hashtag on my website. And I want to know segment of user who visit my website.

なお、ネットでは、「メールで再度、詳細な使用目的を確認される」等の記事がありましたが、私の場合は、入力後に来た確認メールのリンクを押してすぐに承認されました。(メールもとても読まれたとは思えない速さで来ました・・AIで判定してる??)

申請して承認されたら、アプリを作成するメニューから、アプリを作成して「Access Token」「Access token sercret」を発行します。

なお実際にAPIを使ってコーディングをするために必要な情報は以下の4つとなります。

  • API key
  • API secret key
  • Access token
  • Access token secret

サーバーサイド(python)でURL一覧を取得

ここからは、ハッシュタグに紐づいたツイートのタイムラインを表示するための具体的な方法(ソースコード)について記載していきます。

色々な方法があると思いますが、私は、サーバーサイドでハッシュタグに紐づいたつぶやきのURLの一覧を取得して、クライアントサイドでサーバーから返されたURL一覧から、公開されている「https://platform.twitter.com/widgets.js」のスクリプトを使って表示する方法を選択しました。

サーバーサイド(python+ flask)のコードは以下のようになります。

# 事前にpip install tweepyでインストールされている事
import tweepy
     :

@app.route("/api/tweet")
def show_tweet():

   #4つの必要なキー (https://developer.twitter.com/で取得・生成したキー)
    api_key = xxxxxxxxxxxxxxx
    api_secret_key = xxxxxxxxxxxxxxx
    access_token = xxxxxxxxxxxxxx
    access_token_secret = xxxxxxxxxxxxxxxxx

    auth = tweepy.OAuthHandler(api_key, api_secret_key)
    auth.set_access_token(access_token, access_token_secret)

    tweet_url_list = []
    api = tweepy.API(auth, wait_on_rate_limit=True)

   # #hogehogeのハッシュタグがついたタイムラインを取得 件数は10件、リツイートは、除外 
    for tweet in tweepy.Cursor(
          api.search, q="#hogehoge " + " -filter:retweets")
          .items(10):
     #URLの一覧を生成   
        tweet_url_list.append(
           f"https://twitter.com/user/status/{tweet.id}")
   #json形式で返す。 
    return jsonify(tweet_url_list=tweet_url_list))

 

この段階で、ツイートの内容も取得しようと思えば取得できますが、あくまでもURLのみを取得して、表示するための情報の取得はクライアントサイドに任せます。

なお、注意点としては、APIを呼び出す頻度には制限があり、検索の場合だと15分で180回までとなります。

もし制限を超えた場合は、15分間制限解除するまで待たされます。(tweety,APIの引数でwait_on_rate_limit=Trueを指定している場合)

私の場合は、それほどリアルタイム性を求める情報ではないので別途CDNで1分間はキャッシュするようにしています。

上のコードでは省略しましたが、最後のreturnの箇所は実際には以下のようなコードとなっています。(実際の実際は共通化しているのでまた違いますが・・)

response = make_response(
    jsonify(tweet_url_list=tweet_url_list)))
# ブラウザでのキャッシュ時間(秒)
response.cache_control.max_age = 30  
# CDNでのキャッシュ時間(秒)
response.cache_control.s_maxage = 60 
# キャッシュを共有
response.cache_control.public = True 
return response

 

クライアントサイドで描写する。

サーバーからURLの一覧を取得して、ツイートの一覧を生成します。

通常のツイートを表示するための基本的なソースコードは、以下となります。

<blockquote class="twitter-tweet">
<a href="https://twitter.com/user/status/(tweetid)"></a>
</blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8">
</script>

 

読み込んだ「widgets.js」がclass=”twitter-tweet”を解釈して良さげなカード表示にしてくれます。

ただし、今回はサーバーから返された結果を元に動的にHTMLを生成するため、注意点が2つあります。

1点目は、「widgets.js」の読み込みは1回だけにする事です。

上記のコードをループさせて、何回も同じjsを読み込む必要はありません。また、私が作っているサイトの場合は、別途ツイートボタンを表示するためにすでに「widgets.js」は読み込んでいるため、これも合わせて1回だけ読み込むように1箇所に (<head>タグ内)に記載しました。

<head>
    :
   <script async src="https://platform.twitter.com/widgets.js" charset="utf-8">
   </script>
    :
</head>

 

2点目は、「widgets.js」が読み込まれるタイミング(実行タイミング)が処理対象のHTMLの生成タイミングよりも早いと上記の<blockquote>タグをツイートを表示するように変換してくれません。(ツイートボタンも同様です。)

なので、htmlが生成し終わったタイミングで確実に実行(再実行)させる必要があります。

そのための方法は用意されており、以下のように記載します。

twttr.widgets.load(
    document.getElementById(--jsを適用させたい箇所の親タグを指定 --)
)

 

実際のサーバーへのリクエストからタイムラインの描画までのクライアント側でも処理は以下のようになります。(「まだjqueryとか使ってるの?」って感じですがご容赦を・・)

$.ajax({
    type: "GET",
    url: "/api/tweet",
    dataType: "json"})
    .done(function(data) {
        tweet_url_list = data.tweet_url_list
        //件数が0件の場合はエリア毎非表示にする。
        if (tweet_url_list.length == 0) {
            $('#tweet_area').css('display','none');
        }else{
            //戻ってきた件数分のタグを生成
            for(var i in tweet_url_list) {
                $('<blockquote class="twitter-tweet" data-conversation="none"><a href='+ JSON.stringify(tweet_url_list[i])+ '></a></blockquote>').appendTo('#tweet_list')    
            }
            //html生成後にjsをロード(該当箇所の親タグのみ対象)
            twttr.widgets.load(
                document.getElementById('tweet_list')
            );
        }
    })
    //エラーの場合はエリア毎非表示にする。
    .fail(function() {
        $('#tweet_area').css('display','none');
    });

なお、注意点として「今ままでTwitterやってなかったけど、ちょっとテスト用にアカウント作って動作確認してみようか」と思って急遽作成したアカウントで、ツイートしてそれを上記コードで検索しようとしても、検索にヒットしない場合があります。

私がまさにその状態で、適当なハッシュタグでテストした他の方のツイートは検索できるのに、本番用のハッシュタグで、自分がツイートしたものについては「シェア用のリンクを付けた場合は検索にヒットするけど、リンクを付けると検索にヒットしない。」という現象で、APIの仕様を散々調べましたが、わからずに、最終的に、作成したばかりのアカウント(フォロー、フォロワー0)では、信頼性が無いので、リンク付きのツイートが検索されないようになっている。というのを知りました。(こちらのサイトhttps://it.sorayori.com/twitter_spam/を参考にさせていただきました。)

まとめ

以上、Twitterで指定したハッシュタグに紐づくツイートのタイムラインを表示する方法について記載しました。

ツイートの情報を取得して分析するなど高度な事をするならばともかく、ぶっちゃけ、この程度の事をやるために、わざわざ開発者の申請までしなければいけないのはどうかと思います・・

ただ、開発者として、twitterの情報を利用する事を想定しているならば、どちらにせよ開発者の申請をしておいて損は無いと思います。

私も、他の利用方法を模索してアプリ開発に利用できればと思います。