2019-10-05 08:03:18 -07:00
import { IExecuteFunctions } from 'n8n-core' ;
import {
2020-10-01 05:01:39 -07:00
IDataObject ,
ILoadOptionsFunctions ,
2019-10-05 08:03:18 -07:00
INodeExecutionData ,
INodePropertyOptions ,
2020-10-01 05:01:39 -07:00
INodeType ,
INodeTypeDescription ,
2022-03-25 06:36:02 -07:00
JsonObject ,
2021-04-16 09:33:36 -07:00
NodeApiError ,
NodeOperationError ,
2019-10-05 08:03:18 -07:00
} from 'n8n-workflow' ;
2019-10-15 10:21:48 -07:00
import { awsApiRequestREST } from './GenericFunctions' ;
2019-10-05 08:03:18 -07:00
export class AwsLambda implements INodeType {
description : INodeTypeDescription = {
displayName : 'AWS Lambda' ,
name : 'awsLambda' ,
2021-06-12 12:00:37 -07:00
icon : 'file:lambda.svg' ,
2019-10-05 08:03:18 -07:00
group : [ 'output' ] ,
version : 1 ,
subtitle : '={{$parameter["function"]}}' ,
description : 'Invoke functions on AWS Lambda' ,
defaults : {
name : 'AWS Lambda' ,
} ,
inputs : [ 'main' ] ,
outputs : [ 'main' ] ,
credentials : [
{
name : 'aws' ,
required : true ,
2020-10-22 06:46:03 -07:00
} ,
2019-10-05 08:03:18 -07:00
] ,
properties : [
2019-10-15 10:24:45 -07:00
{
displayName : 'Operation' ,
name : 'operation' ,
type : 'options' ,
2022-05-20 14:47:24 -07:00
noDataExpression : true ,
2019-10-15 10:24:45 -07:00
options : [
{
name : 'Invoke' ,
value : 'invoke' ,
description : 'Invoke a function' ,
} ,
] ,
default : 'invoke' ,
} ,
2019-10-05 08:03:18 -07:00
{
2022-06-03 10:23:49 -07:00
displayName : 'Function Name or ID' ,
2019-10-05 08:03:18 -07:00
name : 'function' ,
type : 'options' ,
typeOptions : {
loadOptionsMethod : 'getFunctions' ,
} ,
2019-10-15 10:24:45 -07:00
displayOptions : {
show : {
operation : [
'invoke' ,
] ,
} ,
} ,
2019-10-05 08:03:18 -07:00
options : [ ] ,
default : '' ,
required : true ,
2022-06-03 10:23:49 -07:00
description : 'The function you want to invoke. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.' ,
2019-10-05 08:03:18 -07:00
} ,
2019-10-05 08:10:12 -07:00
{
displayName : 'Qualifier' ,
name : 'qualifier' ,
type : 'string' ,
2019-10-15 10:24:45 -07:00
displayOptions : {
show : {
operation : [
'invoke' ,
] ,
} ,
} ,
2019-10-05 08:10:12 -07:00
required : true ,
default : '$LATEST' ,
description : 'Specify a version or alias to invoke a published version of the function' ,
} ,
{
displayName : 'Invocation Type' ,
name : 'invocationType' ,
type : 'options' ,
options : [
{
2022-06-03 10:23:49 -07:00
name : 'Wait for Results' ,
2019-10-05 08:10:12 -07:00
value : 'RequestResponse' ,
description : 'Invoke the function synchronously and wait for the response' ,
} ,
{
2022-06-03 10:23:49 -07:00
name : 'Continue Workflow' ,
2019-10-05 08:10:12 -07:00
value : 'Event' ,
description : 'Invoke the function and immediately continue the workflow' ,
} ,
] ,
2019-10-15 10:24:45 -07:00
displayOptions : {
show : {
operation : [
'invoke' ,
] ,
} ,
} ,
2019-10-05 08:10:12 -07:00
default : 'RequestResponse' ,
description : 'Specify if the workflow should wait for the function to return the results' ,
} ,
2019-10-05 08:03:18 -07:00
{
displayName : 'JSON Input' ,
name : 'payload' ,
type : 'string' ,
2019-10-15 10:24:45 -07:00
displayOptions : {
show : {
operation : [
'invoke' ,
] ,
} ,
} ,
2019-10-05 08:03:18 -07:00
default : '' ,
description : 'The JSON that you want to provide to your Lambda function as input' ,
2019-10-05 08:10:12 -07:00
typeOptions : {
alwaysOpenEditWindow : true ,
} ,
2019-10-05 08:03:18 -07:00
} ,
] ,
} ;
methods = {
loadOptions : {
async getFunctions ( this : ILoadOptionsFunctions ) : Promise < INodePropertyOptions [ ] > {
const returnData : INodePropertyOptions [ ] = [ ] ;
2021-04-16 09:33:36 -07:00
const data = await awsApiRequestREST . call ( this , 'lambda' , 'GET' , '/2015-03-31/functions/' ) ;
2019-10-05 08:03:18 -07:00
2019-10-16 02:18:39 -07:00
for ( const func of data . Functions ! ) {
2019-10-05 08:03:18 -07:00
returnData . push ( {
name : func.FunctionName as string ,
value : func.FunctionArn as string ,
} ) ;
}
2021-05-07 20:31:04 -07:00
if ( data . NextMarker ) {
let marker : string = data . NextMarker ;
while ( true ) {
const dataLoop = await awsApiRequestREST . call ( this , 'lambda' , 'GET' , ` /2015-03-31/functions/?MaxItems=50&Marker= ${ encodeURIComponent ( marker ) } ` ) ;
2021-05-07 20:31:27 -07:00
2021-05-07 20:31:04 -07:00
for ( const func of dataLoop . Functions ! ) {
returnData . push ( {
name : func.FunctionName as string ,
value : func.FunctionArn as string ,
} ) ;
}
2021-05-07 20:31:27 -07:00
2021-05-07 20:31:04 -07:00
if ( dataLoop . NextMarker ) {
marker = dataLoop . NextMarker ;
} else {
break ;
}
}
}
2021-05-07 20:31:27 -07:00
2019-10-05 08:03:18 -07:00
return returnData ;
2020-10-22 06:46:03 -07:00
} ,
2019-10-05 08:03:18 -07:00
} ,
} ;
async execute ( this : IExecuteFunctions ) : Promise < INodeExecutionData [ ] [ ] > {
const items = this . getInputData ( ) ;
const returnData : IDataObject [ ] = [ ] ;
for ( let i = 0 ; i < items . length ; i ++ ) {
2021-07-19 23:58:54 -07:00
try {
const params = {
FunctionName : this.getNodeParameter ( 'function' , i ) as string ,
InvocationType : this.getNodeParameter ( 'invocationType' , i ) as string ,
Payload : this.getNodeParameter ( 'payload' , i ) as string ,
Qualifier : this.getNodeParameter ( 'qualifier' , i ) as string ,
} ;
const responseData = await awsApiRequestREST . call (
this ,
'lambda' ,
'POST' ,
` /2015-03-31/functions/ ${ params . FunctionName } /invocations?Qualifier= ${ params . Qualifier } ` ,
params . Payload ,
{
'X-Amz-Invocation-Type' : params . InvocationType ,
'Content-Type' : 'application/x-amz-json-1.0' ,
} ,
) ;
2019-10-05 08:03:18 -07:00
2022-03-25 06:36:02 -07:00
if ( responseData !== null && responseData ? . errorMessage !== undefined ) {
2021-07-19 23:58:54 -07:00
let errorMessage = responseData . errorMessage ;
2019-10-16 02:18:39 -07:00
2021-07-19 23:58:54 -07:00
if ( responseData . stackTrace ) {
errorMessage += ` \ n \ nStack trace: \ n ${ responseData . stackTrace } ` ;
}
2019-10-16 02:18:39 -07:00
2021-07-19 23:58:54 -07:00
throw new NodeApiError ( this . getNode ( ) , responseData ) ;
} else {
returnData . push ( {
result : responseData ,
} as IDataObject ) ;
}
} catch ( error ) {
if ( this . continueOnFail ( ) ) {
2022-03-25 06:36:02 -07:00
returnData . push ( { error : ( error as JsonObject ) . message } ) ;
2021-07-19 23:58:54 -07:00
continue ;
}
throw error ;
2019-10-05 13:17:23 -07:00
}
2019-10-05 08:03:18 -07:00
}
return [ this . helpers . returnJsonArray ( returnData ) ] ;
}
}