My goal is to check if a Cognito token is valid and not expired. I found this interesting and friendly package.
https://www.npmjs.com/package/verify-cognito-token
I have already implemented it as an AWS lambda function, but for some reason I'm getting an error response.
//required params
const params = {
region: '<your-aws-region>',
userPoolId: '<your-user-pool-id>'
}
//optional claims examples
const claims = {
aud: '<your-app-client-id>',
email_verified: true,
auth_time: time => time <= 1524588564,
'cognito:groups': groups => groups.includes('Admins')
}
const Verifier = require('verify-cognito-token');
const verifier = new Verifier(params, claims);
verifier.verify(token)
.then(result =>{
//result will be `true` if token is valid, non-expired, and has matching claims
//result will be `false` if token is invalid, expired or fails the claims check
})
ERROR RESPONSE:
Response: { "errorMessage": "RequestId:
4f8d8756-c097-11e8-8adf-6f88f5e6d44a Process exited before completing
request" }
Request ID: "4f8d8756-c097-11e8-8adf-6f88f5e6d44a"
Function Logs: START RequestId: 4f8d8756-c097-11e8-8adf-6f88f5e6d44a
Version: $LATEST
> 2018-09-25T07:47:54.317Z 4f8d8756-c097-11e8-8adf-6f88f5e6d44a /var/task/node_modules/verify-cognito-token/index.js:6
async function fetchKeys() {
^^^^^^^^ SyntaxError: Unexpected token function
at createScript (vm.js:56:10)
at Object.runInThisContext (vm.js:97:10)
at Module._compile (module.js:542:28)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at exports.handler (/var/task/index.js:17:22) END RequestId: 4f8d8756-c097-11e8-8adf-6f88f5e6d44a REPORT RequestId:
4f8d8756-c097-11e8-8adf-6f88f5e6d44a Duration: 191.85 ms Billed
Duration: 200 ms Memory Size: 128 MB Max Memory Used: 19 MB
RequestId: 4f8d8756-c097-11e8-8adf-6f88f5e6d44a Process exited before
completing request
The problem was with Node 6.10.
The Lambda runtime environment should be set to Node 8.10 or higher to support async functions.
Related
I am using AWS Lambda to host a nodeJs service that fetch my open invoices on Stripe and execute a payment and update my database.
The problem is that most of the time, but not all the time (sometimes everything goes how it should), it hang on the call of invoice list and do nothing.
Here's the part of the code where log stops :
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY, {
maxNetworkRetries: 1,
timeout: 2000
});
[other imports]
const microservice = async (event, context, callback) => {
[some code including database connection]
console.log('retrieving all open invoices...')
let invoices;
try {
invoices = await stripe.invoices.list({
status: 'open',
limit: 100,
});
console.log(invoices.data.length + ' data retrieved.');
} catch (error) {
console.log('Unable fetch stripe invoices : ', error);
console.log('Exiting due to stripe connection error.');
reports.push(new Report('Unable fetch stripe invoices', 'ERROR'));
return {
statusCode: 500,
};
}
[code that process invoices]
return {};
};
module.exports.microservice = microservice;
And here the log output :
START RequestId: d628aa1e-dee6-4cc6-9ce0-f7c11cf73249 Version: $LATEST
2021-10-26T00:04:05.741Z d628aa1e-dee6-4cc6-9ce0-f7c11cf73249 INFO Connecting to database...
2021-10-26T00:04:05.929Z d628aa1e-dee6-4cc6-9ce0-f7c11cf73249 INFO Executing (default): SELECT 1+1 AS result
2021-10-26T00:04:05.931Z d628aa1e-dee6-4cc6-9ce0-f7c11cf73249 INFO Connection has been established successfully.
2021-10-26T00:04:05.931Z d628aa1e-dee6-4cc6-9ce0-f7c11cf73249 INFO retrieving all open invoices...
END RequestId: d628aa1e-dee6-4cc6-9ce0-f7c11cf73249
REPORT RequestId: d628aa1e-dee6-4cc6-9ce0-f7c11cf73249 Duration: 15015.49 ms Billed Duration: 15000 ms Memory Size: 400 MB Max Memory Used: 40 MB
2021-10-26T00:04:20.754Z d628aa1e-dee6-4cc6-9ce0-f7c11cf73249 Task timed out after 15.02 seconds
And when it gooes all right it's like that :
START RequestId: e5fb6b08-adf9-433f-b1da-fd9ec29dde31 Version: $LATEST
2021-10-25T14:35:03.369Z e5fb6b08-adf9-433f-b1da-fd9ec29dde31 INFO Connecting to database...
2021-10-25T14:35:03.590Z e5fb6b08-adf9-433f-b1da-fd9ec29dde31 INFO Executing (default): SELECT 1+1 AS result
2021-10-25T14:35:03.600Z e5fb6b08-adf9-433f-b1da-fd9ec29dde31 INFO Connection has been established successfully.
2021-10-25T14:35:03.600Z e5fb6b08-adf9-433f-b1da-fd9ec29dde31 INFO retrieving all open invoices...
2021-10-25T14:35:04.011Z e5fb6b08-adf9-433f-b1da-fd9ec29dde31 INFO 0 data retrieved.
2021-10-25T14:35:04.011Z e5fb6b08-adf9-433f-b1da-fd9ec29dde31 INFO Everything went smoothly !
END RequestId: e5fb6b08-adf9-433f-b1da-fd9ec29dde31
REPORT RequestId: e5fb6b08-adf9-433f-b1da-fd9ec29dde31 Duration: 646.58 ms Billed Duration: 647 ms Memory Size: 400 MB
I don't get why it hangs with no error or log...
Network issues can happen due to various reasons. In your case, what you can try doing is to reduce the limit (e.g. limit : 30) and set your client library to retry the connection again by setting maxNetworkRetries : 3 or number that fits your application. When this is set, Stripe will retry the connection when the timeout error occurs.
This is a perfect match for Step functions use cases. It will allow you to orchestrate the steps of getting the invoices and processing them and easily design a retry mechanism in case of errors.
It is not really a solution, but what is causing the issue is that Stripe take a very long time to return less than 100 results.
We found workaround in order to not fetch this list.
I am working in AWS GovCloud I have the following configuration in AWS Lambda:
A Lambda function which decodes a payload
A Kinesis Stream set as a trigger for the aforementioned function
A Lambda Destination (we have tried Lambda functions as well as SQS, SNS)
No matter the configuration, I cannot seem to get Lambda to trigger the destination function (or queue in the event of SQS).
Here is the current Lambda Function. I have tried many permutations of the result/return payload without avail.
import base64
import json
def lambda_handler(event, context):
#print("Received event: " + json.dumps(event, indent=2))
for record in event['Records']:
payload = base64.b64decode(record['kinesis']['data']).decode('utf-8', 'ignore')
print("Success")
result = {
"statusCode": 202,
"headers": {
#'Content-Type': 'application/json',
},
"body": '{payload}'
}
return json.dumps(result)
I then send a message to Kinesis with the AWS CLI (I have noted that "Test" in the console does not observe desintations as per Jared Short ).
Every 0.1s: aws kinesis put-records --stream-name test-stream --records Data=SGVsbG8sIHRoaXMgaXMgYSB0ZXN0IGZyb20gdGhlIEFXUyBDTEkh,PartitionKey=partitionkey1 Thu Jul 8 19:03:54 2021
{
"FailedRecordCount": 0,
"Records": [
{
"SequenceNumber": "49619938447946944252072058244333476686328287240252293122",
"ShardId": "shardId-000000000000"
}
]
}
Using Cloudwatch metrics and logs I am able to observe the function being triggered by the messages sent to Kinesis every .1 second.
The metrics charts indicate a success (as I expect).
Here is an example log from Cloudwatch:
START RequestId: 0cf3fb87-06e6-4e35-9de8-b30147e7be9d Version: $LATEST
Loading function
Success
END RequestId: 0cf3fb87-06e6-4e35-9de8-b30147e7be9d
REPORT RequestId: 0cf3fb87-06e6-4e35-9de8-b30147e7be9d Duration: 1.27 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 51 MB Init Duration: 113.64 ms
START RequestId: e663fa4a-2d0b-42d6-9e38-599712b71101 Version: $LATEST
Success
END RequestId: e663fa4a-2d0b-42d6-9e38-599712b71101
REPORT RequestId: e663fa4a-2d0b-42d6-9e38-599712b71101 Duration: 1.04 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 51 MB
START RequestId: b1373bbe-d2c6-49fb-a71f-dcedaf9210eb Version: $LATEST
Success
END RequestId: b1373bbe-d2c6-49fb-a71f-dcedaf9210eb
REPORT RequestId: b1373bbe-d2c6-49fb-a71f-dcedaf9210eb Duration: 0.98 ms Billed Duration: 1 ms Memory Size: 128 MB Max Memory Used: 51 MB
START RequestId: e0382653-9c33-44d6-82a7-a82f0f416297 Version: $LATEST
Success
END RequestId: e0382653-9c33-44d6-82a7-a82f0f416297
REPORT RequestId: e0382653-9c33-44d6-82a7-a82f0f416297 Duration: 1.05 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 51 MB
START RequestId: f9600ef5-419f-4271-9680-7368ccc5512d Version: $LATEST
Success
However, viewing the cloudwatch logs/metrics for the destination lambda function or SQS queue clearly show that the destination is not being triggered.
Over the course of troubleshooting, I have over-provisioned IAM policies to the Lambda function execution role so I am fairly confident that it is not an IAM related issue. Additionally, both functions are sharing the same execution role.
One thing I am not clear on after reviewing AWS documentation and 3rd party information is the criteria by which AWS determines success or failure for a given function. I am currently researching the invokation docs in search of what might be wrong here - but my interpretation is that AWS knows our function is successful based on the above Cloudwatch metrics showing a 100% success rate.
Does anyone know what I am doing wrong or how to try to troubleshoot the destination trigger for lambda?
Edit: As pointed out, the code is not correct for multiple record events. This is a function of senseless troubleshooting/changes to the code to get the Destination to trigger. Even something as simple as this does not invoke the destination.
import base64
import json
def lambda_handler(event, context):
#print("Received event: " + json.dumps(event, indent=2))
# for record in event['Records']:
# payload = base64.b64decode(record['kinesis']['data']).decode('utf-8', 'ignore')
# print("Success")
# result = {
# "statusCode": 202,
# "headers": {
# 'Content-Type': 'application/json',
# },
# "body": '{"Success":True, payload}'
# }
return { "result": "OK" }
So, the question: Can someone demonstrate it is possible to have a Kinesis Stream Event Source Trigger a Lambda Function which successfully triggers a Lambda destination in AWS Govcloud?
I'm trying to implement a Custom Resource for the first time. Whenever I try to deploy the containing stack, creation of the Custom Resource fails with "Response is not valid JSON", but I'm not sure why.
My Custom Resource code is below:
import json
import os
import requests
import logging
# https://stackoverflow.com/questions/37703609
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)
def handler(event, context):
try:
log.debug(f'DEBUG - called!')
log.info(f'Event: {event}')
if event['RequestType'] in ['Create', 'Update']:
pass
# I _will_ have logic here eventually - when this is working!
else:
log.info('Non-create/update RequestType')
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref-responses.html
responseData = dict(
{
'Status': 'SUCCESS',
'PhysicalResourceId': event['PhysicalResourceId']
if 'PhysicalResourceId' in event
else context.log_stream_name
},
**{key: event[key] for key in
['StackId', 'RequestId', 'LogicalResourceId']}
)
log.debug(f'Response data: {responseData}')
requests.put(event['ResponseURL'], data=responseData)
except Exception as e:
log.error(f'Lambda failed! {e}')
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref-responses.html
responseData = dict(
{
'Status': 'FAILED',
'Reason': f'See logs in {context["logStreamName"]}',
'PhysicalResourceId': event['PhysicalResourceId']
if 'PhysicalResourceId' in event
else context.log_stream_name,
},
**{key: event.get(key, '') for key in
['StackId', 'RequestId', 'LogicalResourceId']}
)
log.debug(f'Response data: {responseData}')
requests.put(event['ResponseURL'], data=responseData)
And some example log messages from a Create/Delete loop are below:
START RequestId: f151f270-acc6-4cff-b4c0-0eafaf4e5fef Version: $LATEST
[DEBUG] 2021-03-22T19:29:09.33Z f151f270-acc6-4cff-b4c0-0eafaf4e5fef DEBUG - called!
[INFO] 2021-03-22T19:29:09.33Z f151f270-acc6-4cff-b4c0-0eafaf4e5fef Event: {'RequestType': 'Create', 'ServiceToken': 'arn:aws:lambda:us-east-1:119281758091:function:prod-stage-ApplicationSta-FetchCommitHistoryFuncti-T7Z15V6TDZSO', 'ResponseURL': 'https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A119281758091%3Astack/prod-stage-ApplicationStack/94d24fa0-8b44-11eb-a285-0ec6977a61f1%7CFetchCommitsCustomResource%7C1d80a8f0-f72c-4e50-8039-6c0509dd24ee?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20210322T192907Z&X-Amz-SignedHeaders=host&X-Amz-Expires=7200&X-Amz-Credential=AKIA6L7Q4OWT3GW5BT7K%2F20210322%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=4cc0d2590330f42e8928bdfc2bf5a30c31bfb6228d681e11acf25ef17b8dde2c', 'StackId': 'arn:aws:cloudformation:us-east-1:119281758091:stack/prod-stage-ApplicationStack/94d24fa0-8b44-11eb-a285-0ec6977a61f1', 'RequestId': '1d80a8f0-f72c-4e50-8039-6c0509dd24ee', 'LogicalResourceId': 'FetchCommitsCustomResource', 'ResourceType': 'AWS::CloudFormation::CustomResource', 'ResourceProperties': {'ServiceToken': 'arn:aws:lambda:us-east-1:119281758091:function:prod-stage-ApplicationSta-FetchCommitHistoryFuncti-T7Z15V6TDZSO'}}
[DEBUG] 2021-03-22T19:29:09.293Z f151f270-acc6-4cff-b4c0-0eafaf4e5fef Response data: {'Status': 'SUCCESS', 'PhysicalResourceId': '2021/03/22/[$LATEST]8801d1d794c04d25ad31fa43223cbe93', 'StackId': 'arn:aws:cloudformation:us-east-1:119281758091:stack/prod-stage-ApplicationStack/94d24fa0-8b44-11eb-a285-0ec6977a61f1', 'RequestId': '1d80a8f0-f72c-4e50-8039-6c0509dd24ee', 'LogicalResourceId': 'FetchCommitsCustomResource'}
END RequestId: f151f270-acc6-4cff-b4c0-0eafaf4e5fef
REPORT RequestId: f151f270-acc6-4cff-b4c0-0eafaf4e5fef Duration: 444.73 ms Billed Duration: 445 ms Memory Size: 128 MB Max Memory Used: 61 MB Init Duration: 463.55 ms
START RequestId: 616f7c98-1d76-4459-96d3-6257c5620a99 Version: $LATEST
[DEBUG] 2021-03-22T19:29:20.640Z 616f7c98-1d76-4459-96d3-6257c5620a99 DEBUG - called!
[INFO] 2021-03-22T19:29:20.640Z 616f7c98-1d76-4459-96d3-6257c5620a99 Event: {'RequestType': 'Delete', 'ServiceToken': 'arn:aws:lambda:us-east-1:119281758091:function:prod-stage-ApplicationSta-FetchCommitHistoryFuncti-T7Z15V6TDZSO', 'ResponseURL': 'https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A119281758091%3Astack/prod-stage-ApplicationStack/94d24fa0-8b44-11eb-a285-0ec6977a61f1%7CFetchCommitsCustomResource%7C85da252d-1d0d-4fe5-84eb-755f1e6dc646?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20210322T192920Z&X-Amz-SignedHeaders=host&X-Amz-Expires=7200&X-Amz-Credential=AKIA6L7Q4OWT3GW5BT7K%2F20210322%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=0bd2e0a28783980b9014289cd852bf02252cdf5cd11f4405d00707002e6e39e9', 'StackId': 'arn:aws:cloudformation:us-east-1:119281758091:stack/prod-stage-ApplicationStack/94d24fa0-8b44-11eb-a285-0ec6977a61f1', 'RequestId': '85da252d-1d0d-4fe5-84eb-755f1e6dc646', 'LogicalResourceId': 'FetchCommitsCustomResource', 'PhysicalResourceId': 'prod-stage-ApplicationStack-FetchCommitsCustomResource-1VTI0Q0VKIJDM', 'ResourceType': 'AWS::CloudFormation::CustomResource', 'ResourceProperties': {'ServiceToken': 'arn:aws:lambda:us-east-1:119281758091:function:prod-stage-ApplicationSta-FetchCommitHistoryFuncti-T7Z15V6TDZSO'}}
[INFO] 2021-03-22T19:29:20.640Z 616f7c98-1d76-4459-96d3-6257c5620a99 Non-create/update RequestType
[DEBUG] 2021-03-22T19:29:20.640Z 616f7c98-1d76-4459-96d3-6257c5620a99 Response data: {'Status': 'SUCCESS', 'PhysicalResourceId': 'prod-stage-ApplicationStack-FetchCommitsCustomResource-1VTI0Q0VKIJDM', 'StackId': 'arn:aws:cloudformation:us-east-1:119281758091:stack/prod-stage-ApplicationStack/94d24fa0-8b44-11eb-a285-0ec6977a61f1', 'RequestId': '85da252d-1d0d-4fe5-84eb-755f1e6dc646', 'LogicalResourceId': 'FetchCommitsCustomResource'}
END RequestId: 616f7c98-1d76-4459-96d3-6257c5620a99
REPORT RequestId: 616f7c98-1d76-4459-96d3-6257c5620a99 Duration: 174.97 ms Billed Duration: 175 ms Memory Size: 128 MB Max Memory Used: 61 MB
The JSON looks valid to me (in particular, PhysicalResourceId is non-empty, which was an issue when I was first fetching it with just event['PhysicalResourceId']. What's the issue?
I think you may need to convert the dictionary into a json string in your requests.put.
Try something like:
requests.put(event['ResponseURL'], data=json.dumps(responseData))
I had a simple Serverless website running in AWS lambda using node serverless deploy, I then added more stuff to the site and updated to the latest version of serverless, now when I deploy the site and visit the URL I get:
{"message": "Internal server error"}
When I visit the lambda console I get:
{
"errorType": "Runtime.ImportModuleError",
"errorMessage": "Error: Cannot find module './dist/server'",
"trace": [
"Runtime.ImportModuleError: Error: Cannot find module './dist/server'",
" at _loadUserApp (/var/runtime/UserFunction.js:100:13)",
" at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)",
" at Object.<anonymous> (/var/runtime/index.js:45:30)",
" at Module._compile (internal/modules/cjs/loader.js:778:30)",
" at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)",
" at Module.load (internal/modules/cjs/loader.js:653:32)",
" at tryModuleLoad (internal/modules/cjs/loader.js:593:12)",
" at Function.Module._load (internal/modules/cjs/loader.js:585:3)",
" at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)",
" at startup (internal/bootstrap/node.js:283:19)"
]
}
Any idea how to fix this?
More Info
Based on #Amit Baranes comment below which references this SO post here is a Angular site. I don't quite understand what I need to change the handler name to to match my site structure. I am not bundling the files into a .zip myself, but am running the serverless deploy command through node:
Here is the website serverless.yml
# generated by #ng-toolkit/serverless
service: serverless-site
plugins:
- serverless-apigw-binary
provider:
name: aws
runtime: nodejs10.x
memorySize: 192
timeout: 10
stage: production
region: us-east-1
package:
exclude:
- src/**
- node_modules/**
- firebug-lite/**
- e2e/**
- coverage/**
- '!node_modules/aws-serverless-express/**'
- '!node_modules/binary-case/**'
- '!node_modules/type-is/**'
- '!node_modules/media-typer/**'
- '!node_modules/mime-types/**'
- '!node_modules/mime-db/**'
custom:
apigwBinary:
types:
- '*/*'
functions:
api:
handler: lambda.universal
events:
- http: ANY {proxy+}
- http: ANY /
Here is my project file structure (starting inside the src directory) for the website.
Here is the website lambda function when it is deployed:
Since the function didn't have a server.js. I attempted to create is by modifying server.ts and putting it in the folder with no luck:
// generated by Paul
//import 'zone.js/dist/zone-node';
//import 'reflect-metadata';
var express =require('express');
var cors= require('cors');
var compression =require('compression');
var join=require('path').join;
export const app = express();
app.use(compression());
app.use(cors());
const DIST_FOLDER = join(process.cwd(), 'dist/serverless-site');
app.get('*.*', express.static(join(DIST_FOLDER), {
maxAge: '1y'
}));
app.get('/*', (req, res) => {
res.sendFile(join(DIST_FOLDER + '/index.html'));
});
So it seems that server.js is not created in the dist folder.
I got it working by running npm run build:server:prod before serverless deploy
The relevant line in my package.json looks as follows:
"build:server:serverless": "webpack --config webpack.server.config.js"
This is probably not the right way to do it, but it solved the issue of not finding ./dist/server and got me to the next error:
{
"errorType": "TypeError",
"errorMessage": "express is not a function",
"stack": [
"TypeError: express is not a function",
" at Object.<anonymous> (/var/task/dist/server.js:9231:15)",
" at __webpack_require__ (/var/task/dist/server.js:21:30)",
" at /var/task/dist/server.js:85:18",
" at Object.<anonymous> (/var/task/dist/server.js:88:10)",
" at Module._compile (internal/modules/cjs/loader.js:778:30)",
" at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)",
" at Module.load (internal/modules/cjs/loader.js:653:32)",
" at tryModuleLoad (internal/modules/cjs/loader.js:593:12)",
" at Function.Module._load (internal/modules/cjs/loader.js:585:3)",
" at Module.require (internal/modules/cjs/loader.js:692:17)"
]
}
I got the express error fixed by setting esModuleInterop = false in the tsconfig file, thanks to AWS Serverless Lambda + Angular - TypeError: express is not a function
I do see you are using the ng-toolkit package in order to provide universal + serverless for your Angular App.
Based on that, I do think you are receiving such error due to either bad config on latest version of the package, which includes some bugs on the server file along with mismatch with the Angular/Universal package.
I do recommend checking out my sample repo in the meantime Example Angular ng-toolkit, which already fixes that.
Just to point out: this is caused by webpack.config option externals which was introduced on latest express-engine schematic of the Angular Universal packages. Commenting that line, will fix your issue.
The reason is still unknown for me at the moment but hopefully I will bring my findings on this topic.
Cheers!
I have recently started Lambda function development on AWS. When try to import a JavaScript file I am getting the following error,and I have also used DynamoDb
module initialization error: TypeError
at Object.<anonymous> (/var/task/index.js:14:16)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
This is my code which I have zipped along with node modules and package.json
const alexaSDK = require('alexa-sdk');
const awsSDK = require('aws-sdk');
const promisify = require('es6-promisify');
awsSDK.config.update({
region: "us-west"
});
//const appId = 'REPLACE WITH YOUR SKILL APPLICATION ID';
const recipesTable = 'Recipes';
const docClient = new awsSDK.DynamoDB.DocumentClient();
// convert callback style functions to promises
const dbScan = promisify(docClient.scan, docClient);
const dbGet = promisify(docClient.get, docClient);
const dbPut = promisify(docClient.put, docClient);
const dbDelete = promisify(docClient.delete, docClient);
I have installed everything that is needed.Could anyone help with this error.