OpenWhisk invoke watson text to speech action from an action - node.js

I am trying to invoke an action included into Watson system package (text to speech) from an OpenWhisk action.
I have binded the service and set-up the credentials and so from the CLI I can see
wsk list
entities in namespace: xxxxxx
packages
/xxxxxx/myWatson private binding
Here is my OpenWhisk action:
function main(param) {
//code here for my action. At the end, I invoke the text to speech
if (...) {
textToSpeech(param.text);
}
else {
return whisk.error(error);
}
return whisk.async();
}
function textToSpeech(text){
whisk.invoke({
name:'myWatson/textToSpeech',
parameters:{
payload: text,
voice: 'en-US_MichaelVoice',
accept: 'audio/wav',
encoding: 'base64'
},
blocking: true,
next: function(error, activation){
if(error){
return whisk.error(error);
}
else{
return whisk.done({msg:'success'});
}
}
});
}
And I get the following error
"response": {
"result": {
"error": "The requested resource does not exist. (undefined)"
},
"status": "application error",
"success": false
}
Can you help understanding what I am doing wrong?

The name of the action should be fully qualified to include the namespace. From your CLI output, it looks like your package is /xxxxxx/myWatson so your action reference in the whisk.invoke should be /xxxxxx/myWatson/textToSpeech.

Related

Lambda custom authorize, how to return custom message?

i'm using serverless-framework, node.js and typescript for my service. I have a custom authorizer where I fetch from external service some data and depending on the response from that service I want to return such an error code in my lambda.
The problem is that each time the response from the authorizer is (no matter how I return the error and what error and what status code it passes):
{
"statusCode": 403,
"error": "Forbidden",
"message": "No principalId set on the Response"
}
Is this the specifics of the custom authorizer and nothing else can be returned or is it possible to modify the response somehow?
serverless.yml
...
functions:
users:
handler: lambdas/users/handler.main
events:
- http:
path: /users
method: GET
private: true
authorizer:
name: customAuthorizer
resultTtlInSeconds: 0
customAuthorizer:
handler: lambdas/custom-authorizer/handler.handler
environment:
APP_NAME: ${env:APP_NAME}
...
and this is a simply code from my handler
handler.ts
export async function handler(event: APIGatewayTokenAuthorizerEvent, context: Context): Promise<any> {
context.callbackWaitsForEmptyEventLoop = false;
try {
if (!event.authorizationToken) {
throw new HttpError("Unauthorized", 401);
}
const hasAccess = await fetchingPolicyFromExternalService(event.authorizationToken);
if (!hasAccess) {
throw new HttpError("Forbidden", 403);
}
const policyDocument = generatePolicy(event, "Allow"); //generate policy for Allow user to invoke api
return policyDocument;
} catch (error) {
if (error instanceof HttpError) {
return {
statusCode: error.status,
body: error.message,
};
}
return {
statusCode: 500,
body: "UnknownError",
};
}
}
Regarding private: true
Clients connecting to this Rest API will then need to set any of these API keys values in the x-api-key header of their request. This is only necessary for functions where the private property is set to true.
https://www.serverless.com/framework/docs/providers/aws/events/apigateway/
Not sure how you're sending your request, but consider this part. It could be that you're missing header information and that is why it always answers like that (i.e not your authorizer, but your function is protected). Therefore this response may come from your function, not the authorizer.

MalformedResponse Error on Google Assistant

I am calling a third-party API to fetch data. In a situation when the API returns error I can't continue my user flow on the Google Assitant
Error I see in Google Cloud Console is as follows:
"MalformedResponse: ErrorId: c316c2bc-be3b-4c8f-8d9b-2b45434a0325.
Failed to parse Dialogflow response into AppResponse because of
invalid platform response. : Could not find a RichResponse or
SystemIntent in the platform response for agentId:
0bc4ed97-dfec-4936-b90d-28f047eb7b34 and intentId:
3dcf4b35-00e0-4c75-815c-d1a76494e08e"
Here is my intent code.
app.intent('askPin', (conv, params) => {
conv.user.storage.pin_prompt_count = conv.user.storage.pin_prompt_count + 1;
var member = services.getMemberDetails(memberId, params.account_pin);
return member.then(function (result) {
if (result) {
conv.user.storage.pin_prompt_count = 0; //reset prompt count once verified
conv.user.storage.account_pin = params.account_pin;
conv.contexts.delete('account-pin-context');//delete context to pin intent will not be invoked again.
return handleService(conv);
}
}).catch(function (err) {
console.log("Paresh Varde 1");
conv.ask("Invalid Pin. Please try again");
})
});
Here is the Response I see being generated from the log
{
"status": 200,
"headers": {
"content-type": "application/json;charset=utf-8"
},
"body": {
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "Invalid Pin. Please try again"
}
}
]
}
}
}
}
}
I don't see any error in the firebase console (where the function is deployed). However I see an error in Google Cloud console as follows:
MalformedResponse: ErrorId: c316c2bc-be3b-4c8f-8d9b-2b45434a0325. Failed to parse Dialogflow response into AppResponse because of invalid platform response. : Could not find a RichResponse or SystemIntent in the platform response for agentId: 0bc4ed97-dfec-4936-b90d-28f047eb7b34 and intentId: 3dcf4b35-00e0-4c75-815c-d1a76494e08e
I see a message on my simulator as "App isn't responding right now. Try again soon." and it leaves the conversation.
Please advise.
The problem was that my webhook call was taking more than 5 seconds to complete. Webhook must complete it's execution in less than 5 seconds to work properly and make the conversation smooth.
For now, I need to work out my REST interface so that API I am calling respond quickly to achieve this timeout limit.

how to add update multiple response of a dialog node in IBM watson assistant with Nodejs

I have a node application which is interacting with IBM watson assistant.
I need to update the response output of a dialog node and I'm using the following watson api
var params = {
workspace_id: //,
dialog_node: 'greeting',
new_dialog_node: 'greeting',
new_output: {
text: 'Hello! What can I do for you?'
//add more than one text
}
};
assistant.updateDialogNode(params, function(err, response) {
if (err) {
console.error(err);
} else {
console.log(JSON.stringify(response, null, 2));
}
});
the API only accepts object type text:'Hello! What can I do for you?' this also overwrites the previous response
the error [ { message: 'output should be of type Object', path: '.output' } ]
How can I update the Dialog and add multiple responses at the same time or update the existing one?
thanks in advance!
Have you tried the following format for new_output?
{
"text": {
"values": [
"first response",
"second response"
],
"selection_policy": "sequential"
}

paypal invalid negative testing input

I try to simulate negative testing using paypal rest sdk with nodejs based on here
Hier is my code implementation:
config.headers = {
"PayPal-Mock-Response": {"mock_application_codes":"INSTRUMENT_DECLINED"}
}
paypal.payment.execute(paymentId, data, config, function (error, payment) {
if (error) {
console.log(error.response);
} else {
// success code
}
}});
However I got this following error:
{ name: 'SIMULATION_FRAMEWORK_INVALID_NEGATIVE_TESTING_INPUT',message:'Invalid input found. See the following supported cases.',links: [ { href: 'https://developer.paypal.com/docs/api/nt-rest/',rel: 'information_link' } ],details: [ { issue: 'You must have valid input.' } ],httpStatusCode: 400 }
Can anyone help me what's wrong from my code?
Many Thanks
You have to stringify the object:
headers: {
'PayPal-Mock-Response': JSON.stringify({
"mock_application_codes":"CANNOT_PAY_SELF"
})
},

AWS cognito: getCredentials not working

Im in the process of learning to use AWS Cognito. I have set up a userpool and a identity pool.
Code (simplified):
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: (result) => {
let cognitoGetUser = userPool.getCurrentUser();
if (cognitoGetUser != null) {
cognitoGetUser.getSession((err, result) => {
if (result) {
console.log ("Authenticated to Cognito User and Identity Pools!");
let token = result.getIdToken().getJwtToken();
let cognitoParams = {
IdentityPoolId: this.identityPool,
Logins: {}
};
cognitoParams.Logins["cognito-idp.eu-west-1.amazonaws.com/"+this.poolData.UserPoolId] = token;
AWS.config.credentials = new AWS.CognitoIdentityCredentials(cognitoParams);
AWS.config.getCredentials(() => {
console.log(AWS.config.credentials.accessKeyId)
console.log(AWS.config.credentials.secretAccessKey)
console.log(AWS.config.credentials.sessionToken)
}
}
}
}
},
onFailure: function(err) {
console.log('error');
console.log(err)
}
}
}
Most of the code works as expected: The authenticateUser fires the onSuccess and I can see a jwt token ect
Problem: I cant get the AWS.config.getCredentials to work. It executed without any errors, but accessKeyId, secretAccessKey and SessionToken are all undefined.
Any suggestions to what I'm doing wrong?
I cant get the AWS.config.getCredentials to work. It executed without any errors but,
This may be a mistaken assumption. Your abbreviated code is missing a couple of closing parentheses, but ran fine for me without any meaningful adjustments.
When calling getCredentials, any errors are "silently" reported through an error object. I would think you'd see a 400 response somewhere (network tab or console or both), but getCredentials() doesn't really report errors in a visible fashion by itself.
To see what is going wrong, you should add a parameter to the callback you pass to getCredentials():
AWS.config.getCredentials((err) => {
if (err) {
console.log(err);
} else {
console.log(AWS.config.credentials.accessKeyId)
console.log(AWS.config.credentials.secretAccessKey)
console.log(AWS.config.credentials.sessionToken)
}
});
For reference, one commonly encountered error object looks like this. Note that the useful message is found in originalError.message:
{
"message": "Could not load credentials from CognitoIdentityCredentials",
"code": "CredentialsError",
"time": "2018-06-03T15:19:02.078Z",
"requestId": "71b03b4a-6741-11e8-98af-b70a114474f8",
"statusCode": 400,
"retryable": false,
"retryDelay": 94.28032122526344,
"originalError": {
"message": "Invalid login token. Issuer doesn't match providerName",
"code": "NotAuthorizedException",
"time": "2018-06-03T15:19:02.078Z",
"requestId": "71b03b4a-6741-11e8-98af-b70a114474f8",
"statusCode": 400,
"retryable": false,
"retryDelay": 94.28032122526344
}
}
The corresponding 400 in the Network tab contains this response:
{"__type":"NotAuthorizedException","message":"Invalid login token. Issuer doesn't match providerName"}

Resources