LoginSignup
16
12

More than 5 years have passed since last update.

GoogleHomeをスプラトゥーンアシスタントにする #2 Twitterからステージ情報の取得

Last updated at Posted at 2017-10-16

はじめに

Google Homeを買ったはいいものの、テレビ無し、外出ない、家電使わない自分には少々物足りないので
生活の大半を占めるスプラトゥーンのアシスタントをGoogle Homeには勤めてもらいます。

みたいな事を書いたので、その続きです。
GoogleHomeをDialogflow(旧:API.ai)でスプラトゥーンアシスタントにする

実装する機能

スプラトゥーンは3つのゲームモードがあり、それぞれ時間によってステージが異なります。
確認するにはスマホアプリかまたはゲーム内アナウンスで確認する必要があるので、これをハンズフリーで確認できるようにしたいと思います。
スクリーンショット 2017-10-16 17.55.37.png

実装する機能のイメージ↓

僕「ステージ 〇〇(ゲームモード)

GoogleHome「〇〇のステージは××(ステージ名)です

また、ゲームモードの「ガチマッチ」「リーグマッチ」ではルールが3種類あるのでそれも確認できるようにします。

使用ツール・環境

webhookの置き場にherokuを使用し、
前回とは違い、IFTTTは使用せずDialogflowとwebhookのみで実装します。

ステージ情報の取得

現在配信されているステージ情報を取ってきます。
公式アプリから閲覧できるイカリング2からプロキシをごにょごにょして取ってきてもいいんですが、
【スプラトゥーン2】イカリング2の戦績データをPCブラウザで無理矢理閲覧する

世の中には便利なBotを作っている人がいるのでこちらのBotのツイートから取得しようと思います。

ツイート取得機能は応用が効きそうですしね(イカリングからの取得が面倒そうだからという訳では無いです)

twythonをインストール

TwitterAPIを叩くのに今回はtwythonを使います。
初期設定はこちら参照
Twitter REST APIの使い方

どうせ大した事しないのでtwython使うまでも無い気はしますが...
$pip install twython

スクリプトを書きます。

twython.py
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,"ガチマッチ")+"です")

これで、現在のステージ名とガチマッチ・リーグマッチの場合は「ガチホコ」「ガチエリア」「ガチヤグラ」等のゲームモードを出力できるようになりました。

出力例
スクリーンショット 2017-10-16 17.14.47.png

これを後は前回作成したpythonファイルに書き加えればOKです。

webhook-dialogflow.py
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を登録可能です。
スクリーンショット_2017-10-18_22_06_40.png
(成績が前回作成したintent)

今回はユーザーの発言が「ステージ」だった場合にBotが反応し、
「ステージ」の後に続く部分をmodeとして入力で受け取ります。

スクリーンショット 2017-10-16 16.40.24.png
ActionにはgetStageと入力。JSONのこの部分を上記のpythonスクリプトは見て前回のwebhookと分岐させています。
スクリーンショット 2017-10-16 18.06.21.png

Entities

入力として受け取る単語をEntitiesから登録します。
今回もスプラトゥーンのデータベースは無いようなのでポチポチ登録しましょう。
スクリーンショット 2017-10-16 16.40.40.png

Fulfillment

前回と変更点はありません。
webhookを流すurlを入力しておきましょう。
20171012132542.png

これでセッティングは終了です。

テストする

Dialogdlowのコンソール右側にテキストを入力してテストしましょう。
スクリーンショット 2017-10-16 16.40.14.png
ステージが出てきました!
action,parameter valueも問題なさそうですね。

完成

動作の確認はこちらの動画から↓
IMAGE ALT TEXT HERE

おわりに

今回はゲームモードを取得しましたが、先日開催されたフェスやもう1つのゲームモードサーモンランに対応していないのでそこら辺やろうかと思います。
でも別々のTwitterBotから取得するぐらいならイカリングから読み出した方がいい気も…先は長いですね。
スプラトゥーン以外にもTwitterとの連携は便利そうなので使っていきたいです。

良きスプラトゥーンライフを!(フェスは負けました)

参考

16
12
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
12