Integrate actions sdk with aws lambda - aws-lambda

I am trying to develop a google assistant app with actions sdk. I found lot of samples online which all are using google's firebase cloud functions to deploy.
From this link(https://actions-on-google.github.io/actions-on-google-nodejs/) I also found that it is possible to deploy the actions sdk functions into aws lambda.
But unfortunately I did not find any sample which is showing how to write and deploy actions sdk into aws lambda.
Can anybody help me to write an application which is similar to the one shown here(https://github.com/actions-on-google/actionssdk-say-number-nodejs) and deploy it into aws lambda?
I tried the following to do the same. But it did not worked.
Created a folder and initialized it with "npm init".
Added index.js file.
Then ran the command "npm install actions-on-google". It appeared in the package.json file.
Created a zip folder of the entire source inside that folder I created.
Created a aws lambda function and uploaded the zip folder and set the "Handler" of the lambda function as "index.fulfillment".
Created an api gateway and linked it to the lambda function and deployed it.
Then took the url and editted the "actions.json" file and ran the gactions command.
Then when I started testing the app in the actions console using the simulator I am getting the error "UnparseableJsonResponse API Version 2: Failed to parse JSON response string with 'INVALID_ARGUMENT' error: "error_message: Cannot find field"
Here is the code inside index.js file
'use strict';
const {actionssdk, SimpleResponse} = require('actions-on-google');
const app = actionssdk({debug: true});
app.intent('actions.intent.MAIN', (conv) => {
conv.ask("welcome");
});
app.intent('actions.intent.TEXT', async (conv, input) => {
conv.ask('You said ' + input);
});
exports.fulfillment = app
Here is the cloud watch logs from aws
2018-11-10T08:35:46.715Z 9dbb17f8-e4c3-11e8-bce3-730a5244a300
{
"errorMessage": "Cannot convert undefined or null to object",
"errorType": "TypeError",
"stackTrace": [
"Function.keys (<anonymous>)",
"Lambda.<anonymous> (/var/task/node_modules/actions-on-google/dist/framework/lambda.js:36:36)",
"Generator.next (<anonymous>)",
"/var/task/node_modules/actions-on-google/dist/framework/lambda.js:22:71",
"new Promise (<anonymous>)",
"__awaiter (/var/task/node_modules/actions-on-google/dist/framework/lambda.js:18:12)",
"/var/task/node_modules/actions-on-google/dist/framework/lambda.js:30:46",
"omni (/var/task/node_modules/actions-on-google/dist/assistant.js:44:53)"
]
}

The code changes to host it on AWS are fairly straightforward. Instead of importing the firebase-functions library and using it, you just need to establish the lambda endpoint with the dialogflow app itself. So the code might look something like:
const { dialogflow } = require('actions-on-google')
const app = dialogflow()
// Setup intent handlers with app.intent() here
exports.factsAboutGoogle = app

Related

No response from invoke container when running sam local invoke

Trying to test a basic lambda locally that runs fine in AWS but I keep getting
No response from invoke container for MyLambdaXXXXXXXX
'tsc' and 'synth' run fine and I get a proper cdk.out
The invoke command is
sam local invoke --region us-east-1 --env-vars .env.json -t ./cdk.out/my-project.template.json -e events/example.event.json MyLambdaXXXXXXXX
There is no api or anything docker related that I find in similar questions like the few listed below.
No response from invoke container when running sam local
No response from invoke container for FunctionName
https://github.com/aws/aws-sam-cli/issues/2837
The only output I see is this (no logs from even the first line of the lambda)
Invoking index.execute (nodejs14.x)
Skip pulling image and use local one: public.ecr.aws/sam/emulation-nodejs14.x:rapid-1.46.0-x86_64.
Mounting /path-to-my-project/my-project/cdk.out/asset.aaaaa9999999cd5a9f38e9c4e503cc9c9bdf8ccdc8f9999991b12b6161e99999 as /var/task:ro,delegated inside runtime container
No response from invoke container for MyLambdaXXXXXXXX
Process finished with exit code 0
If it matters my handler structure for my lambda is async
export const execute = async (sqsEvent: SQSEvent): Promise<PutEventsCommandOutput> => {
await someAsyncStuffWithDocumentDB()
}
And I'm using NodejsFunction cdk with bundling like this
bundling: {
minify: true,
sourceMap: true,
externalModules: ['aws-lambda', 'aws-sdk'],
loader: { '.pem': 'file' }, // cert for DocumentDB
},
I came across similar issue and solved it by increasing 'Timeout' from 3 to 10 in [template.yaml] file.
When you import(or require) a number of npm packages, the loading time can be pretty long, maybe 3 secs are not enough. Just my guess

How does serverless know where to find the serverless.yml?

How does npm/yarn serverless packageadded locally in a project know where to locate the serverless.yml file?
I am trying to locate the exact piece of code in the source code of serverless framework ( https://github.com/serverless/serverless), where this happens, but haven't had any luck so far.
I need to know this because my
yarn sls offline start
command does not seem to the new changes that i did in serverless.yml file.
It keeps picking the old one.
This is the code used by Serverless to load the configuration:
https://github.com/serverless/serverless/blob/master/lib/utils/getServerlessConfigFile.js#L9
Relevant excerpt:
const servicePath = srvcPath || process.cwd();
const jsonPath = path.join(servicePath, 'serverless.json');
const ymlPath = path.join(servicePath, 'serverless.yml');
const yamlPath = path.join(servicePath, 'serverless.yaml');
const jsPath = path.join(servicePath, 'serverless.js');
return BbPromise.props({
json: fileExists(jsonPath),
yml: fileExists(ymlPath),
yaml: fileExists(yamlPath),
js: fileExists(jsPath),
}).then(exists => {
Note that from the CLI servicePath is set to the current working directory.
Looking at the code, my guess is that you may have a serverless.json which takes precedence over serverless.yaml? The command serverless print will show your resolved configuration. (https://serverless.com/framework/docs/providers/aws/cli-reference/print/#print)

Configuring the Hyperledger Composer REST server with a persistent data store

I am following this tutorial
https://hyperledger.github.io/composer/integrating/deploying-the-rest-server.html
I have done all the steps. But when I run rest-server through github, it prints following stack trace.
Error
404 Cannot GET /auth/github
status: 404
Error: Cannot GET /auth/github
at raiseUrlNotFoundError (/home/praval/.nvm/versions/node/v6.11.1/lib/node_modules/composer-rest-server/node_modules/loopback/server/middleware/url-not-found.js:21:17)
I presume you installed the Github strategy via npm install -g passport-github?
If so did it create a folder /auth/github?
You are required to go to this Folder per documentation: "Authenticate to the REST server by navigating to the value of the authPath property specified in the environment variable COMPOSER_PROVIDERS. In the example above, this is http://localhost:3000/auth/github"
In my case that folder was not created. I read on Github website: https://github.com/cfsghost/passport-github
"The author of Passport-Github has not maintained the original module for a long time. Features in his module don't work since Github upgraded their API to version 3.0. We forked it and re-published it to NPM with a new name passport-github2"
I'm looking for guidance on this.
Before create private api just execute this command in your terminal.
export COMPOSER_PROVIDERS='{
"github": {
"provider": "github",
"module": "passport-github",
"clientID": "<your id>",
"clientSecret": "<your secret>",
"authPath": "/auth/github",
"callbackURL": "/auth/github/callback",
"successRedirect": "http://localhost(domain of angular app):4200(port)/home(page to redirect)",
"failureRedirect": "http://localhost(domain of angular app):4200(port)/login-github(page to redirect)""
}
}'
To check if all is fine - run command
echo $COMPOSER_PROVIDERS
After this you will see your COMPOSER_PROVIDERS value.
And after in github profile app (https://github.com/settings/applications/) you must configure "Homepage URL" (ex. http://APIdomain:3000/) and "Authorization callback URL" (ex. http://APIdomain:3000/auth/github/callback)

PhoneGap Build API for Node.js - Unable to load a custom build

I am trying to upload a zip file containing my App into PhoneGap Build by using the API with Node.js but it doesn't work, it does if I upload the file manually from the website.
After a successfully authentication with this piece of code:
pgBuild.auth({ token: phonegapBuildToken }, authenticationResponse);
in my callback I do the following:
function authenticationResponse(e, api){
unlockAndroidKeyMethod(api);
unlockiOSKeyMethod(api);
var options = {
form: {
data: {
platforms: ['android', 'ios']
},
file: './www/xxx.zip'
}
};
api.post(phonegapEndpoint + '/build', options, function(ee, data) {
console.log('## BUILD IN PROGRESS...');
console.log(ee);
console.log(data);
//waitingForPendingBuild(api);
});
}
inside the option I am pointing to the file I want to load
file: './www/xxx.zip'
the problem is that whatever I put there it doesn't get picked up, what PhoneGap Build builds is the file always the file loaded through the website.
Can I get some help, please? :)
Thanks
PS: I get no error
I have managed to solved this problem - it was a problem on how I create the zip file apparently...PhoneGap Build API don't like zip files done with gulp-zip, using archiverjs (https://archiverjs.com/docs/) solves the issue :)
Thanks

run lambda function with input parameter in serverless framework command line

I have started a aws project with help of serverless framework, but i have one question regarding run lambda function.
How can I run lambda function with input parameters? I can do it via amazon console, lambda test configuration->test event. but I cannot find a correspondning function in serverless, does anyone know?
Thanks
For the lambda part
You can use event.json file:
{
"principalId": "1234",
"inputVar": "foo"
}
and then run sls function run.
According to docs, if don't specify any stage, function will run locally, if you do specify a stage, function will run deployed code in corresponding stage. BUT the docs seems outdated, you also need to pass -d flag like:
sls function run myFunction -s dev -d
This command will invoke your deployed lambda function, with parameters from your local event.json file
Here is the source code for function run options.
For APIG integration
There are some samples in documentation.
If you don't want to use templates, you can just insert related code in your s-function.json, inside the endpoint description.
"endpoints": [
...
"requestTemplates": {
"application/json": {
"principalId": "$context.authorizer.principalId",
"apiKey": "$context.identity.apiKey",
"inputVar": "$input.json('inputVar')"
}
}
...
]
Syntax is as described in API Gateway Accessing the $input Variable doc.

Resources