Twitterで自動ふぁぼをつけられるWEBアプリをつくりました。
Twitterで自動ふぁぼ!PythonでTwitterBOTをつくる。の続きの記事です。
上記の記事で作成した自動ふぁぼアプリは、事前に取得した認証キーを入力したユーザー、つまり自分しか使用できないものでした。
今回はTwitterAPIのOAuth認証について学び、誰でも使えるWEBアプリとして公開することに成功しました。
今回はその過程をまとめていこうと思います。
ちなみに自動ふぁぼ機能はこちらのWEBアプリから使えますので良ければどうぞ!(2019/03現在)
MINIBOT
もくじ
今回作成したアプリの概要
今回作成したのは、指定したキーワードを含むツイート最大30件にいいねをつけるBotアプリです。
こちらから使えます。※下記不具合により使用できない場合あり!ご了承お願いします!
せっかくTwitterのOAuth認証をマスターしたので、以前作った自動ふぁぼアプリをWEBアプリ化してみました!https://t.co/5UH31r6Wd2 pic.twitter.com/CvXeIeOqbG
— カシワバユキ@Androidアプリ (@yuki_kashiwaba) 2018年11月17日
開発に使用しているのは、
・Python3
・Flask
・Heroku
・TwitterAPI
・Tweepy(Pythonのライブラリ)
です。
実装した機能は、
・Twitter認証
・キーワードの取得
・入力されたキーワードを含むツイートに対するふぁぼの実行
です。
ただ、初めは完全に動作していたのに、URLをツイッターで公開してから原因不明の不具合が起きるようになってしまいました…。
認証に成功したユーザーの情報をDBに保存せず、毎回認証させてるせいなのか、設計のミスなのか、原因が全くわかりません。
ツイッターに公開したら突然使えなくなってしまったんだけど、もしかして複数人が一斉に使うとおかしくなるような致命的なバグがある感じですか…? https://t.co/TsO1H4cJpU
— カシワバユキ@Androidアプリ (@yuki_kashiwaba) 2018年11月17日
現在においても、連続で何度か使用すると同様のエラーが発生しています。
欠陥WEBアプリですね。
修正するにも原因がわからず困っているので、もしわかる方がいらっしゃればコメントしていただけると嬉しく思います。
ローカルだと完璧に動作するので、ブラウザとかネットワーク関連のエラーだと思うんですよ。
ネットワークもWEBのことも全然知らないので原因わかる方教えてください…(泣) pic.twitter.com/M5q9umS5X5— カシワバユキ@Androidアプリ (@yuki_kashiwaba) 2018年11月17日
OAuth認証について
今回の肝はOAuth認証でした。
TwitterAPIを使ったアプリケーションをWEBアプリとして利用するにあたって、使用ユーザの認証は不可欠です。
OAuth認証とは、とても簡潔に言えば、「悪意あるアプリケーションにユーザーの情報を渡さない」ための認証の仕組みです。
詳しくはこちらの記事が分かりやすかったです。
キーワードは、アクセストークンと認可サーバーの二つ。
API側は、データを要求してきたアプリケーションから受け取ったアクセストークンを検証し、データを返します。
このアクセストークンは、認可サーバーというサーバーから、ユーザーの承認によって発行されます。
今回のTwitterAPI認証も同様の仕組みで成り立っています。
今回は、PythonのライブラリであるTweepyを用いて認証を行いました。
参考にしたのはこちら。
Twitterの連携アプリを作成する(他人のアカウントでつぶやく)
Twitter認証を実装する
ここからは、例によってコードをぺたぺた貼っていきます。
import tweepy import urllib import os from flask import Flask, redirect, url_for, render_template,request,flash from requests_oauthlib import OAuth1Session from urllib.parse import parse_qsl import twitter app = Flask(__name__) ck = "APIのキー" cs = "シークレットキー" auth = tweepy.OAuthHandler(ck, cs) app.secret_key = 'ランダムな文字列' #Flashのために必要 @app.route('/') def main(): try: redirect_url = auth.get_authorization_url() return render_template("index.html", redirect_url=redirect_url) except tweepy.TweepError: flash('認証に失敗しました。もう一度やり直してください。') return render_template("error.html") return render_template("index.html", redirect_url=redirect_url) @app.route('/callback') def callback(): try: token = request.values.get('oauth_token', '') verifier = request.values.get('oauth_verifier', '') #flash('認証に成功しました。') return render_template("index.html", token=token, verifier=verifier) except: return render_template("error.html") @app.route('/input', methods=["POST"]) def input(): if request.method == "POST": text = request.form["text"] token = request.form["token"] verifier = request.form["verifier"] auth.request_token = {'oauth_token':token, 'oauth_token_secret':verifier} try: auth.get_access_token(verifier) except tweepy.TweepError: print('Erroredirect Failed to get access token.') AT = auth.access_token AS = auth.access_token_secret twitter.twitter_fav(text,AT,AS) flash(text + 'を含むツイートにいいねをつけました。') return redirect("https://twi-api-test.herokuapp.com/") if __name__ == '__main__': app.run()
これがメイン部分のコードです。
流れとしては、
①リクエストトークンを取得
②リクエストトークンを使ってアクセストークンを取得
という二つの処理を行っているだけなのですが、かなり苦戦しました。
①リクエストトークンを取得
コードでいうとこの部分です。
def main(): try: redirect_url = auth.get_authorization_url() return render_template("index.html", redirect_url=redirect_url) except tweepy.TweepError: flash('認証に失敗しました。もう一度やり直してください。') return render_template("error.html") return render_template("index.html", redirect_url=redirect_url)
Tweepyを使って、認証を行うためのURLを取得しています。
認証サイトでアプリ連携を許可すると、設定したURLにリクエストトークンの情報を付与された状態でコールバックされます。
コールバックされたURLに認証情報が付与されているので、GETメソッドで送られていているのだとは思います。
以下のコードは、返されたリクエストトークンを取得するためのコードです。
@app.route('/callback') def callback(): try: token = request.values.get('oauth_token', '') verifier = request.values.get('oauth_verifier', '') #flash('認証に成功しました。') return render_template("index.html", token=token, verifier=verifier) except: return render_template("error.html")
受け取ったリクエストの中から、’oauth_token’と’oauth_verifier’を取得しました。
次は、この情報を元にアクセストークンを取得します。
②リクエストトークンを使ってアクセストークンを取得
Tweepyのライブラリを使えば、必要なのはこの4行だけです。
便利なのですが、理屈がわかってなかったので苦労しました。
auth.request_token = {'oauth_token':token, 'oauth_token_secret':verifier} auth.get_access_token(verifier) AT = auth.access_token AS = auth.access_token_secret
まとめ
相変わらずの解説割愛祭りで心苦しい。
解説文を書こうと思うと筆が止まるのは、理解が浅いからなのでしょう。
今は実装でいっぱいいっぱいですが、いずれは技術書を書けるレベルの深い知識を身に着けたい…。