Пара наблюдений:
Первый
В ветке кода, которая обрабатывает GetMachineStateIntent
, вы добавили код для создания обработчиков состояний, но они не были правильно подключены. В лучшем случае этот код ничего не сделает, в худшем случае он может вызвать некоторые проблемы. Удалить это.
// take the following lines of code out
var ConfirmationHandlers = Alexa.CreateStateHandler(states.CONFIRMATIONMODE, {
'YesIntent': function () {
this.emit("GetMachineStateIntent");
},
'AMAZON.NoIntent': function () {
this.response.speak(GetMachineStateIntent);
this.emit(':responseReady');
}
});
Второй Параметры запроса, которые вы передаете в свой запрос DynamoDB, жестко запрограммированы. Это означает, что вы всегда получите один и тот же результат. Вам нужно передать значения слотов, которые вы получаете в намерении, в параметры для запроса.
var params = {
TableName: "updatedincident",
Key: {
date: "2018-03-28",
time: "04:23",
state: "Blocked Primary"
}
};
Это жестко запрограммировано. Вам нужно только указать первичный ключ (date
) и ключ сортировки («время»), чтобы вы могли удалить state
. А для date
и time
необходимо изменить значения, которые будут динамически передаваться из dateSlot
и timeSlot
.
Третий В ветви кода, которая обрабатывает запросы типа IntentRequest
, вы обрабатываете GetMachineStateIntent
дважды, и код немного избыточен. Перепишите это следующим образом:
...
} else if (request.type === "IntentRequest") {
if (request.intent.name === "GetMachineStateIntent") {
GetMachineStateIntent(context, callback);
} 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") {
Четвертый
Это наиболее сложно объяснить. Когда вы запрашиваете состояние машины, вы будете указывать дату и время, но, предположительно, состояние машины может не сохраняться в базе данных с отметкой времени, которая точно соответствует значению времени в вашем запросе. Таким образом, вы должны выполнить запрос, который по существу эквивалентен «каково состояние машины на дату X, в самое последнее время до или равно Y»
Это та самая "самая последняя часть времени, предшествующая или равная Y", которая хитрая. Вы должны создать запрос к вашей таблице, который выражает это, и вам также придется изменить способ хранения меток времени в таблице, от строки до числового формата, чтобы вы могли легко выразить это неравенство.
Я собираюсь показать здесь, как передать dateSlot и timeSlot, чтобы сделать запрос, но я рекомендую вам посмотреть, как это работает (возможно, задайте конкретные вопросы, если вы застряли).
Вот ваш код с упомянутыми мною модификациями:
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: '#d = :dVal and #t < :tVal',
ExpressionAttributeValues: {
':dVal': dateSlot,
':tVal': timeSlot
},
ExpressionAttributeNames: {
'#d': 'date',
'#t': 'time'
},
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");
}
}
};