はじめに
Google Homeを買ったはいいものの、テレビ無し、外出ない、家電使わない自分には少々物足りないので
生活の大半を占めるスプラトゥーンのアシスタントをGoogle Homeには勤めてもらいます。
みたいな事を書いたので、その続きです。
GoogleHomeをDialogflow(旧:API.ai)でスプラトゥーンアシスタントにする
実装する機能
スプラトゥーンは3つのゲームモードがあり、それぞれ時間によってステージが異なります。
確認するにはスマホアプリかまたはゲーム内アナウンスで確認する必要があるので、これをハンズフリーで確認できるようにしたいと思います。
実装する機能のイメージ↓
僕「ステージ 〇〇(ゲームモード)」
GoogleHome「〇〇のステージは××(ステージ名)です」
また、ゲームモードの「ガチマッチ」「リーグマッチ」ではルールが3種類あるのでそれも確認できるようにします。
使用ツール・環境
- Google Home
- Dialogflow
- python3.5.2
- twython
webhookの置き場にherokuを使用し、
前回とは違い、IFTTTは使用せずDialogflowとwebhookのみで実装します。
ステージ情報の取得
現在配信されているステージ情報を取ってきます。
公式アプリから閲覧できるイカリング2からプロキシをごにょごにょして取ってきてもいいんですが、
【スプラトゥーン2】イカリング2の戦績データをPCブラウザで無理矢理閲覧する
世の中には便利なBotを作っている人がいるのでこちらのBotのツイートから取得しようと思います。
10/16 15:00~
— スプラトゥーン2 ステージ情報bot (@splatoon2_stage) 2017年10月16日
▼ナワバリ
タチウオパーキング、モズク農園
▼ガチエリア
バッテラストリート、海女美術大学
▼リーグ:ガチヤグラ
ガンガゼ野外音楽堂、コンブトラック pic.twitter.com/hL7og5epFO
ツイート取得機能は応用が効きそうですしね~~(イカリングからの取得が面倒そうだからという訳では無いです)~~
twythonをインストール
TwitterAPIを叩くのに今回はtwythonを使います。
初期設定はこちら参照
Twitter REST APIの使い方
どうせ大した事しないのでtwython使うまでも無い気はしますが...
$pip install twython
スクリプトを書きます。
from twython import Twython, TwythonError
APP_KEY = "取得したAPI Key"
APP_SECRET = "取得したAPI Secret"
OAUTH_TOKEN = "取得したAccess Token"
OAUTH_TOKEN_SECRET = "取得したAccess Token Secret"
def getStage(num,mode):
twitter = Twython(APP_KEY, APP_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET)
#ツイートを取得したいTwiiterアカウントのID
screen_name = "splatoon2_stage"
results = twitter.get_user_timeline(screen_name=screen_name,count=5)
date = list(filter(lambda s:s != '', results[num]["text"].replace("▼","").replace("、","と").split()))
time = date[1].replace((b'\xef\xbd\x9e').decode('utf-8'),"から")
nawabari = date[3]
gachi_mode = date[4]
gachi_stage = date[5]
league_mode = date[6].replace("リーグ:","モードは")
league_stage = date[7]
if mode == "ナワバリ":
return time + nawabari
elif mode == "ガチマッチ":
return time+"モードは"+gachi_mode+"ステージは"+gachi_stage
elif mode == "リーグマッチ":
return time +league_mode +"ステージは"+ league_stage
if __name__ == '__main__':
print(getStage(0,"ガチマッチ")+"です")
これで、現在のステージ名とガチマッチ・リーグマッチの場合は「ガチホコ」「ガチエリア」「ガチヤグラ」等のゲームモードを出力できるようになりました。
これを後は前回作成したpythonファイルに書き加えればOKです。
from __future__ import print_function
from future.standard_library import install_aliases
install_aliases()
from urllib.parse import urlparse, urlencode
from urllib.request import urlopen, Request
from urllib.error import HTTPError
import json
import os
from flask import Flask
from flask import request
from flask import make_response, jsonify
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from twython import Twython, TwythonError
APP_KEY = "取得したAPI Key"
APP_SECRET = "取得したAPI Secret"
OAUTH_TOKEN = "取得したAccess Token"
OAUTH_TOKEN_SECRET = "取得したAccess Token Secret"
# Flask app should start in global layout
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
req = request.get_json(silent=True, force=True)
result = req.get("result")
parameters = result.get("parameters")
text = ""
if req.get("result").get("action") == "getSpreadSheet":
text = getSpreadSheet(parameters.get("weapon_name"))
if req.get("result").get("action") == "getStage":
text = getStage(0,parameters.get("mode"))+"です"
r = make_response(jsonify({'speech':text,'displayText':text}))
r.headers['Content-Type'] = 'application/json'
return r
def getStage(num,mode):
twitter = Twython(APP_KEY, APP_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET)
screen_name = "splatoon2_stage"
results = twitter.get_user_timeline(screen_name=screen_name,count=5)
date = list(filter(lambda s:s != '', results[num]["text"].replace("▼","").replace("、","と").split()))
time = date[1].replace((b'\xef\xbd\x9e').decode('utf-8'),"から")
nawabari = date[3]
gachi_mode = date[4]
gachi_stage = date[5]
league_mode = date[6].replace("リーグ:","モードは")
league_stage = date[7]
if mode == "ナワバリ":
return time + nawabari
elif mode == "ガチマッチ":
return time+"モードは"+gachi_mode+"ステージは"+gachi_stage
elif mode == "リーグマッチ":
return time +league_mode +"ステージは"+ league_stage
def getSpreadSheet(weapon_name):
#
#省略 前回のスクリプト参照
#
return text
if __name__ == '__main__':
port = int(os.getenv('PORT', 5000))
print("Starting app on port %d" % port)
app.run(debug=False, port=port, host='0.0.0.0')
では、次にwebhookを送信するDialogflowの設定に行きましょう。
Dialogflowのセッティング
詳しくは前回のを見て頂くとして、新規に設定する部分を載せます。
前回のBotに機能を追加する場合はIntents
に新しく返答を登録すればOKです。
Intents
Intents
で入力の受け取りや失敗した際の返答を登録します。
新しくstage
を作成。CREATE INTENT
で新規intentを登録可能です。
(成績
が前回作成したintent)
今回はユーザーの発言が「ステージ」だった場合にBotが反応し、
「ステージ」の後に続く部分をmode
として入力で受け取ります。


Entities
入力として受け取る単語をEntities
から登録します。
今回もスプラトゥーンのデータベースは無いようなのでポチポチ登録しましょう。
Fulfillment
前回と変更点はありません。
webhookを流すurlを入力しておきましょう。
これでセッティングは終了です。
テストする
Dialogdlowのコンソール右側にテキストを入力してテストしましょう。
ステージが出てきました!
action
,parameter value
も問題なさそうですね。
完成
おわりに
今回はゲームモードを取得しましたが、先日開催されたフェスやもう1つのゲームモードサーモンランに対応していないのでそこら辺やろうかと思います。
でも別々のTwitterBotから取得するぐらいならイカリングから読み出した方がいい気も…先は長いですね。
スプラトゥーン以外にもTwitterとの連携は便利そうなので使っていきたいです。
良きスプラトゥーンライフを!(フェスは負けました)