はじめに

GoogleHomeの方が個人的には好き。
EchoPlus買ったけど、重低音きつくて音楽聴くには向いてない。。。
(しかもSpotify未対応。。。え?いいとこないじゃん。。。)

我が家のEchoは豆しばのスキルしか使っていないので、
何か仕事をさせてあげたいと思い今回よく利用する西鉄バスの到着時刻を教えて貰うスキルを作成しました。

以下をパクらせて頂きました。参考にさせて頂きました。
@osa9さんAmazon Echoにバスの到着時刻を教えて貰う

AWS Lambdaで処理を作成

関数の作成

Lambda>関数の作成
Pythonを使用しているので、値を以下のようにセットし、「関数の作成」を押下(名前は何でもOK)
image.png

トリガーの追加から、「Alexa Skills Kit」を選択、
スキルID検証は「無効」でOK

関数コード

「BUS_SCHEDULE_URL」については、必要な情報に合わせてパラメータ等変更して下さい。
にしてつ時刻表 テキスト版

alexa_bus.py
import logging
import traceback,sys
import urllib.request
from bs4 import BeautifulSoup

# 西鉄バス時刻表(テキスト版)運行状況のURL(サンプルは百年橋 → 博多駅筑紫口)
BUS_SCHEDULE_URL = 'https://jik.nishitetsu.jp/am/route?ftKbn=t&f_list=0001%2C550013&t_list=0000%2CD00209&btnSearchFT=%8C%9F%8D%F5&jkn_busnavi=1'


# 西鉄バスのリアルタイム運行状況を取得する
def get_bus_schedule(url):
    logging.info("Retrieving URL: {}".format(url))
    content = urllib.request.urlopen(url).read().decode('shift_jisx0213')
    soup = BeautifulSoup(content, "html.parser")

    # エラーメッセージがある時(バスが終了している時も含む)
    errors = soup.select('.errorTxt')
    if len(list(errors)) > 0:
        message = errors[0].contents[0]
        logging.warn("Error: ".format(message))
        raise Exception(message)

    # ダイヤをパースする
    result = []
    for bus_info in soup.find_all('form'):
        res = list(map(lambda col: col.string, bus_info.find_all('p')))

        # 取りたくないformが最後にあるので
        if len(res) == 0:
            break

        # スロープでない場合、以下のダミーを要素に追加
        if len(res) == 5:
            res.insert(2,'ダミー')


        info = {
            'scheduled_arrival': res[0].split()[1],  # 乗車 19:08 百年橋
            'bus_stop': res[1],  # [67] 普通  博多駅
            'bus_route': res[3],  # 約5分遅れ 2停前通過
            'destination': res[4],  # 乗り換え0回
            'type': res[5].split()[2]  # 降車 19:19 博多駅筑紫口
        }

        result += [info]

    return result


def bus(event, context):
    logging.info(event)

    # スケジュールを取得してメッセージを組み立てる
    try:
        schedules = get_bus_schedule(BUS_SCHEDULE_URL)
        message = '{}行きのバスは、{}'.format(schedules[0]['type'], schedules[0]['scheduled_arrival'] + schedules[0]['bus_route']) + '。'
        if len(schedules) > 1:
            message += 'その次は、{}'.format(schedules[1]['scheduled_arrival'] + schedules[1]['bus_route']) + '。'
        if len(schedules) > 2:
            message += ' その次は、{}'.format(schedules[2]['scheduled_arrival'] + schedules[2]['bus_route']) + '。'
        if len(schedules) > 3:
            message += ' その次は、{}'.format(schedules[3]['scheduled_arrival'] + schedules[3]['bus_route']) + '。'
    except:
        ex,ms,tb=sys.exc_info()
        message = 'エラー {}'.format(ms)

    logging.info(message)

    response = {
        'version': '1.0',
        'response': {
            'outputSpeech': {
                'type': 'PlainText',
                'text': message,
            }
        }
    }

    return response

# テスト用
if __name__ == '__main__':
    print(bus(None, None))

注意点

上記「alexa_bus.py」では、beautifulsoupを利用し、スクレイピングを行っている為、パッケージを含めた状態で、zipファイルをアップロードする必要があります。
(各パッケージについては、Windows,Macそれぞれ、pythonのディレクトリ内にあるはずです。なければ、pipでパッケージの取得が必要です。)
※zipファイルを作成する際、ディレクトリを圧縮するのではなく、以下赤枠のように対象ファイルを選択し、圧縮する必要があります。
image.png

zipファイルをアップロード>ハンドラを変更>保存
image.png

3.AlexaSkil作成

Amazon開発者ポータルを開きログイン
(※Alexa 開発者アカウント作成時のハマりどころ)

Alexa Skills Kit

個人的には以前のコンソールの方が日本語でわかりやすいですが、今回は新しいコンソールを使ってスキルを作成します。
image.png

スキル名、言語を設定
image.png

とりあえずCustomを選択
image.png

以下赤枠内のチェックリストをそれぞれ設定
image.png

1.Invocation Name>「時刻表」を設定
2.Intents,Samples,and Slotsについては、以下を設定
image.png
image.png
3.Build Model押下にて、Buildが開始されます。
4.EndpointでDefault Regionの欄にLambda関数画面の右上にあるARNを貼り付け
image.png

4.テスト

「時刻表を開いて、次のバスは」と入力すると以下の結果が得られます。
image.png

Echo持っている方は、「有効なスキル」>「DEVスキル」で「西鉄バス時刻表」のスキルを有効にすれば、使えるはずです。
Echo持ってなくてもReverbで確認ができます。

5.最後に

特に詳しいわけでもなく、先駆者の方々を真似て自分用のメモとして書きました。
バス停の指定、日時の指定も、「Alexa スロット」等で検索すれば、作れると思います。。。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.