Help us understand the problem. What is going on with this article?

GoogleAppEngine SDK for PythonでTwitter BOTを作る

More than 5 years have passed since last update.

Pythonの勉強のために無料でも使えるGoogleAppEngine(以下GAE)をプラットフォームにTwitter BOTを作成して運用しています。
BOTはGoogleアラートを利用してラブライブのニュースを定期的に呟いてます。
アカウント: @ll_news_bot
ソース : GitHub

GAE SDK for PythonでBOTを運用するまでの手順を備忘録として残しておきます。

BOT仕様

今回作成したBOTの最終的な仕様は次のようになります。

  • 30mごと(※1)にGoogleアラートの新エントリを呟く(9:00~23:59)
  • フォローミーを呟く(18:30)
  • 30mごと(※1)にフォロー返し(6:00~23:59)
  • 1h毎にフォローのみの場合リムーブ(0:00~5:59)

※1 GAEにはインスタンス時間というものがあり、リクエストの処理期間中のみ時間を消費するというわけではない。
リクエストが終わった後もすぐ対応できるようアイドル状態になるが、その間も時間を消費する。
そのため、呟きとリフォローを同じ時間に行うことで無駄なアイドル時間を消費しないようにしています。

事前準備

Googleアラート

Googleアラートから新しいニュースを作成します。この時配信先を フィード にします。

環境

ローカルで開発するために次の環境を使用しています。

  • Mac OS X 10.9.2
  • Eclipse 4.3 + PyDev
  • GoogleAppEngineLauncher 1.9.2
  • Python2.7.6

Twitter

  • BOTアカウントの取得
  • Twitter Developerへの登録
  • 新しいアプリの作成とAPIキーの取得
    • Permissions - アクセス権限をR/W に変更
    • Test OAuth より各種認証情報を取得

GoogleAppEngine

appengine.google.com よりBOT用の新しいアプリケーションを作成します。
この時入力した Application Identifier は GAELauncherで新しいアプリを作成する際に Application ID で使用します。

外部モジュール

BOT開発にあたり次のサードパーティ製モジュールを利用しました。
Twitter APIのPythonラッパーとRSSフィードのパーサーの2種類のモジュールです。

上記のモジュールはWebアプリケーションと一緒にGAE上にデプロイしなければいけないので、
モジュールをインストール or ビルドしたあと、プロジェクト内にコピーする必要がありました。

BOT実装

作成したBOTの機能は大きく「RSSフィードから呟きの作成」と「Twitter APIの操作」になりますので、これらの処理ごとのモジュールを作成していきます。

feedモジュール

このモジュールでは feedparser モジュールを利用してRSSフィードを解析し、呟く内容を作成しています。
新着エントリがないか定期的に確認しているため、重複して呟かないように DataStore を利用しています。

class FeedFetcher(object):
    '''GoogleアラートのRSSフィードをパースするためのクラス'''

    def fetch_new_entries(self):
    '''GoogleアラートのRSSフィードから新しいエントリを取得する。'''
    # 省略
    return new_entory

class Entry(object):
    '''解析したエントリー情報を格納するためのクラス'''

    def make_tweets(self):
    '''呟き内容を作成する'''
    return # 呟き

# 使い方
fetcher = FeedFetcher()
new_entries = fetcher. fetch_new_entries()
for entry in new_entries:
    print entry.make_tweet()

botモジュール

このモジュールでは、python-twitterモジュールをラップし、必要なAPIを簡単に叩けるようにしています。
また、準備の時に取得したTwitterの認証情報をpython-twitter APIに渡しています。
こちらを参考にさせていただき、GAEでpython-twitterを使用する場合はキャッシュしないようにしています。

class TwitterBot(object):
    '''Twitterへの呟き、ユーザのリフォローとフォロー解除を行うためのクラス'''

    def tweet(self, message):
    '''Twitterへ対象の内容を呟く'''
    # 省略

    def get_not_follow_users(self):
    '''未フォローユーザのIDリストを取得する'''
    return # 未フォローユーザIDリスト

    def refollow(self, not_follow_id):
    '''対象のユーザをフォローする'''
    # 省略

    # ...省略

#使い方
bot = TwitterBot()
fetcher = FeedFetcher()
bot.tweet(fetcher. fetch_new_entries[0].make_tweet)
bot.refollow(bot. get_not_follow_users()[0])

リクエストハンドラ

まずURLマッピングを行うために app.yaml ファイルを作成します。
login が admin になっていると、ブラウザ上でURLを叩いてもアカウント認証しないとリクエストが送信されないようになります。
script には モジュール名とURLマッピングを行う WSGIApplication オブジェクト名を書きます。

application: ll-news-bot
version: 8
runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /
  script: tweet.app
  login: admin

- url: /tweet
  script: tweet.app

python側では RequestHandler を継承したクラスを作成し、get もしくは post メソッドのハンドル処理を書いていきます。
一度に大量にTwitterAPI をコールすることはありませんが、勉強のためタスクキューを使用しています。
タスクが実行されると指定したURLにPOSTメソッドのリクエストが送信されます。

tweet.py
class MainHandler(webapp2.RequestHandler):    
    def get(self):
         taskqueue.add(queue_name='tweet', url='/tweet', params={'message': u'テスト'})

class TweetHandler(webapp2.RequestHandler):    
    def post(self):
        # つぶやき処理
        bot = TwitterBot()
        bot.tweet(self.request.get('message')

app = webapp2.WSGIApplication([('/', MainHandler), ('/tweet', TweetHandler)], true) 

タスクキューを使用するには queue.yaml を作成します。タスクキューに関する説明は次のサイトがとても参考になりました。

app.yaml
queue:
- name: tweet
  rate: 1/s
  bucket_size: 1 
  retry_parameters:
    task_retry_limit: 0

最後にこの処理を定期的に実行させるように cron.yaml ファイルを作成します。
どのくらいの間隔で実行するか schedule で設定します。

cron.yaml
cron:
- description: tweet task
  url: /
  schedule: every 30 minutes from 9:00 to 23:59
  timezone: Asia/Tokyo

ローカル実行

GAELaucherアプリを使用し、ローカル環境でアプリの動作確認してみます。
作成はLauncherアプリから行えます。その際、Application IDに事前準備で予め作成しておいたアプリの Application Identifier を使用します。

実行の前にメニューから Make Symlink を実行しておく必要があります。
また、GAEが使用するポート番号を他のアプリが使用している場合は、どちらかのポート番号を変更する必要があります。

デプロイ

最後にGAELauncherを使用し、Googleのサーバーにアプリケーションをデプロイします。
その際にアカウント入力がありますので、事前準備で作成したアプリケーションに対応するGoogleアカウントを入力します。

デプロイ中に Checking if deployment succeeded. が延々と表示される場合がありましたが、これはサーバー側の問題のようです。
最後にバージョンを上げて再デプロイするかロールバックしてくださいとでますので、今回はバージョンを上げて再デプロイしたところ上手くいきました。
  
以上がTwitterのBOTを開発してから運用するまでの流れになります。

droibit
Androidのアプリ作ってます。最近はKotlinが熱い(・8・)
https://github.com/droibit
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした