【问题标题】:Why does this Alexa custom skill's Lambda in Nodejs doesnt work (Alexa doesnt speak, times out)为什么这个 Alexa 自定义技能 Lambda in Node Js 不起作用(Alexa 不说话,超时)
【发布时间】:2019-12-27 10:13:51
【问题描述】:

我必须在 Intent 匹配时向我的 mqtt 代理发布一条 MQTT 消息,以下是无法按预期工作的代码。

var mqtt = require('mqtt-async');

function sendMQTTMessage(json)
{
    if(!client || !client.connected)
    {
        console.log('found mqtt client to be not connected');
        if(client)client.end();

        var options = {
        username: 'uname',
        password: 'pass',
        rejectUnauthorized: false,
        clean: true
        };

        client = mqtt.connect('mqtts://ip:8883',options);
        client.on('connect', () => {
            client.publish('alexaIntentMatch', JSON.stringify(json));
            console.log('sent');
        });
    }
    else//publish now
    {
        client.publish('alexaIntentMatch', JSON.stringify(json));
        console.log('sent');
    }
}
const ItineraryIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'itinerary';
    },
    handle(handlerInput) {
        var res = {'intentName':'ITENARY'};
        sendMQTTMessage(res);
        return handlerInput.responseBuilder.speak('You asked for ITENARY').getResponse();}
};

发生的情况是,当消息成功发送到 mqtt 代理时,Alexa 不说话(可以在 cloudwatch 中看到请求在 8 多秒后超时)。

Task timed out after 8.01 seconds

虽然这段代码工作得很好,

const ItineraryIntentHandler = {
canHandle(handlerInput) {
    return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
        && Alexa.getIntentName(handlerInput.requestEnvelope) === 'itinerary';
},
handle(handlerInput) {let userID = handlerInput.requestEnvelope.context.System.user.userId;
    let client = mqtt.connect('mqtts://ip:8883',{
    username: 'uname',
    password: 'pass',
    rejectUnauthorized: false,
    clean: true
    });
    client.on('connect', () => {
        var res = {'intentName':'ITENARY'};
        client.publish('alexaIntentMatch', JSON.stringify(res));
        console.log('worked');
        client.end();
    });
    return handlerInput.responseBuilder.speak("Today's itinerary is displayed on your TV.").getResponse();}};

这里有什么愚蠢的地方漏掉了。

【问题讨论】:

    标签: node.js aws-lambda alexa alexa-skills-kit alexa-skill


    【解决方案1】:

    尝试添加asyncawait

    var mqtt = require('mqtt-async');
    
    async function sendMQTTMessage(json)
    {
        if(!client || !client.connected)
        {
            console.log('found mqtt client to be not connected');
            if(client)client.end();
    
            var options = {
            username: 'uname',
            password: 'pass',
            rejectUnauthorized: false,
            clean: true
            };
    
            client = mqtt.connect('mqtts://ip:8883',options);
            client.on('connect', () => {
                await client.publish('alexaIntentMatch', JSON.stringify(json));
                console.log('sent');
            });
        }
        else//publish now
        {
            await client.publish('alexaIntentMatch', JSON.stringify(json));
            console.log('sent');
        }
    }
    const ItineraryIntentHandler = {
        canHandle(handlerInput) {
            return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
                && Alexa.getIntentName(handlerInput.requestEnvelope) === 'itinerary';
        },
        async handle(handlerInput) {
            var res = {'intentName':'ITENARY'};
            await sendMQTTMessage(res);
            return handlerInput.responseBuilder.speak('You asked for ITENARY').getResponse();}
    };
    

    【讨论】:

    • 对不起,回复晚了,我已经尝试过类似的方法,但都不起作用。只是上面提到的一个有效,似乎无法弄清楚为什么
    • 这是因为 JS 不会等待 Promise(connecting to mqtt) 完成,它会直接调用 Alexa 的 handlerInput.responseBuilder.speak 请求。所以通过在任何地方添加asyncawait,你说JS完成这个承诺,然后只进行下一条指令。
    • 您可以在这里了解 JS 同步、异步的工作原理 - medium.com/better-programming/…
    • 明白了,但是如何让alexa不说出handlerInput.responseBuilder.speak中发送给它的文本,它是一个静态文本
    • 如果它是静态的并且与 Promise 无关,那么它应该可以工作。尝试删除所有 Promise 代码并使用像 github.com/alexa/skill-sample-nodejs-hello-world/blob/master/… 这样的 vanilla 请求。从第 18 行到第 30 行。
    猜你喜欢
    • 1970-01-01
    • 2018-11-04
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多