You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于NodeJS+Lambda的Alexa技能分页询问功能实现求助

Hey there! Let's figure out how to add pagination to your Alexa skill—this is such a common use case, and I’ve helped a few folks get this working with Node.js and Lambda before. Here’s a straightforward, step-by-step guide tailored to your setup:

1. Track Conversation State with Session Attributes

Since Lambda functions are stateless (they don’t retain data between calls), we need to store two key pieces of info for the conversation:

  • The full array of data from your API
  • The index of the last item we’ve already spoken

Alexa’s Session Attributes are perfect for this—they act as temporary storage for the current user session. We’ll update these attributes as we paginate through the data.

2. Modify Your Intent Handlers

We’ll need three core handlers:

  • Your original data-fetching intent (to start the flow)
  • A handler for when the user says "Yes" (to get the next batch)
  • A handler for when the user says "No" (to end the session)

Example Code for Handlers

First, your main data intent handler (starts the flow):

const FetchDataIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'YourDataIntentName';
    },
    async handle(handlerInput) {
        // 1. Fetch your data from the API
        const fullDataArray = await fetchYourApiData(); // Replace with your actual API call
        
        // 2. Store data and initial index in session attributes
        const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
        sessionAttributes.fullData = fullDataArray;
        sessionAttributes.currentIndex = 10; // We'll speak items 0-9 first
        
        // 3. Build speech for the first 10 items
        const firstBatchSpeech = fullDataArray.slice(0, 10)
            .map((item, idx) => `${idx + 1}. ${item.yourDataField}`) // Replace with your data's display field
            .join(' ');
        
        // 4. Add the follow-up question and keep the session open
        const speechOutput = `${firstBatchSpeech} Would you like to hear the next 10 items?`;
        const repromptText = "I didn't catch that—would you like to hear the next 10 items?";
        
        handlerInput.attributesManager.setSessionAttributes(sessionAttributes);
        
        return handlerInput.responseBuilder
            .speak(speechOutput)
            .reprompt(repromptText)
            .withShouldEndSession(false) // Critical: keeps the session alive for user input
            .getResponse();
    }
};

Next, the handler for when the user says "Yes":

const AmazonYesIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.YesIntent';
    },
    handle(handlerInput) {
        const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
        const { fullData, currentIndex } = sessionAttributes;
        
        // Check if there are any items left to speak
        if (currentIndex >= fullData.length) {
            return handlerInput.responseBuilder
                .speak("There are no more items to share. Thanks for using the skill!")
                .withShouldEndSession(true)
                .getResponse();
        }
        
        // Get the next batch of up to 10 items
        const nextBatch = fullData.slice(currentIndex, currentIndex + 10);
        const nextBatchSpeech = nextBatch
            .map((item, idx) => `${currentIndex + idx + 1}. ${item.yourDataField}`)
            .join(' ');
        
        // Update the current index for next time
        sessionAttributes.currentIndex += 10;
        handlerInput.attributesManager.setSessionAttributes(sessionAttributes);
        
        // Build the response (with follow-up if more items exist)
        let speechOutput, repromptText;
        if (sessionAttributes.currentIndex < fullData.length) {
            repromptText = "Would you like to hear the next 10 items?";
            speechOutput = `${nextBatchSpeech} ${repromptText}`;
        } else {
            speechOutput = `${nextBatchSpeech} That's all the items we have. Thanks for listening!`;
        }
        
        return handlerInput.responseBuilder
            .speak(speechOutput)
            .reprompt(repromptText || "")
            .withShouldEndSession(sessionAttributes.currentIndex >= fullData.length)
            .getResponse();
    }
};

Finally, the handler for when the user says "No":

const AmazonNoIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.NoIntent';
    },
    handle(handlerInput) {
        return handlerInput.responseBuilder
            .speak("Alright, thanks for using the skill! Have a great day.")
            .withShouldEndSession(true)
            .getResponse();
    }
};
3. Critical Skill Console Setup

Don’t forget to enable the built-in intents in your Alexa Developer Console:

  1. Go to your skill’s Interaction Model > Intents
  2. Click Add Intent > select Use an existing intent from Alexa’s built-in library
  3. Search for and add AMAZON.YesIntent and AMAZON.NoIntent
  4. Save and build your model (this is mandatory for the intents to work)
4. Troubleshooting Tips
  • Session ends unexpectedly? Double-check that withShouldEndSession(false) is set when you’re waiting for user input.
  • Data not persisting between calls? Make sure you’re calling handlerInput.attributesManager.setSessionAttributes(sessionAttributes) after updating the attributes.
  • Built-in intents not triggering? Confirm you’ve added them to your interaction model and deployed the updated model to your development environment.

内容的提问来源于stack exchange,提问作者Yannick Borschneck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:36:31