Claudia.js 文本回复和 Alexa 的问题

issues with Claudia.js text responses and Alexa

我正在开发一个 Claudia.js 机器人,它可以通过 Slack、FB Messenger 和 Alexa 技能访问。据说在 claudia 中,你可以 return 纯文本,框架会正确地将它返回给 "frontend" ... Alexa "Service Simulator" 我总是得到 "The response is invalid." 这是使用 Claudia.js 的 lambda。基本上它从客户端获取消息,然后将它们分流到另一个 Lambda,即 "AI"。 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 我仍然得到 "The response is invalid." 因为服务响应正在返回 "undefined."

查看日志,一旦响应被 returned(由 botBuilder 解析并传递给 Alexa)就会发生此错误 [TypeError: Cannot read property 'replace' of undefined]


另一个更新:

如果我将 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]

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

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

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

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

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

通过查看机器人构建器的代码,我最好的选择是你得到的错误是由于你的 alexaAppName 未定义,并且当此变量的 passing it down to the responder that is encoded in base64, it's not possible to run a replace .

我会尝试确保我的应用程序名称配置正确,并且给出的是 alexa claudia example.

中显示的有效字符串