Как получить конкретный предмет из таблицы DynamoDB, используя NodeJs для развития навыков alexa - PullRequest
0 голосов
/ 26 марта 2019

Я пытался развить навык в Alexa, который может хранить данные в таблице Amazon DynamoDB. На данный момент я могу добавить данные (то есть имя элемента) вместе с атрибутом (то есть местоположением элемента) в таблицу DynamoDB, используя голосовые команды, я также могу удалить конкретный элемент из таблицы. Но теперь я хочу, чтобы Алекса получала конкретный элемент вместе с его атрибутом (местоположением) из таблицы всякий раз, когда я говорю, что Alexa get {itemName}.

Я создал два отдельных файла index.js для обработки с намеренными запросами и DbHelper.js для передачи параметров в таблицу. Я включил код в оба файла ниже. я использую лямбда-функцию AWS для размещения конечной точки моего навыка и использую NodeJ для кодирования лямбда-функции.

Я пытался использовать различные параметры запроса, включенные в aws-sdk, такие как docClient.get, docClient.scan и docClient.query, но, поскольку я новичок в этом, все, что я мог сделать, это получить все элементы из таблица не конкретный элемент.

Я ожидаю получить конкретный предмет из таблицы, но я получу все предметы, присутствующие в таблице.

/* ```````````````Index.js```````````````*/

const Alexa = require('ask-sdk');
const dbHelper = require('./helpers/dbHelper');
const GENERAL_REPROMPT = "What would you like to do?";
const dynamoDBTableName = "FORGETABLE_THINGS";
const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    const speechText = 'Hello there. What is your favourite thing? You can say add itemname to add your item or say get to get your items.';
    const repromptText = 'What would you like to do? You can say HELP to get available options';

    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(repromptText)
      .getResponse();
  },
};

const InProgressAddItemIntentHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' &&
      request.intent.name === 'AddItemIntent' &&
      request.dialogState !== 'COMPLETED';
  },
  handle(handlerInput) {
    const currentIntent = handlerInput.requestEnvelope.request.intent;
    return handlerInput.responseBuilder
      .addDelegateDirective(currentIntent)
      .getResponse();
  }
}

const AddItemIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'AddItemIntent';
  },
  async handle(handlerInput) {
    const {responseBuilder } = handlerInput;
    const userID = handlerInput.requestEnvelope.context.System.user.userId;
    const slots = handlerInput.requestEnvelope.request.intent.slots;
    const itemValue = slots.itemValue.value;
    const location = slots.location.value;
    return dbHelper.addItem(itemValue, location, userID)
      .then((data) => {
        const speechText = `You have added ${itemValue}, placed at ${location}. You can say add to add another one or remove to remove item`;
        return responseBuilder
          .speak(speechText)
          .reprompt(GENERAL_REPROMPT)
          .getResponse();
      })
      .catch((err) => {
        console.log("Error occured while saving it", err);
        const speechText = "we cannot save your item right now. Try again!"
        return responseBuilder
          .speak(speechText)
          .getResponse();
      })
  },
};

const GetItemIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'GetItemIntent';
  },
  async handle(handlerInput) {
    const {responseBuilder } = handlerInput;
    //const userID = handlerInput.requestEnvelope.context.System.user.userId; 
    const itemName= slots.itemValue.value;
    return dbHelper.getItem(itemName)
      .then((data) => {
        var speechText = "Your items are "
        if (data.length == 0) { 
          speechText = "You do not have any favourite item yet, add item by saying add itemname "
        } else {
          const datas = data.map(e => e.itemName + " " + e.Location);
          speechText += datas.join(" ,")
        }
        return responseBuilder
          .speak(speechText)
          .reprompt(GENERAL_REPROMPT)
          .getResponse();
      })
      .catch((err) => {
        const speechText = "we cannot get your item right now. Try again!"
        return responseBuilder
          .speak(speechText)
          .getResponse();
      })
  }
}

const InProgressRemoveItemIntentHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest' &&
      request.intent.name === 'RemoveItemIntent' &&
      request.dialogState !== 'COMPLETED';
  },
  handle(handlerInput) {
    const currentIntent = handlerInput.requestEnvelope.request.intent;
    return handlerInput.responseBuilder
      .addDelegateDirective(currentIntent)
      .getResponse();
  }
}

const RemoveItemIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'RemoveItemIntent';
  }, 
  handle(handlerInput) {
    const {responseBuilder } = handlerInput;
    const userID = handlerInput.requestEnvelope.context.System.user.userId;  
    const slots = handlerInput.requestEnvelope.request.intent.slots;
    const itemValue = slots.itemValue.value;
    return dbHelper.removeItem(itemValue, userID)
      .then((data) => {
        const speechText = `You have removed item with name ${itemValue} you can add another one by saying add`
        return responseBuilder
          .speak(speechText)
          .reprompt(GENERAL_REPROMPT)
          .getResponse();
      })
      .catch((err) => {
        const speechText = `You do not have item with name ${itemValue}, you can add it by saying add`
        return responseBuilder
          .speak(speechText)
          .reprompt(GENERAL_REPROMPT)
          .getResponse();
      })
  }
}

const HelpIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'AMAZON.HelpIntent';
  },
  handle(handlerInput) {
    const speechText = 'You can introduce yourself by telling me your name';

    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(speechText)
      .getResponse();
  },
};

const CancelAndStopIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && (handlerInput.requestEnvelope.request.intent.name === 'AMAZON.CancelIntent'
        || handlerInput.requestEnvelope.request.intent.name === 'AMAZON.StopIntent');
  },
  handle(handlerInput) {
    const speechText = 'Goodbye!';

    return handlerInput.responseBuilder
      .speak(speechText)
      .getResponse();
  },
};

const SessionEndedRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
  },
  handle(handlerInput) {
    console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);

    return handlerInput.responseBuilder.getResponse();
  },
};

const ErrorHandler = {
  canHandle() {
    return true;
  },
  handle(handlerInput, error) {
    console.log(`Error handled: ${error.message}`);

    return handlerInput.responseBuilder
      .speak('Sorry, I can\'t understand the command. Please say again.')
      .reprompt('Sorry, I can\'t understand the command. Please say again.')
      .getResponse();
  },
};

const skillBuilder = Alexa.SkillBuilders.standard();

exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequestHandler,
    InProgressAddItemIntentHandler,
    AddItemIntentHandler,
    GetItemIntentHandler,
    InProgressRemoveItemIntentHandler,
    RemoveItemIntentHandler,
    HelpIntentHandler,
    CancelAndStopIntentHandler,
    SessionEndedRequestHandler
  )
  .addErrorHandlers(ErrorHandler)
  .withTableName(dynamoDBTableName)
  .withAutoCreateTable(true)
  .lambda();

/*```````````dbHelper.js`````````````*/
var AWS = require("aws-sdk");
AWS.config.update({
  region: "us-east-1"
});
const tableName = "FORGETABLE_THINGS";

var dbHelper = function() {};
var docClient = new AWS.DynamoDB.DocumentClient();

dbHelper.prototype.addItem = (item, location, userID) => {
  return new Promise((resolve, reject) => {
    const params = {
      TableName: tableName,
      Item: {
        'itemName': item,
        'Location': location,
        'userId': userID,

      }
    };
    docClient.put(params, (err, data) => {
      if (err) {
        console.log("Unable to insert =>", JSON.stringify(err))
        return reject("Unable to insert");
      }
      console.log("Saved Data, ", JSON.stringify(data));
      resolve(data);
    });
  });
}

dbHelper.prototype.getItem = (userID) => {
  return new Promise((resolve, reject) => {
    const params = {
      TableName: tableName,
      KeyConditionExpression: "#userID = :user_id",
      ExpressionAttributeNames: {
        "#userID": "userId"
        "itemName": "itemName"
      },
      ExpressionAttributeValues: {
        ":user_id": userID

      }
    }
    docClient.query(params, (err, data) => {
      if (err) {
        console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
        return reject(JSON.stringify(err, null, 2))
      }
      console.log("GetItem succeeded:", JSON.stringify(data, null, 2));
      resolve(data.Items)

    })
  });
}

dbHelper.prototype.removeItem = (item, userID) => {
  return new Promise((resolve, reject) => {
    const params = {
      TableName: tableName,
      Key: {
        "userId": userID,
        "itemName": item
      },
      ConditionExpression: "attribute_exists(itemName)"
    }
    docClient.delete(params, function(err, data) {
      if (err) {
        console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
        return reject(JSON.stringify(err, null, 2));
      }
      console.log(JSON.stringify(err));
      console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));
      resolve();
    })
  });
};

module.exports = new dbHelper();
...