APL 버튼 클릭시 이벤트

15828 단어 AlexaSkillsKitAPL

이 기사의 목표



버튼을 누르면 말하기

전제



APL 이미지 표시

APL v1.7

할 일



TouchWrapper 을 사용하여 터치 이벤트를 발화합니다.

TouchWrapper란?



자식 요소가 터치되면 onPress 명령을 보내는 구성 요소

버튼 배치





소재는 이것



        "items": [
            {
                "items": [
                    {
                        "type": "TouchWrapper",
                        "items": [
                            {
                                "source": "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/bad9d928-77b7-c399-c316-49eb6329cda9.png",
                                "type": "Image",
                                "width": "241",
                                "height": "65"
                            }
                        ]
                    }
                ],
                "alignItems": "center",
                "justifyContent": "center",
                "type": "Container"
            }
        ]

버튼 터치를 감지하여 서버로 전송



SendEvent

onPress되면 SendEvent 명령을 실행하여 서버에 버튼이 터치되었음을 알립니다.

쓰는 방법은 샘플이 매우 참고가 된다.
{
  "type": "TouchWrapper",
  "id": "idForTheTouchWrapper",
...
  "onPress": [
    {
      "type": "SendEvent",
      "arguments": [
        "textWasPressed",
        "このデータをスキルに送信する"
      ],
      "components": [
        "idForTheTextComponent"
      ]
    }
  ],
...
}

arguments에 관해서는 버튼을 검지하는 것만이라면 불필요하므로 쓰지 않는다. (기본 [])
components도 우선 불필요.
또, 서버에 어느 버튼이 눌려졌는지를 전하기 위해서 TouchWrapper 에 고유의 ID를 붙인다.


                        "type": "TouchWrapper",
                        "id": "startButton",
                        "onPress": [
                            {
                                "type": "SendEvent"
                            }
                        ]

onPress의 부분은 APL의 부분에 곧 쓴다. (길기 때문에)

Handler 쓰기



Alexa에서 보낸 요청 처리
에 handler 쓰는 법이 쓰여져 있다.

// (1)
const isButtonPress = (requestEnvelope, componentId) => {
    const source = requestEnvelope.request.source
    return Alexa.getRequestType(requestEnvelope) === 'Alexa.Presentation.APL.UserEvent'
        && source.handler === 'Press'
        && source.id === componentId;
};

// (2)
const StartButtonHandler = {
    canHandle(handlerInput) { // (2.1)
        return isButtonPress(handlerInput.requestEnvelope, 'startButton');
    },
    handle(handlerInput) { // (2.2)
        const speakOutput = 'ボタンが押されました';
        return handlerInput.responseBuilder
            .speak(speakOutput)
            .getResponse();
    }
}
...

// (3)
exports.handler = Alexa.SkillBuilders.custom()
    .addRequestHandlers(
        LaunchRequestHandler,
        HelloWorldIntentHandler,
        StartButtonHandler,
...

(2) Handler의 기입 방법의 구조는, 제1 인수(2.1)에 「실행할지 어떨지」, 제2 인수(2.2)에 「실행하는 처리」를 쓴다.
이번 「실행할지 어떨지」는 「id가 startButton의 TouchWrapper로부터 SendEvent가 보내져 오면」이다.
그렇다면 어떻게 데이터가 전송되는지.
SendEvent 문서에는 다음과 같이 작성됩니다.

기술에 Alexa.Presentation.APL.UserEvent 요청을 보냅니다.

UserEvent 요청

UserEvent 요청 처리

이 근처에 방법이 쓰여 있다.

그래서 실제로 오는 데이터는 다음과 같습니다.

    "event": {
        "header": {
            "namespace": "Alexa.Presentation.APL",
            "name": "UserEvent",
            "messageId": "messageId",
            "dialogRequestId": "b63a281e-36f3-47c1-bf27-3140e53ff84b"
        },
        "payload": {
            "presentationToken": "amzn1.as-tt.v1.ThirdPartySdkSpeechlet#TID#amzn1.ask.skill.ce32fc86-b796-4238-9496-537069c1ccec::",
            "arguments": [],
            "source": {
                "type": "TouchWrapper",
                "handler": "Press",
                "id": "startButton"
            },
            "components": {},
            "dialogRequestId": "b63a281e-36f3-47c1-bf27-3140e53ff84b"
        }
    },
    "context": [
...
}
handlerInput.requestEnvelope.request 에서 위 요청의 payload그리고는 source.handler 로 터치 이벤트인가, source.id 로 무엇이 터치되었는지를 판단하고 있다. (1)

(3) Handler는 addRequestHandlers에 등록할 필요가 있으므로 이것을 잊지 않도록 한다.

기타 문서
Processing-Request
getRequestType

참고

좋은 웹페이지 즐겨찾기