やりたいこと
Lambdaで定期的に特定のハッシュタグが含まれるTweetを取得して、それに対して自動で画像付きリプライを送る。
実装方法
- CloudWatchのイベント機能で、n時間に一回Lambdaの関数を実行させる
- Lambdaで、
- S3からツイートに添付する画像ファイルを取得
- n時間分の特定のつぶやき(例:
#W杯
を含むツイート)を取得 - 取得した特定のつぶやきに対して画像付きでリプライを送る
Lambdaで実装する理由としては、
- 1日に数回しか実行しないスクリプトの為に常に稼働しているサーバを構築、管理するのはコストと時間がかかるのでやりたくない
- コスト面では、Lambdaは月々100万リクエストまで無料
- 添付画像に使うファイルをS3にアップロードするだけでよく、管理が楽
- AWSのアカウントがあれば誰でも扱える
といったことが挙げられます。
TwitterAPIを扱う為のPythonライブラリ Tweepy
今回はPythonのライブラリTweepyを使って実装します。
http://www.tweepy.org/
API Referenceはこちらです。
TwitterのAPIが簡単に扱えるようになっています。
例えば検索APIは、
api.search(q='"#W杯"', lang='ja', result_type='recent',count=10)
このようにすることで、#W杯
を含む日本語のツイートを最新のものから10件取得してくれます。
環境
- Python 3.6.3
- tweepy 3.6.0
必要なライブラリ等の導入
# Tweepyのインストール
pip install tweepy
今回はApexを使ってLambda関数をデプロイします。
導入については以下の記事を参照してください。(自演)
https://qiita.com/shioiyan/items/9ef9d309b8c16fe6b427
ファイル構成
今回のファイル構成は以下のようになります。
.
├── functions
│ └── twitter_reply
│ ├── function.json
│ ├── index.py
│ ├── requirements.txt
│ └── site-packages
└── project.json
実装
{
"description": "twitter reply method",
"runtime": "python3.6",
"handler": "index.lambda_handler",
"environment":{
"PYTHONPATH": "/var/runtime:/var/task/site-packages",
"CK": "xxxxx(Consumer Key)",
"CS": "xxxxx(Consumer Secret)",
"AT": "xxxxx(Access Token)",
"AS": "xxxxx(Access Token Secret)",
"KEYWORD": "#W杯",
"IMAGE_NAME": "football.png",
"BUCKET_NAME": "xxxxx(S3のbucket名)",
"TEXT": "ニッポンチャチャチャ"
}
}
TwitterアプリケーションのConsumer Key等はこちらでアプリケーション登録を行うことで取得することができます。
KEYWORD
にはリプライを送りたいハッシュタグを入れておきます。
IMAGE_NAME
リプライで添付する画像(S3のBUCKET_NAME
配下に置いておく)の名前です。
TEXT
はリプライで画像と共に送る文章です。
# coding: UTF-8
import tweepy
from tweepy import TweepError
import os
import boto3
# Twitterの認証周りのkey
CK = os.environ['CK']
CS = os.environ['CS']
AT = os.environ['AT']
AS = os.environ['AS']
# Lambdaで実行される関数
def lambda_handler(event, context):
# Twitterの認証
auth = tweepy.OAuthHandler(CK, CS)
auth.set_access_token(AT, AS)
api = tweepy.API(auth)
# s3から画像ファイルを取ってきてローカルに保存
s3 = boto3.resource('s3')
bucket_name = os.environ['BUCKET_NAME']
filename = os.environ['IMAGE_NAME']
file_path = '/tmp/' + 'image.png'
bucket = s3.Bucket(bucket_name)
bucket.download_file(filename, file_path)
# キーワードに当てはまるつぶやきをしている人に画像付きでリプライ
keyword = os.environ['KEYWORD']
text = os.environ['TEXT']
for status in api.search(q=keyword, result_type='recent',count=1):
print(status._json)
statusId = status.id
name = status.author.name
replyText = name + ", " + text
try:
# reply
api.update_with_media(file_path, status=replyText.encode("UTF-8"), in_reply_to_status_id=statusId)
except TweepError:
print("Debug::TweepError reply failed...")
tweepy==3.6.0
今回使うインストールしておく必要のあるライブラリはtweepyだけです。
これをApexでデプロイしましょう。
$ apex deploy twitter_reply --profile lambda-user --region ap-northeast-1
実行例
$ apex invoke twitter_reply --profile lambda-user --region ap-northeast-1
実行することでKEYWORD
で設定したハッシュタグの含むツイート一件に対してリプライを画像付きで送ることができます。
また、定期的に実行するには、CloudWatchのイベントを使うことで実現できます。
注意点
- 無差別にリプライを送ることはやめましょう。
- 鍵垢(Tweet非公開)のTweetは
api.search()
で取得できません。- Tweetを公開に設定を変えても、鍵垢の時にTweetしたものは取得できないです。(自分が試した限りではそうでした)
- Twitter APIは時間あたりのリクエスト制限があるのであらかじめ確認しておいた方が良いです。
まとめ
Amazon Lambdaを使ってTwitterの特定のハッシュタグを含むツイートに画像付きでリプライを送ることができました。
鍵垢に対してリプライを送れないのが不便で、デバッグが大変だと感じました。
たくさんのツイートにリプライを送るときにどれくらいの実行時間が必要なのかはLambdaを使う上で確認しておく必要がありそうです。