簡體   English   中英

Alexa Skill:是否可以讓 Alexa 從 Alexa Developer Console - Alexa Hosted 播放 .mp3?

[英]Alexa Skill: is it possible to have Alexa play a .mp3 from Alexa Developer Console - Alexa Hosted?

我正在嘗試為 Alexa 創建一項技能,根據我選擇的 tg 的類別重現 .mp3 文件。 我聲明我從未使用過node.js並且我看過一門關於如何創建 alexa 技能的課程。 到目前為止,我已經創建了該技能的框架,並創建了一個database.json文件,其中包含各種帶有附加鏈接的新聞類別。

索引文件

const Alexa = require('ask-sdk-core');
const database = require('./database'); 

function getCategoryStreamUrl(name) { 
    let category = database.find(e => e.name === name);
    if (category !== null && category !== undefined) {
        return category.StreamUrl;
    } else {
        return "";
    }
}

function getCategoryUpdateDate(name) { 
    let category = database.find(e => e.name === name);
    if (category !== null && category !== undefined) {
        return category.UpdateDate;
    } else {
        return "";
    }
}

const LaunchRequestHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
    },
    handle(handlerInput) {
        const speakOutput = 'Welcome, with this skill you can listen to our TG. You can choose a category or say Help.';
        const repromptOutput = 'You can choose a category or say Help. What do you want to do?'
        return handlerInput.responseBuilder
            .speak(speakOutput)
            .reprompt(repromptOutput)
            .getResponse();
    }
};
const ScegliCategoriaIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'ScegliCategoriaIntent';
    },
    handle(handlerInput) {
        const speakOutput = 'The TGs available are: Political, Lazio, Environment, Health, School, Pediatrics, Rehabilitation, Agriculture, Psychology and Youth. Which do you want to hear?'
        return handlerInput.responseBuilder
            .speak(speakOutput)
            .reprompt(repromptOutput)
            .getResponse();
    }
};
 const CategoriaIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'CategoriaIntent';
    },
    handle(handlerInput) {
        const filledSlots = handlerInput.requestEnvelope.request.intent.slots;
        const slotValues = getSlotValues(filledSlots);

        console.log("CategoriaIntentHandler >>>>>>>>>>>>>>>>");
        console.log(slotValues);

        const categoryName = slotValues["category"].synonym
        const categoryStreamUrl = getCategoryStreamUrl(categoryName);
        const categoryUpdateDate = getCategoryUpdateDate(categoryName);

        var speakOutput = "";
        if (categoryStreamUrl !== "") {
            speakOutput = "You have chosen the TG " + categoryName + ". The TG was updated on " + categoryUpdateDate + ". " + categoryStreamUrl + ". If you want to hear other news, name another TG or you can say STOP to close this skill.";
        } else {
            speakOutput = "I'm sorry, the selected TG is not available. You can say the name of another TG or 'categories' to hear the list of available categories. What do you want to do?";
        }

        return handlerInput.responseBuilder
            .speak(speakOutput)
            .reprompt("If you want to hear more news, say the name of another TG. You can say 'categories' to listen to the list of available categories or you can say STOP to close this skill. What do you want to do?")
            .getResponse();
    }
};
const HelpIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.HelpIntent';
    },
    handle(handlerInput) {
        const speakOutput = "You can say 'categories' to listen to the list of available categories or you can say STOP to close this skill. What do you want to do?";
        const repromptOutput = "If you want to stop listening, say STOP."

        return handlerInput.responseBuilder
            .speak(speakOutput)
            .reprompt(repromptOutput)
            .getResponse();
    }
};
const CancelAndStopIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && (Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.CancelIntent'
                || Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.StopIntent');
    },
    handle(handlerInput) {
        const speakOutput = "Goodbye!";
        return handlerInput.responseBuilder
            .speak(speakOutput)
            .getResponse();
    }
};
const SessionEndedRequestHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'SessionEndedRequest';
    },
    handle(handlerInput) {
        // Any cleanup logic goes here.
        return handlerInput.responseBuilder.getResponse();
    }
};

// The intent reflector is used for interaction model testing and debugging.
// It will simply repeat the intent the user said. You can create custom handlers
// for your intents by defining them above, then also adding them to the request
// handler chain below.
const IntentReflectorHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest';
    },
    handle(handlerInput) {
        const intentName = Alexa.getIntentName(handlerInput.requestEnvelope);
        const speakOutput = `You just triggered ${intentName}`;

        return handlerInput.responseBuilder
            .speak(speakOutput)
            //.reprompt('add a reprompt if you want to keep the session open for the user to respond')
            .getResponse();
    }
};

// Generic error handling to capture any syntax or routing errors. If you receive an error
// stating the request handler chain is not found, you have not implemented a handler for
// the intent being invoked or included it in the skill builder below.
const ErrorHandler = {
    canHandle() {
        return true;
    },
    handle(handlerInput, error) {
        console.log(`~~~~ Error handled: ${error.stack}`);
        const speakOutput = `I'm sorry I did not understand. Say 'Help' to know the available commands.`;

        return handlerInput.responseBuilder
            .speak(speakOutput)
            .reprompt(speakOutput)
            .getResponse();
    }
};

function getSlotValues (filledSlots) {

    let slotValues = {}; //

    console.log('The filled slots: ' + JSON.stringify(filledSlots));
    Object.keys(filledSlots).forEach(function(item) {

    var name = filledSlots[item].name;

    if(filledSlots[item]&&
        filledSlots[item].resolutions &&
        filledSlots[item].resolutions.resolutionsPerAuthority[0] &&
        filledSlots[item].resolutions.resolutionsPerAuthority[0].status &&
        filledSlots[item].resolutions.resolutionsPerAuthority[0].status.code ) {

        switch (filledSlots[item].resolutions.resolutionsPerAuthority[0].status.code) {
            case "ER_SUCCESS_MATCH": 
                slotValues[name] = {
                    "synonym": filledSlots[item].value,
                    "resolved": filledSlots[item].resolutions.resolutionsPerAuthority[0].values[0].value.name,
                    "isValidated": true
                };
                break;
            case "ER_SUCCESS_NO_MATCH": 
                slotValues[name] = {
                    "synonym": filledSlots[item].value,
                    "resolved": filledSlots[item].value,
                    "isValidated":false
                };
                break;
            }
        } else { 
            slotValues[name] = {
                "synonym": filledSlots[item].value,
                "resolved": filledSlots[item].value,
                "isValidated": false
            };
        }
    },this);
    return slotValues;
}

// The SkillBuilder acts as the entry point for your skill, routing all request and response
// payloads to the handlers above. Make sure any new handlers or interceptors you've
// defined are included below. The order matters - they're processed top to bottom.
exports.handler = Alexa.SkillBuilders.custom()
    .addRequestHandlers(
        LaunchRequestHandler,
        ScegliCategoriaIntentHandler,
        CategoriaIntentHandler,
        HelpIntentHandler,
        CancelAndStopIntentHandler,
        SessionEndedRequestHandler,
        IntentReflectorHandler, // make sure IntentReflectorHandler is last so it doesn't override your custom intent handlers
    )
    .addErrorHandlers(
        ErrorHandler,
    )
    .lambda();

數據庫.JSON

[
    {
        "uid":"ID",
        "updateDate": "DATA",
        "name": "NAME SLOT",
        "titleText": "TG 01",
        "mainText":"",
        "streamUrl":"https://www.mysite.it/tg.mp3",
        "redirectionUrl":"https://www.mysite.it/category/tg"
          },
    {
        etc_01
        },
{
        etc_02
        },
{
        etc_03
        },
]

問題是現在它不起作用了,事實上當我讓 alexa 告訴我TG 01她告訴我:

“你選擇了TG 01。TG更新為undefined。Undefined。另一個TG或者你可以說STOP關閉這個技能。”

簡而言之,它不識別categoryUpdateDatecategoryStreamUrl

我該怎么做才能修復它?

您在兩個函數中都返回了錯誤的數據:

它們應該是: category.updateDatecategory.streamUrl ,因為您正在讀取 JSON 文件。 (也許閱讀本指南以更好地了解如何讀取和訪問 JSON 屬性等..)

function getCategoryStreamUrl(name) { 
    let category = database.find(e => e.name === name);
    if (category !== null && category !== undefined) {
        return category.streamUrl;
    } else {
        return "";
    }
}

function getCategoryUpdateDate(name) { 
    let category = database.find(e => e.name === name);
    if (category !== null && category !== undefined) {
        return category.updateDate;
    } else {
        return "";
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM