Home

読み込み中...

Google App EngineでRSSをツイートするbotをつくるまで

2011/05/13

このエントリーをはてなブックマークに追加

はじめに

Pythonです。Javaじゃないです。Pythonはすごく良い言語です。

Go言語も出るとかいう話でますます盛り上がりを見せそうですね、Appengine。

以下、Macな環境ですすめます。ちなみにPython2.5がいります。

下準備

Google App Engine SDK for Pythonのセットアップ

こちらからダウンロードし、Applicationsフォルダにつっこみます。
Macの場合、一度起動するとシンボリックリンクはるか聞かれるのではいと答えておきましょう。

Applicationを作成する

今度はこちらでApplicationを作成しておきます。

Kay Frameworkのダウンロード

ここからダウンロードできます。
(Kayについて詳しくは公式ドキュメント(日)を参照してください)

プロジェクトの作成

では、早速プロジェクトを作成します。
先程ダウンロードしたKay Frameworkのmanage.pyを呼び出してプロジェクトを作成します。

% python kay/manage.py startproject myproject
% cd myproject

ライブラリを用意する

myproject直下にライブラリを配置するためのフォルダを作成します。

% mkdir lib

tweepy

TwitterのAPIを呼ぶために使います。
tweepyをダウンロードしてその中のtweepyフォルダをそのままlibに置きます。

Universal Feed Parser

RSSフィードを処理するために使います。
Universal Feed Parserのfeedparser/feedparser.pyをlibに置きます。

アプリケーションをつくる

実際のコードを書いていくアプリケーションを作成します。
ここではrssとします。

% python manage.py startapp rss

プロジェクトでアプリケーションを利用出来るように設定ファイルを編集します。

myproject/settings.py

INSTALLED_APPS = (
    'rss',
)

処理を書く前にちょっとした準備

Twitterのアプリケーションを作成して、Consumer Keyなどをゲットしておく

つぶやかせたいアカウントでログインした状態でTwitter Applicationsにアクセスすると、アプリケーションの登録、Access Tokenの取得などできます。

bit.lyの開発者用IDを取得しておく

短縮URLを生成するために使います。
bit.lyにログインした状態でここにアクセスすると取得できます。

RSSフィードのURL

ちなみにRSSのURLですが、僕はここでつぶやかせたいRSSをGoogleリーダーでフォルダにまとめています。
それを公開設定にし、その公開ページで取得できるRSSを指定することで複数のフィードをまとめてつぶやかせています。

実際の処理を書く

rssbot/views.py

# -*- coding: utf-8 -*-

import urllib
from google.appengine.api import (
  memcache, urlfetch
)
from google.appengine.ext import deferred
from kay.utils.decorators import cron_only
from werkzeug import Response
import feedparser
import tweepy

# Twitter
CONSUMER_KEY = 'YOUR_CONSUMER_KEY'
CONSUMER_SECRET = 'YOUR_CONSUMER_SECRET'
ACCESS_TOKEN = 'YOUR_ACCESS_TOKEN'
ACCESS_TOKEN_SECRET = 'YOUR_ACCESS_TOKEN_SECRET'

# bit.ly
BITLY_API_URL = 'http://api.bit.ly/v3/shorten?login=%s&apiKey=%s&format=txt&longUrl=%s'
BITLY_USER = "YOUR_USER_NAME"
BITLY_API_KEY = 'YOUR_BITLY_API_KEY'

# RSS
FEED_URL = "http://www.google.com/reader/public/atom/user%2F00376767601824910239%2Flabel%2FPublic"

# Cron処理
@cron_only
def index(request):
  deferred.defer(task)
  return Response(None)

# Cron処理から呼ばれる
def task():
  atom = feedparser.parse(FEED_URL)

  tweets = memcache.get("rss")
  if tweets == None:
    tweets = []

  for e in atom.entries:
    if not e.link in tweets:
      tweets.append(e.link)
      if not e.title.startswith('PR:'):
        deferred.defer(tweet, e.source.title, e.title, e.link)

  # 最新100件をmemcachedに保存する
  tweets = tweets[len(tweets)-100:]
  memcache.set("bot", tweets)

  return Response(None)

# Tweetするタスク
def tweet(blog_title, article_title, link):
  try:
    s_link = shorten_url(link)

    auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
    auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
    api = tweepy.API(auth)

    title = ''
    if blog_title is not '':
      title += u'【%s】 ' % blog_title

    title += article_title
    status = '%s %s' % (title, s_link)
    # 140文字を超えるならタイトルを切り捨てる
    if len(status) > 140:
      status = title[:(140 - len(s_link)-3)] + u'…  ' + s_link

    api.update_status(status=status)
  except Exception:
    pass

  return Response(None)

# URLを短くする
def shorten_url(long_url):
  bitly = BITLY_API_URL % (BITLY_USER, BITLY_API_KEY, urllib.quote_plus(long_url))

  result = urlfetch.fetch(bitly)
  if result.status_code != 200:
    return long_url

  return result.content[:-1]

エラー処理とか適当ですがまぁ個人的なものならこれで事足りると思います。

cronの設定

twitterbot/cron.yaml

このファイルは最初ないので自分で作ります。

cron:
- description: rss
  url: /rss/
  schedule: every 3 minutes 

ここでは3分毎にcron処理するように設定します。

デプロイする

app.yaml

myprojectの部分を自分のアプリケーションIDに置き換えます。

application: myproject

あとは以下のコマンドを実行してGoogleのID, パスワードを入力したら完了です。

python manage.py appcfg update

以上です!

大変お世話になったリンク

Leave a comment