Claudia.js文本回复和Alexa

时间:2017-04-18 15:28:22

标签: node.js aws-lambda chatbot alexa claudia.js

我正在研究Claudia.js机器人,可以通过Slack,FB信使和Alexa技能联系到。据说在claudia中,你可以返回纯文本,框架会正确地将它返回到“前端”......我目前在这里使用FB和Slack可以正常工作,但是当我通过Alexa“服务模拟器”访问它时我总是得到“答复无效”。这是使用Claudia.js的lambda。基本上它从客户端获取消息,然后将它们分流到另一个是“AI”的Lambda。 Alexa似乎在第67行窒息。想法?

const promiseDelay = require('promise-delay');
// const aws = require('aws-sdk');
// const lambda = new aws.Lambda();
const lambda = require('aws-lambda-invoke');

const botBuilder = require('claudia-bot-builder');

const stackTrace = require('stack-trace');

//const slackDelayedReply = botBuilder.slackDelayedReply;
const getIntentName = alexaPayload =>
    alexaPayload &&
    alexaPayload.request &&
    alexaPayload.request.type === 'IntentRequest' &&
    alexaPayload.request.intent &&
    alexaPayload.request.intent.name;


const api = botBuilder((message, apiRequest) => {
  console.log = console.log.bind(null, '[LOG]');
  console.info = console.info.bind(null, '[INFO]');
  console.error = console.error.bind(null, '[ERROR]');
  console.warn = console.warn.bind(null, '[WARN]');

  console.info(message, apiRequest);
  console.log(apiRequest.body);

  const requestData = {
    'user-id': {
      type: message.type,
      ID: message.sender
    },
    epoch: 1484771343.01,
    'payload-type': 'luis',
    facets: {},
    utterance: 'Seek Showtimes',
    payload: {
      query: 'Seek Showtime',
      topScoringIntent: {
        intent: 'SeekShowtime',
        score: 1.0
      },
      intents: [{
        intent: 'SeekShowtime',
        score: 1
      }],
      entities: []
    }
  };
  if (message.text) {
    return new Promise((resolve, reject) => {
      lambda.raw.invoke({
        FunctionName: 'ca2',
        Payload: JSON.stringify(requestData),
      }, (err, done) => {
        if (err) {
          const trace = stackTrace.parse(err);
          console.warn(err);
          console.error(trace);
          return reject(err);
        }
        resolve(done);
      });
    }).then((result) => { // the initial response
      const payload = JSON.parse(result.Payload);
      console.log(payload.utterance);
      return payload.utterance;
    }).catch((error) => {
      const trace = stackTrace.parse(error);
      console.warn(error);
      console.error(trace);
      return 'Could not setup';
    });
  } else if (getIntentName(apiRequest.body) === 'ExitApp') {
    return {
      response: {
        outputSpeech: {
          type: 'PlainText',
          text: 'Bye from Bot!'
        },
        shouldEndSession: true
      }
    };
  } else {
    return {};
  }
},
{ platforms: ['facebook', 'slackSlashCommand', 'alexa'] }
);

module.exports = api;

更新 - 即使我对纯文本字符串响应进行硬编码或使用Alexa Message Builder我仍然会收到“响应无效”。因为服务响应回来了“未定义。”

查看日志,一旦返回响应(由botBuilder进行解析并传递给Alexa),就会出现此错误[TypeError: Cannot read property 'replace' of undefined]

另一个更新:

如果我用{/ p>之类的内容替换return payload.utterance

if (type === 'alexa-skill') {
        Console.warn('trying to contact alexa');
        return "Hi from Alexa";
      }

问题仍然存在。

这是Json请求的来源,没问题:

2017-04-27T18:06:30.552Z    3d70c273-2b74-11e7-a1c8-bf3fec00cbff    STORE Map { "user-id": Map { "type": "alexa-skill", "ID": "amzn1.ask.account.AF6FUNJDSHGCXPVSAO5HUSRYFBD3SPCJJLILC4HLPS3K3L4AOWIMXPS4ZDDCXQ3ZVIV5L4FOMYD23PWZXEIAKYQBVXIQTPE2WW2PMBIXQIY3TUATXADCVNYO7NYUR2B45EU5GRIWBFHQIPLQVDQZMXD7IYVGTKAV3OWPHROCPR7XIUGNSJEAGQZJOMULSKT5HYSNUNJONASE34Y" }, "epoch": 1484771343.01, "payload-type": "luis", "utterance": "when is Logan playing", "payload": Map { "query": "when is Logan playing" } }

这是我从另一个lambda(有效载荷)回来的响应:

017-04-27T18:06:32.513Z 3d70c273-2b74-11e7-a1c8-bf3fec00cbff    [LOG] mnlpData { StatusCode: 200,
Payload: '{"utterance": "To find movies playing near you, I need to know where you are. Please tell me your zip code.", "AskLocation": 1, "context": {"updated": 1493316392.162429, "user_id": "TEST_ID_TUES_14", "sessions": [{"intents": ["SeekShowtime", "SeekShowtime"], "facet-delta": {}, "facets": {"ity.location": {"ity.zip": "", "ity.code": "", "ity.theatre-name": ""}, "ity.movie": {"ity.title": "", "ity.code": ""}, "ity.time": [], "ity.date": []}, "modes": ["", "SHOWTIME_SWITCH", "AskLocation", "SHOWTIME_SWITCH", "AskLocation"]}], "created": 1493316379.950335, "mode_process_count": 2, "user-id": {"type": "alexa-skill", "ID": "amzn1.ask.account.AF6FUNJDSHGCXPVSAO5HUSRYFBD3SPCJJLILC4HLPS3K3L4AOWIMXPS4ZDDCXQ3ZVIV5L4FOMYD23PWZXEIAKYQBVXIQTPE2WW2PMBIXQIY3TUATXADCVNYO7NYUR2B45EU5GRIWBFHQIPLQVDQZMXD7IYVGTKAV3OWPHROCPR7XIUGNSJEAGQZJOMULSKT5HYSNUNJONASE34Y"}, "utterance": ["To find movies playing near you, I need to know where you are. Please tell me your zip code."]}}' }

然后:

2017-04-27T18:06:32.514Z    3d70c273-2b74-11e7-a1c8-bf3fec00cbff    [WARN] trying to contact alexa

然后是错误:

2017-04-27T18:06:32.514Z    3d70c273-2b74-11e7-a1c8-bf3fec00cbff    [TypeError: Cannot read property 'replace' of undefined]

2 个答案:

答案 0 :(得分:1)

如果您还没有,请运行claudia update --configure-alexa-skill并输入您的机器人名称,然后使用它在您的alexa技能构建器设置中提供的URL。选择HTTPS而不是lambda arn。

目前,message.text作为空字符串传递,这意味着没有任何日志块被触发,并且您在代码的最底部返回一个空对象。通过用字符串替换那个空对象来自己测试,alexa测试员不再抱怨。

那么为什么message.text是一个空字符串? Claudia js通过连接为您的意图填充的所有插槽来填充文本字段。如果你的意图没有插槽,那么克劳迪娅会传递一个空字符串。

为您的意图添加插槽,确保已配置技能,并修复逻辑语句问题。

答案 1 :(得分:1)

首先,如果您注意到从另一个lambda发送给您的有效负载,您可以看到utterance是一个数组,因此您可能必须传递第一个元素(如果存在)。

通过查看机器人构建器的代码,我最好的选择是,您获得的错误是由于您的alexaAppName未定义,以及passing it down到响应者的时间是在base64中编码,不可能run a replace这个变量。

我会尝试确保我的应用名称配置正确,并且给出的是有效的字符串,如alexa claudia example所示。