Is accessing the Customer Profile API possible using the Cloud9 code editor in the AWS Lambda web console? If so, how? - node.js

First off, I'm new to Alexa skill development, so I have much to learn. I've been banging my head off the desk trying to figure this out. I've found various tutorials and have gone over the information provided by Amazon for accessing the Customer Profile API via an Alexa skill but still can't manage to obtain the customer's phone number.
I'm using the AWS console in-line code editor (Cloud9). Most, if not all, instructions use something like 'axios', 'request', or 'https' modules which I don't think is possible unless you use the ask-cli (please correct me if I'm wrong). Also, I followed a tutorial to initially create the skill which had me use Skillinator.io to create an AWS Lambda template based on the skill's JSON in the Amazon Developer console. The format of the code in the Customer Profile API tutorials does not match what was provided by the Skillinator.io tool. The way the Intent handlers are set up is different, which is where I believe my confusion is coming from. Here's an example:
Skillinator.io code:
const handlers = {
'LaunchRequest': function () {
welcomeOutput = 'Welcome to the Alexa Skills Kit!';
welcomeReprompt = 'You can say, Hello!';
this.emit(':ask', welcomeOutput, welcomeReprompt);
},
};
Tutorial code:
const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
const speechText = 'Welcome to the Alexa Skills Kit!';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withSimpleCard('Hello World', speechText)
.getResponse();
}
};
Can anyone shed some light and help me understand why there is a difference in the way the handlers are formatted, and how (if possible) to create the request to the Customer Profile API?
I've already completed the steps for the necessary permissions/account linking.
Thanks in advance.
EDIT:
I've learned that the difference in syntax is due to the different versions of the sdk, Skillinator being 'alexa-sdk' or v1 and the various tutorials using 'ask-sdk' or v2.
I'm still curious as to whether using modules like 'axios' or 'request' is possible via the in-line code editor in AWS console or if it's even possible to access the Customer Profile API using sdk v1?

I've decided to answer the question with what I've learned in hopes that others won't waste as much time as I have trying to understand it.
Basically, it is possible to use the above-mentioned modules in sdk v1 using the AWS console's in-line code editor but you must create a .zip file of your code and any necessary modules and upload that .zip to Lambda.
I've edited my original answer to include my findings for the difference in syntax in the intent handlers.
From what I can tell (and please correct me if I'm wrong), it is not possible to access the Customer Profile API using the sdk v1.

Related

What is the simplest way is to deploy an existing AWS Lex and Lambda as an Alexa Skills Kit (ASK)?

I currently have a Lex bot that requires a Lambda function on my AWS account. I want to turn this existing bot into an Alexa Skill but can't migrate it easily.
What I've done so far:
Publish a version of the Lex Bot and export as an ASK
Import the JSON file into the Alexa Developer Console JSON Editor
Followed this tutorial to give both my Alexa Skill and Lambda function access to each other
I've checked in the CloudWatch Logs and the Alexa Skill seems to be calling my function properly, however, it won't fulfill the intent. When it reaches the end of the dialog for an intent, the Amazon Skill only says:
You just triggered [IntentName]
I understand that the JSON format is different for Alexa and Lex and the return formats are as follows:
// Alexa return
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt(speakOutput)
.getResponse();
// AWS Lex return
return {
sessionAttributes: attributes,
dialogAction: {
type: 'Close',
fulfillmentState: fulfillStatus,
message: {
contentType: "PlainText",
content: messageContent,
}
}
};
Is there any simple way to convert my existing Lambda function to work with an Alexa Skill without needing to rewrite the entire thing?
The answer to my question is: no. There is no way way to use my existing Lex-specific Lambda function with Alexa since Lex and Alexa use different API's.
The closest thing I found to using one Lambda for both would be to create a middleware to determine what client type is calling the Lambda, then, handle the Lex API calls and the Alexa API calls separately. This code comes from the AWS QnABot GitHub.
In my opinion, this seems to go against the idea of single responsibility. Since they're both using different code anyway, it seems like creating 2 separate Lambdas would be better. Please let me know your thoughts on this.
It's unfortunate that Lex code isn't able to translate to Alexa simply. Hopefully the AWS team creates a simple solution for this in the future.
This is specifically for Lex V1 though. V2 seems to more easily translate into an Alexa Skill.

Testing Google Pay via Stripe in cypress

I'm trying to write a Cypress test that interacts with react-stripe-js's PaymentRequestButtonElement component. Unfortunately I'm hitting a little bit of a stumbling block actually getting my test to render the button (works fine when I manually test).
I've tried mocking the window's PaymentRequest function:
cy.window().then(win => {
if (win.PaymentRequest) {
// If we’re running in headed mode
cy.stub(win, 'PaymentRequest').callsFake(getMockPaymentRequest(validPaymentRequestResponse));
} else {
// else headless
win.PaymentRequest = getMockPaymentRequest(validPaymentRequestResponse)
}
});
but no luck, our button still doesn't appear. I suspect it has something to do with the following error I see in my console:
Unable to download payment manifest "https://google.com/pay"., but had a look through Google and seemingly nobody seems to have mentioned this.
I've also tried stubbing window.Stripe in a similar way (to mock out the stripe.paymentRequest function) but equally no luck there.
Has anyone had any success implementing something similar?
In order to test Stripe's Payment Request button in Cypress you will likely need to mock the Payment Request API:
Now that all the pieces are in place we can attempt to test something a bit trickier, the Payment Request API that Stripe conveniently wraps for us.
This API is used to detect whether a browser supports payment methods like Apple or Google Pay and then handles accepting payments via these APIs.

Stripe BillingPortal NodeJS

I'm facing difficulty in integration of the Stripe customer billing portal using NodeJS. Please, help.
Error:
Cannot read property sessions of undefined.
This error sounds like one that would be thrown by a line of code that looks like
var session = await stripe.billingPortal.sessions.create({
customer: 'cus_XXYYZZ',
return_url: 'https://example.com/account',
});
either because you've not imported the Stripe NodeJS library correctly, or you are using a version prior to 8.45.0, which is the first version of the Stripe NodeJS library to support the Customer Portal.
You should also make sure to closely read and follow the Customer Portal guide in the Stripe docs as there are some nuances that you should understand.

Is it possible to lookup a database in a Dialogflow intent?

I'm trying to make an app using DialogFlow which finds a specific object in a specific place.
This is a generic example.
The user would say something like "Where to I find Dog in Europe" and the app would reply with "Dog can be found in Europe via: breeding, finding it out in the wild or by buying it"
considering Dog as input1 and europe as input2
Ideally the app should be able to cross reference input1 and input2 to find the correct response. Can I implement a database like structure and do this?
You can't access a database from Dialogflow directly, but you can build your own fulfillment backend that can do anything you want. It communicates with Dialogflow via HTTP requests/responses in the Dialogflow Webhook format.
Here is an example fulfillment that reads data from Firebase database - https://github.com/actions-on-google/dialogflow-updates-nodejs
You can't access a database directly in Dialog flow, but you can build your own fulfillment back end. I have been using Airtable as a database and Integromat and Webhooks to query the database and parse the results back to Dialogflow. As a novice coder I found this to be the simnplest way.
KaySubb is right, you can make a fulfillment that reads data from a firebase database(or firestore).
You can do this turning on fulfillment at the bottom page of the intent page.
First go to https://console.firebase.google.com/ (login with google account) and you should be able to see your google cloud platform project.
To use firebase, you need to first install it. Get node.js as you need npm first. I'm not sure what OS you're on but go into command line or terminal and type.
npm install firebase --save
then type:
firebase login
this will authenticate your login and connect your project when you deploy.
Then use go to the directory you want to create your project in:
firebase init functions
Select your project and select javascript, install all dependencies
Now go to functions and open the index.js file. Here you can change you write code needed in js.
Write your functions and type:
firebase deploy
in the command line open in the file directory. When it completes, it will
give you a link. This as the webhook URL in dialogflow (it should start with
https://us-central). If you see only 1 link which says
console.firebase.google.com....... then open that link on a browser, click on
"functions" on the left side of the screen and get the link from there.
This should get you started with firebase, now you can link your project to firebase fulfillment. There is great firestore explanation here
https://www.youtube.com/watch?v=kdk6MhhI8oc
But I'll give you a brief explanation:
On the top of your index.js file you will need:
const functions = require('firebase-functions');
var admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);
var firestore = admin.firestore();
The basic code is here:
exports.webhook = functions.https.onRequest((request, response) => {
switch(request.body.result.action){
case 'saveData':
let params = request.body.result.parameters
firestore.collection('colName').doc('docName').add({
name:params.name
age:params.age
}).then(() => {
response.send({
speech:
`this is a response for "${params.name}".`
});
})
.catch((e => {
console.log('Error getting documents', e);
response.send({
speech:
`Sorry, something has gone wrong. Try again and if the problem persists, please report it.`
});
}))
break;
default:
}
})
I'll explain what it does:
You need the switch to decide which intent to do. request.body.result.action returns the action name (write this in dialogflow just above the parameters).
Once that is decided request.body.result.parameters give you the parameters from the intent. params.______ gives you the parameter.
I would definitely recommend reading the official documentation:
https://firebase.google.com/docs/firestore/quickstart
to help understand the data structure to help create the ideal database for you. Essentially a collection is a list and within that a doc is one entry. You can name them yourself of using the entries from param.
respond.send is what the bot will reply to the user, I've also shown how to use the parameters in the response.
.catch will just store any errors in the log, you can read the log in console.firebase.google.com.... open your project and click on function. There will be a place to read logs there. You can check any errors encountered over there.
default: will output whatever default response you wrote on dialogflow at the bottom of the intent.
Hope this helps,comment any questions. I have gone through a huge amount as concisely as I could. This will take some time to get used to and become good at, follow the docs and the youtube videos if you have a lot of trouble!
If you're having even more trouble, there is a slack that helps people that I can direct you to.

How to get Correct Subscription key for microsoft Face API for Nodejs?

I am using project-oxford inorder to use Microsoft API with nodejs. I am keep on getting error that ,
{"code":"Unspecified","message":"Access denied due to invalid subscription key. Make sure you are subscribed to an API you are trying to call and provide the right key."}
{"code":"Unspecified","message":"Access denied due to invalid subscription key. Make sure you are subscribed to an API you are trying to call and provide the right key."}
I have also regenerated my subscription key for my microsoft account and tried to access the code. Still I am getting the same issue. Spent lot of time to find my bug fixed, But I couldn't able to solve.
This is my nodejs code,
var oxford = require('project-oxford'),
client = new oxford.Client({SubscriptionKey});
client.video.trackFace({
url: path,
}).then(function (response) {
console.log('Response ' + JSON.stringify(response));
},function (error) {
console.log("Error"+JSON.stringify(error));
});
Please guide me to fix this issue.Thanks in Advance!!
You can obtain a key via the Microsoft Cognitive Services web site.
From what I can gather, you are using https://github.com/felixrieseberg/project-oxford, is that correct?
It seems that project requires one subscription key, which then is used for all API calls. I can't see any reasons it shouldn't work, if you have signed up for the subscription key for the Video API.
Given that the library you're using is built the way it is, it seems to me that you will only be able to use one API at the time, doing it the way you're doing it now.
Am I making any sense?
Actually Now I am getting output for the same code excepting that I was not able use the localhost URL [i.e., http://localhost:3000/uploads/img.jpg]. While using the url of webserver only then I am getting the output!!
Can anyone explain me the complete fact. i.e., I need to know whether I cannot use the localhost url. If I use so I am getting the error which I have posted in this question.

Resources