question

Mr H Speight avatar image
Mr H Speight asked

Dynamic SpeakItem in pager

I am having a problem trying to generate a SpeakItem at run time.

The transformer SSML input needs to be generated randomly from a list of questions so is not known when the document is rendered.

My idea was to use SetValue to update the inputPath's SSML however it does not overwrite the value set when the document is rendered.

Setting the text property works fine but the updated value is not converted to SSML.

My logic flow should be

Say and display a randomly generated question

Accept the user's answer

Say and dispay the correct/incorrect response followed by the next randomly generated question


{
    "type": "APL",
    "version": "1.6",
    "onMount": [],
    "mainTemplate": {
        "parameters": [
            "quiz"
        ],
        "item": {
            "type": "Container",
            "id": "topContainer",
            "width": "100%",
            "height": "100%",
            "items": [
                {
                    "type": "Pager",
                    "navigation": "wrap",
                    "id": "quizPager",
                    "height": "100%",
                    "width": "100%",
                    "data": "${quiz.properties.pagerData}",
                    "items": {
                        "type": "Container",
                        "direction": "row",
                        "id": "quizPageContainer",
                        "width": "100%",
                        "height": "100%",
                        "alignItems": "center",
                        "items": [
                            {
                                "type": "Text",
                                "id": "${data.id}",
                                "text": "${data.text}",
                                "speech": "${data.textSpeech}",
                                "width": "100%",
                                "fontSize": 80,
                                "textAlign": "center"
                            }
                        ]
                    }
                }
            ]
        }
    }
}
  
                 
{
    "quiz": {
        "type": "object",
        "properties": {
            "pagerData": [
                {
                    "text": "Question one",
                    "id": "Q1",
                    "pageText": "<speak>This is question one.</speak>"
                },
                {
                    "text": "Question two",
                    "id": "Q2",
                    "pageText": "<speak>And this is question two.</speak>"
                }
            ]
        },
        "transformers": [
            {
                "inputPath": "pagerData[*].pageText",
                "outputName": "textSpeech",
                "transformer": "ssmlToSpeech"
            }
        ]
    }
}
  
                 


I know this can be achieved using RenderDocument but my aim is to provide a smoother visual experience.

apl
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Andy Whitworth avatar image
Andy Whitworth answered

Why can't you select the random question list at the time you render the APL doc ?

10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Mr H Speight avatar image
Mr H Speight answered

That's a possibility but I current have around 800 questions in a database which would be updated with new content periodically.

1 comment
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Andy Whitworth avatar image Andy Whitworth commented ·

Yes, but your code just selects the questions and passes them as a datasource with the static APL document as part of the RenderDocument directive.

https://developer.amazon.com/en-US/docs/alexa/alexa-presentation-language/apl-data-source.html#bind-a-dynamic-data-source-to-your-apl-document

When you return the RenderDocument directive you can supply the datasource as a separate parameter to the APL document. So the datasource can be dynamic and referenced in the static APL.

handlerInput.responseBuilder.addDirective({
                    type: 'Alexa.Presentation.APL.RenderDocument',
                    token: 'yourtoken',
                    document: yourQuizQuestionsAPLDoc,
                    datasources: {
                        // Dynamic quiz questions, selected from database 
                        questions: [{
                            question: 'quiz question 1'
                        },
                        {
                            question: 'quiz question 2'
                        },
                        {
                            question: 'quiz question 3'
                        },
                        //// etc
                        ]}
                });


0 Likes 0 ·
Mr H Speight avatar image
Mr H Speight answered

To make things more natural sounding I was hoping to speak the result of question 1 before asking question 2.

e.g. "That's correct. Question two is ..." or "No that's the wrong answer. The correct answer is blue. Question two is ..."

As said using ExecuteCommands I can display the response on the page but don't know how to get SpeakItem to say the words.

This what I have for the ExecuteCommands directive

.addDirective({type: 'Alexa.Presentation.APL.ExecuteCommands',

            token: token,
            commands:      

                {

                    "type": "SetValue
                    "componentId": "Q2
                    "property": "text
                    "value": "Correct Answer"

                },

                {

                    "type": "SetValue
                    "componentId": "Q2
                    "property": "pageText
                    "value": "<speak>That is correct. Next question is</speak>"

                },

                {

                    "type": "SpeakItem
                    "componentId": "Q2"

                }

            ]})


According to the documentation here speakitem only works on the output of a transformer.

I'm guessing that after the document is rendered the property becomes immutable so cannot be updated with SetValue.

10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Mr H Speight avatar image
Mr H Speight answered

I was able to achieve this using SendEvent

10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.