Динамодб Алекса запрос не вызывает элемент данных - PullRequest
0 голосов
/ 16 мая 2018

Я создаю навык, в котором я хочу позвонить Алексе и прочитать разные предметы в определенные даты и время. В настоящее время моя таблица настроена следующим образом: Дата | Время | Государство

Дата установлена ​​как мой первичный ключ, а время - как ключ сортировки. Я установил дату и время как значения слотов в ASK, и я вижу, что эти значения пропускаются. Я также удостоверился, что формат моей даты и времени правильный в DynamodB.

Моя проблема в том, что когда я звоню Алексе и спрашиваю состояние в определенную дату и время, я не могу заставить Алексу ответить с состоянием, соответствующим этой дате и времени.

Может кто-нибудь помочь мне с этим? Или скажите мне, где я ошибаюсь, я вставлю свой код ниже.

const awsSDK = require('aws-sdk');
const updatedincident = 'updatedincident';
const docClient = new awsSDK.DynamoDB.DocumentClient();

var AWSregion = 'us-east-1';  // us-east-1
var AWS = require('aws-sdk');
var dbClient = new AWS.DynamoDB.DocumentClient();
AWS.config.update({
    region: "'us-east-1'"
});

let GetMachineStateIntent = (context, callback, dateSlot, timeSlot) => {    
  var params = {
    TableName: "updatedincident",
    KeyConditionExpression: 'date = :dVal and time < :tVal',
    ExpressionAttributeValues: {
       ':dVal': dateSlot,
       ':tVal': timeSlot
    },
    ScanIndexForward: false // gets values in reverse order by time 
  };
  dbClient.query(params, function (err, data) {
    if (err) {
       // failed to read from table for some reason..
       console.log('failed to load data item:\n' + JSON.stringify(err, null, 2));
       // let skill tell the user that it couldn't find the data 
       sendResponse(context, callback, {
          output: "the data could not be loaded from your database",
          endSession: false
       });
    } else {
       let dataItem = data.Items[0];           
       console.log('loaded data item:\n' + JSON.stringify(dataItem, null, 2));
       // assuming the item has an attribute called "state"..
       sendResponse(context, callback, {
          output: dataItem.state,
          endSession: false
       });
    }
  });
};


function sendResponse(context, callback, responseOptions) {
  if(typeof callback === 'undefined') {
    context.succeed(buildResponse(responseOptions));
  } else {
    callback(null, buildResponse(responseOptions));
  }
}

function buildResponse(options) {
  var alexaResponse = {
    version: "1.0",
    response: {
      outputSpeech: {
        "type": "SSML",
        "ssml": `<speak><prosody rate="slow">${options.output}</prosody></speak>`
      },
      shouldEndSession: options.endSession
    }
  };
  if (options.repromptText) {
    alexaResponse.response.reprompt = {
      outputSpeech: {
        "type": "SSML",
        "ssml": `<speak><prosody rate="slow">${options.reprompt}</prosody></speak>`
      }
    };
  }
  return alexaResponse;
}

exports.handler = (event, context, callback) => {
  try {
    var request = event.request;
    if (request.type === "LaunchRequest") {
      sendResponse(context, callback, {
        output: "welcome to my skill, I can tell you about the status of machines at different times. what data are you looking for?",
        endSession: false
      });
    } else if (request.type === "IntentRequest") {
      if (request.intent.name === "GetMachineStateIntent") {
        var dateSlot = request.intent.slots.Date != null 
             ? request.intent.slots.Date. value : null;
        var timeSlot = request.intent.slots.Time != null
             ? request.intent.slots.Time.value : null;
        // pass the slot values to the GetMachineStateIntent function
        GetMachineStateIntent(context, callback, dateSlot, timeSlot);
      } else if (request.intent.name === "AMAZON.StopIntent" || request.intent.name === "AMAZON.CancelIntent") {
        sendResponse(context, callback, {
          output: "ok. good bye!",
          endSession: true
        });
      }
      else if (request.intent.name === "AMAZON.HelpIntent") {
        sendResponse(context, callback, {
          output: "you can ask me about incidents that have happened or states of machines in the past",
          reprompt: "what can I help you with?",
          endSession: false
        });
      }
      else {
        sendResponse(context, callback, {
          output: "I don't know that one! please try again!",
          endSession: false
        });
      }
    }
    else if (request.type === "SessionEndedRequest") {
      sendResponse(context, callback, ""); // no response needed
    }
    else {
      // an unexpected request type received.. just say I don't know..
      sendResponse(context, callback, {
          output: "I don't know that one! please try again!",
          endSession: false
      });
    }
  } catch (e) {
    // handle the error by logging it and sending back an failure
    console.log('Unexpected error occurred in the skill handler!', e);
    if(typeof callback === 'undefined') {
       context.fail("Unexpected error");
    } else {
       callback("Unexpected error");
    }
  }
};

Ответ, который я в настоящее время получаю с моим кодом выше:

'the data could not be loaded from your database'

Облачные часы также говорят мне об этом

2018-05-16T09:29:06.635Z	93d4b6e6-58eb-11e8-b686-597d65771e90	failed to load data item:
{
    "message": "Invalid KeyConditionExpression: Attribute name is a reserved keyword; reserved keyword: date",
    "code": "ValidationException",
    "time": "2018-05-16T09:29:06.633Z",
    "requestId": "EQPQTAGO4QKH9SM5GSOA9O3DDFVV4KQNSO5AEMVJF66Q9ASUAAJG",
    "statusCode": 400,
    "retryable": false,
    "retryDelay": 35.56027710686527
}

1 Ответ

0 голосов
/ 17 мая 2018

В функции GetMachineStateIntent попробуйте изменить структуру params следующим образом:

var params = {
  TableName: "updatedincident",
  KeyConditionExpression: '#d = :dVal and #t < :tVal',
  ExpressionAttributeValues: {
     ':dVal': dateSlot,
     ':tVal': timeSlot
  },
  ExpressionAttributeNames: {
     '#d': 'date',
     '#t': 'time'
  },
  ScanIndexForward: false // gets values in reverse order by time 
};

Похоже, слово date является зарезервированным ключевым словом, поэтому его нельзя использовать непосредственно в выражении, таком как date = :dVal, поэтому вы должны присвоить ему псевдоним имени атрибута (#d), который отображается обратно. к фактическому имени атрибута (date).

...