Использование Alexa скилла porofile api вместе с динамодером для сохранения адреса электронной почты пользователя - PullRequest
0 голосов
/ 29 ноября 2018

Я пытаюсь создать демонстрационную версию Alexa Skill, в которой я использую API профиля клиента, чтобы получить информацию о клиенте, такую ​​как электронная почта и т. Д., А затем хочу сохранить идентификатор электронной почты в DynamoDb.Я следовал всем инструкциям из документации и не могу заставить это работать.Пожалуйста, посмотрите мой код и скажите, что я делаю не так.Любая помощь или свежий взгляд приветствуется.

    dBhelper.js

    var AWS = require("aws-sdk");
    AWS.config.update({region: "us-east-1"});
    const tableName = "user-emails";

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

    dbHelper.prototype.addEmail = (email, userID) => {
        return new Promise((resolve, reject) => {
            const params = {
                TableName: tableName,
                Item: {
                  'email' : email,
                  '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);
            });
        });
    }





    module.exports = new dbHelper();


    index.js

    //const Alexa = require('ask-sdk-core');
    const Alexa = require('ask-sdk');
    const dbHelper = require('./helpers/dbHelper');
    const GENERAL_REPROMPT = "What would you like to do?";
    const dynamoDBTableName = "user-emails";

    const messages = {
      WELCOME: 'Welcome to the Sample Alexa Customer Profile API Skill! You can ask for your name, your email address, or your phone number. What do you want to ask?',
      WHAT_DO_YOU_WANT: 'What do you want to ask?',
      NOTIFY_MISSING_PERMISSIONS: 'Please enable Customer Profile permissions in the Amazon Alexa app.',
      NAME_MISSING: 'You can set your name either in the Alexa app under calling and messaging, or you can set it at Amazon.com, under log-in and security.',
      EMAIL_MISSING: 'You can set your email at Amazon.com, under log-in and security.',
      NUMBER_MISSING: 'You can set your phone number at Amazon.com, under log-in and security.',
      NAME_AVAILABLE: 'Here is your full name: ',
      EMAIL_AVAILABLE: 'Here is your email address: ',
      NUMBER_AVAILABLE: 'Here is your phone number: ',
      ERROR: 'Uh Oh. Looks like something went wrong.',
      API_FAILURE: 'There was an error with the Alexa Customer Profile API. Please try again.',
      GOODBYE: 'Bye! Thanks for using the Sample Alexa Customer Profile API Skill!',
      UNHANDLED: 'This skill doesn\'t support that. Please ask something else.',
      HELP: 'You can use this skill by asking something like: whats my name?',
      STOP: 'Bye! Thanks for using the Sample Alexa Customer Profile API Skill!',
    };

    const PERMISSIONS = ['alexa::profile:name:read', 'alexa::profile:email:read', 'alexa::profile:mobile_number:read'];

    const LaunchRequest = {
      canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
      },
      handle(handlerInput) {
        return handlerInput.responseBuilder.speak(messages.WELCOME)
          .reprompt(messages.WHAT_DO_YOU_WANT)
          .getResponse();
      },
    };

    const NameIntent = {
      canHandle(handlerInput) {
        const { request } = handlerInput.requestEnvelope;

        return request.type === 'IntentRequest' && request.intent.name === 'NameIntent';
      },
      async handle(handlerInput) {
        const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;

        const consentToken = requestEnvelope.context.System.apiAccessToken;
        if (!consentToken) {
          return responseBuilder
            .speak(messages.NOTIFY_MISSING_PERMISSIONS)
            .withAskForPermissionsConsentCard(PERMISSIONS)
            .getResponse();
        }
        try {
          const client = serviceClientFactory.getUpsServiceClient();
          const name = await client.getProfileName();

          console.log('Name successfully retrieved, now responding to user.');

          let response;
          if (name == null) {
            response = responseBuilder.speak(messages.NAME_MISSING).getResponse();
          } else {
            response = responseBuilder.speak(messages.NAME_AVAILABLE + name).getResponse();
          }
          return response;
        } catch (error) {
          if (error.name !== 'ServiceError') {
            const response = responseBuilder.speak(messages.ERROR).getResponse();
            return response;
          }
          throw error;
        }
      },
    };

    const EmailIntent = {
      canHandle(handlerInput) {
        const { request } = handlerInput.requestEnvelope;

        return request.type === 'IntentRequest' && request.intent.name === 'EmailIntent';
      },
      async handle(handlerInput) {
        const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;

        const consentToken = requestEnvelope.context.System.apiAccessToken;
        if (!consentToken) {
          return responseBuilder
            .speak(messages.NOTIFY_MISSING_PERMISSIONS)
            .withAskForPermissionsConsentCard(PERMISSIONS)
            .getResponse();
        }
        try {
          const client = serviceClientFactory.getUpsServiceClient();
          const email = await client.getProfileEmail();

          console.log('Email successfully retrieved, now responding to user.');

          let response;
          if (email == null) {
            response = responseBuilder.speak(messages.EMAIL_MISSING).getResponse();
          } else {
            response = responseBuilder.speak(messages.EMAIL_AVAILABLE + email).getResponse();
          }
          return response;
        } catch (error) {
          if (error.name !== 'ServiceError') {
            const response = responseBuilder.speak(messages.ERROR).getResponse();
            return response;
          }
          throw error;
        }
      },
    };



    const AddEmailIntentHandler = {
      canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'IntentRequest'
          && handlerInput.requestEnvelope.request.intent.name === 'AddEmailIntent';
      },
      async handle(handlerInput) {
        const {responseBuilder } = handlerInput;
        const userID = handlerInput.requestEnvelope.context.System.user.userId;
        const client = serviceClientFactory.getUpsServiceClient();
          const email = await client.getProfileEmail();

        return dbHelper.addEmail(email, userID)
          .then((data) => {
            const speechText = `You have added the email id.`;
            return responseBuilder
              .speak(speechText)
              .reprompt(GENERAL_REPROMPT)
              .getResponse();
          })
          .catch((err) => {
            console.log("Error occured while saving email", err);
            const speechText = "we cannot save your email right now. Try again!"
            return responseBuilder
              .speak(speechText)
              .getResponse();
          })
      },
    };





    const NumberIntent = {
      canHandle(handlerInput) {
        const { request } = handlerInput.requestEnvelope;

        return request.type === 'IntentRequest' && request.intent.name === 'NumberIntent';
      },
      async handle(handlerInput) {
        const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;

        const consentToken = requestEnvelope.context.System.apiAccessToken;
        if (!consentToken) {
          return responseBuilder
            .speak(messages.NOTIFY_MISSING_PERMISSIONS)
            .withAskForPermissionsConsentCard(PERMISSIONS)
            .getResponse();
        }
        try {
          const client = serviceClientFactory.getUpsServiceClient();
          const number = await client.getProfileMobileNumber();

          console.log('Number successfully retrieved, now responding to user.');

          let response;
          if (number == null) {
            response = responseBuilder.speak(messages.NUMBER_MISSING).getResponse();
          } else {
            response = responseBuilder.speak(`${messages.NUMBER_AVAILABLE} ${number.countryCode} ${number.phoneNumber}`).getResponse();
          }
          return response;
        } catch (error) {
          if (error.name !== 'ServiceError') {
            const response = responseBuilder.speak(messages.ERROR).getResponse();
            return response;
          }
          throw error;
        }
      },
    };

    const SessionEndedRequest = {
      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 UnhandledIntent = {
      canHandle() {
        return true;
      },
      handle(handlerInput) {
        return handlerInput.responseBuilder
          .speak(messages.UNHANDLED)
          .reprompt(messages.UNHANDLED)
          .getResponse();
      },
    };

    const HelpIntent = {
      canHandle(handlerInput) {
        const { request } = handlerInput.requestEnvelope;

        return request.type === 'IntentRequest' && request.intent.name === 'AMAZON.HelpIntent';
      },
      handle(handlerInput) {
        return handlerInput.responseBuilder
          .speak(messages.HELP)
          .reprompt(messages.HELP)
          .getResponse();
      },
    };

    const CancelIntent = {
      canHandle(handlerInput) {
        const { request } = handlerInput.requestEnvelope;

        return request.type === 'IntentRequest' && request.intent.name === 'AMAZON.CancelIntent';
      },
      handle(handlerInput) {
        return handlerInput.responseBuilder
          .speak(messages.GOODBYE)
          .getResponse();
      },
    };

    const StopIntent = {
      canHandle(handlerInput) {
        const { request } = handlerInput.requestEnvelope;

        return request.type === 'IntentRequest' && request.intent.name === 'AMAZON.StopIntent';
      },
      handle(handlerInput) {
        return handlerInput.responseBuilder
          .speak(messages.STOP)
          .getResponse();
      },
    };

    const ProfileError = {
      canHandle(handlerInput, error) {
        return error.name === 'ServiceError';
      },
      handle(handlerInput, error) {
        if (error.statusCode === 403) {
          return handlerInput.responseBuilder
            .speak(messages.NOTIFY_MISSING_PERMISSIONS)
            .withAskForPermissionsConsentCard(PERMISSIONS)
            .getResponse();
        }
        return handlerInput.responseBuilder
          .speak(messages.LOCATION_FAILURE)
          .reprompt(messages.LOCATION_FAILURE)
          .getResponse();
      },
    };


    const skillBuilder = Alexa.SkillBuilders.standard();

    exports.handler = skillBuilder
      .addRequestHandlers(
        LaunchRequest,
        NameIntent,
        EmailIntent,
        AddEmailIntent,
        NumberIntent,
        SessionEndedRequest,
        HelpIntent,
        CancelIntent,
        StopIntent,
        UnhandledIntent,
      )
      .addErrorHandlers(ProfileError)
      .withApiClient(new Alexa.DefaultApiClient())
      .withCustomUserAgent('cookbook/customer-profile/v1')
      .withTableName(dynamoDBTableName)
      .withAutoCreateTable(true)


      .lambda();

1 Ответ

0 голосов
/ 30 ноября 2018

Какую ошибку вы получаете?Вы:

  1. Убедитесь, что права доступа настроены для доступа к информации с помощью навыков?

Код для получения информации об устройстве выглядит некорректно для стандартного конструктора навыков.

Вот пример кода, который я использую для получения часового пояса пользователя и имени.

try
{
  const deviceID  = handlerInput.requestEnvelope.context.System.device.deviceId; 
  if (deviceID) {
    const deviceAddressServiceClient = handlerInput.serviceClientFactory.getUpsServiceClient();
    timeZone = await deviceAddressServiceClient.getSystemTimeZone(deviceID);
    givenName = await deviceAddressServiceClient.getProfileGivenName(deviceID);
  }
}
...