베이 스타즈가 이기고 있을 때만 응답하고, 지고 있을 때는 찢어지는 Alexa 스킬을 만들었다

소개



제가 걱정했을 무렵, 일본에서 가장 강한 팀은 요코하마 베이 스타즈였습니다.
야수에서는 타니시게, 로즈, 코마타, 스즈키 나오, 투수에서는 미우라, 사이토 타카시, 사사키 등… 그리네요.
역시 아이라고 하는 것은, 강한 팀을 좋아하게 되는 것이고, 그 때 나는 베이스터즈의 팬이 되었습니다.
아시다시피 베이스터스는 그 후 쇠퇴의 일도를 따라가는데요...

최근에는 일도 바쁘고, 베이스타즈의 경기를 보는 것은 적어졌습니다만, 아직도 경기 결과만은 신경이 쓰여져 조금 봐 버립니다.贔屓의 팀이 이기면 기쁩니다.
단지 반대로, 결과를 보고 베이스타즈가 지고 있다고 위장 버립니다. 어쩔 수 없지만.

그런 가운데 어느 날 후라고 생각했습니다.
「베이스터즈가 이길 때만 가르쳐 주면, 기분이 떨어지지 않고 끝나지 말아야…

스킬



베이스터스 속보(비공식)


사용법



■ 이길 때
「베이스 속보를 열고」

알렉사 「현재 7회표입니다. 베이스타즈가 5대 2로 이기고 있습니다!」

■ 잃을 때
「베이스 속보를 열고」

알렉사 「요코하마 F 마리노스의 결과를 조사합니까?」

그렇다면 투수가 불타는 경우 결과를 알지 않고 기분 좋게 하루를 보낼 수 있습니다

구성



Amazon Echo Dot → Alexa → AWS Lambda (Python) → Sportsnavi (프로 야구)

Alexa 스킬은 AWS Lambda에서 Node.js를 사용하여 개발하는 것이 표준이라고 생각하지만, 이번에는 스크래핑에 BeautifulSoup을 사용하고 싶었기 때문에 Python3에서 구현했습니다.

속보 정보는 스포나비 씨 의 데이터를 이용하였습니다.

소스 코드



Alexa 콘솔의 설정은, 공식의 튜토리얼등을 참고해 주시면 좋겠습니다.
이번에는 파이썬 스크립트 만 게시합니다. 템플릿으로 "alexa-skills-kit-color-expert-python"을 이용하여 이 코드를 기반으로 구현했습니다.
이 기사를 쓰고 있을 때에 깨달았습니다만, Alexa Skills Kit SDK for Python의 베타 버전 가 6월에 릴리스 되고 있었던 것 같아, 이쪽을 이용하면 더 코드량을 삭감할 수 있을까 생각합니다.

lambda_function.py
import urllib.request
from bs4 import BeautifulSoup
import random

# --------------- Helpers that build all of the responses ----------------------

def build_speechlet_response(output):
    return {
        'outputSpeech': {
            'type': 'PlainText',
            'text': output
        },
        'card': {
            'type': 'Simple',
            'title': 'ベイスターズ速報',
            'content': output
        },
        'reprompt': {
            'outputSpeech': {
                'type': 'PlainText',
                'text': None
            }
        },
        'shouldEndSession': True
    }

def build_response(speechlet_response):
    return {
        'version': '1.0',
        'sessionAttributes': {},
        'response': speechlet_response
    }

# --------------- Functions that control the skill's behavior ------------------

def get_baystars_result():
    lose_text_list = ["今日はいい天気ですね","横浜Fマリノスの結果をお調べですか?","他人を応援するより自分が頑張ったほうが楽しいですよ","大魔神は今、馬ぬしをやっているそうです"]

    html = urllib.request.urlopen('https://baseball.yahoo.co.jp/npb/schedule/').read()
    soup = BeautifulSoup(html, 'html.parser')


    #ベイスターズが含まれる対戦テーブルを取得
    #無い場合は試合無しと判断
    if soup.find(class_="yjMS",text="DeNA") == None:
        speech_output = "今日は試合が無いようです"
        return build_response(build_speechlet_response(speech_output))
    else:
        table = soup.find(class_="yjMS",text="DeNA").parent.parent

    #表の上のチーム:a,下のチーム:b
    team_a = table.select('.yjMS')[0].a.string
    team_b = table.select('.yjMS')[1].a.string

    team_a_score = table.select('.score_r')[0].string
    team_b_score = table.select('.score_r')[1].string

    game_status = table.select('.yjMSt')[0].string
    if game_status == "結果":
        lead_text = "試合終了!"
    elif game_status == "中止":
        lead_text = "試合は" + game_status + "になりました"
    else:
        lead_text = "現在" + game_status + "です"

    if game_status == "試合前" or game_status == "中止":
        speech_output = lead_text
    elif team_a == "DeNA" and int(team_a_score) > int(team_b_score):
        speech_output = lead_text + "ベイスターズは" + team_a_score + "対" + team_b_score + "で勝っています!" 
    elif team_b == "DeNA" and int(team_b_score) > int(team_a_score):
        speech_output = lead_text + "ベイスターズは" + team_b_score + "対" + team_a_score + "で勝っています!" 
    else:
        speech_output = random.choice(lose_text_list)

    return build_response(build_speechlet_response(speech_output))


def handle_session_end_request():
    speech_output = "Bye"
    return build_response(build_speechlet_response(speech_output))

# --------------- Events ------------------

def on_launch(launch_request):
    return get_baystars_result()

def on_intent(intent_request):
    intent_name = intent_request['intent']['name']

    if intent_name == "ResultIntent":
        return get_baystars_result()
    elif intent_name == "AMAZON.HelpIntent":
        return get_baystars_result()
    elif intent_name == "AMAZON.CancelIntent" or intent_name == "AMAZON.StopIntent":
        return handle_session_end_request()
    else:
        raise ValueError("Invalid intent")

# --------------- Main handler ------------------

def lambda_handler(event, context):
    if event['request']['type'] == "LaunchRequest":
        return on_launch(event['request'])
    elif event['request']['type'] == "IntentRequest":
        return on_intent(event['request'])
    elif event['request']['type'] == "SessionEndedRequest":
        return on_session_ended(event['request'])


심사에 대해서



당초 「베이스터즈 속보」로 심사 제출했습니다만, 팀으로부터 승인을 얻지 않았다고 심사를 통과하지 말라고 했으므로, 「(비공식)」을 덧붙였습니다. 스킬 상세에 대해서도 마찬가지이며, 비공식이라는 취지를 썼습니다.

또 호출명에 대해서는, 「베이스터즈」의 워드는 사용하지 않게 지적이 있었기 때문에, 「베이스 속보」로 했습니다.

1. 비공식임을 명기한다.
2. 호출명에 고유명사를 사용하지 않는다
2 점을 지키면 심사가 돌파 될 수 있습니다

결론



기사를 보고 조금이라도 재미있는, 참고가 된다고 생각하면, 좋아 버튼을 눌러 주실 수 있으면 다행입니다.
또한 구현에 대한 더 나은 방법이 있다면 의견을 주시면 도움이 될 것입니다

그 외 여러가지 기사를 쓰고 있으므로, 흥미가 있는 분은 꼭!
AI가 선택한 정말 비슷한 유명인 톱 10

좋은 웹페이지 즐겨찾기