Coder Social home page Coder Social logo

aws-lambda-go's Introduction

AWS Lambda for Go

tests build-lambda-zip Go Reference GoCard codecov

Libraries, samples, and tools to help Go developers develop AWS Lambda functions.

To learn more about writing AWS Lambda functions in Go, go to the official documentation

Getting Started

// main.go
package main

import (
	"github.com/aws/aws-lambda-go/lambda"
)

func hello() (string, error) {
	return "Hello λ!", nil
}

func main() {
	// Make the handler available for Remote Procedure Call by AWS Lambda
	lambda.Start(hello)
}

Building your function

Preparing a binary to deploy to AWS Lambda requires that it is compiled for Linux and placed into a .zip file. When using the provided, provided.al2, or provided.al2023 runtime, the executable within the .zip file should be named bootstrap. Lambda's default architecture is x86_64, so when cross compiling from a non-x86 environment, the executable should be built with GOARCH=amd64. Likewise, if the Lambda function will be configured to use ARM, the executable should built with GOARCH=arm64.

GOOS=linux GOARCH=amd64 go build -o bootstrap main.go
zip lambda-handler.zip bootstrap

For developers on Linux

On Linux, the Go compiler's default behavior is to link the output executable to the system libc for some standard library functionality (for example, DNS lookups). If the build environment is using a Linux distribution with a GNU libc version newer than the deployment environment, the application when deployed to Lambda may fail with an error like /lib64/libc.so.6: version `GLIBC_X.YZ' not found.

Most Go applications do not require linking to the system libc. This behavior can be disabled by using the CGO_ENABLED environment variable.

CGO_ENABLED=0 go build -o bootstrap main.go
zip lambda-handler.zip bootstrap

See Using CGO

For developers on Windows

Windows developers may have trouble producing a zip file that marks the binary as executable on Linux. To create a .zip that will work on AWS Lambda, the build-lambda-zip tool may be helpful.

Get the tool

go.exe install github.com/aws/aws-lambda-go/cmd/build-lambda-zip@latest

Use the tool from your GOPATH. If you have a default installation of Go, the tool will be in %USERPROFILE%\Go\bin.

in cmd.exe:

set GOOS=linux
set GOARCH=amd64
set CGO_ENABLED=0
go build -o bootstrap main.go
%USERPROFILE%\Go\bin\build-lambda-zip.exe -o lambda-handler.zip bootstrap

in Powershell:

$env:GOOS = "linux"
$env:GOARCH = "amd64"
$env:CGO_ENABLED = "0"
go build -o bootstrap main.go
~\Go\Bin\build-lambda-zip.exe -o lambda-handler.zip bootstrap

Using CGO

For applications that require CGO, the build environment must be using a GNU libc version installed compatible with the target Lambda runtime. Otherwise, execution may fail with errors like /lib64/libc.so.6: version `GLIBC_X.YZ' not found.

Lambda runtime GLIBC version
provided.al2023 2.34
provided.al2 2.26
provided and go1.x 2.17

Alternatively, Lambda supports container images as a deployment package alternative to .zip files. For more information, refer to the official documentation for working with with container images.

Deploying your functions

To deploy your function, refer to the official documentation for deploying using the AWS CLI, AWS Cloudformation, and AWS SAM.

Event Integrations

The event models can be used to model AWS event sources. The official documentation has detailed walkthroughs.

aws-lambda-go's People

Contributors

alex avatar amz-brandon avatar artempanko avatar astj avatar atsushi-ishibashi avatar bhavikkumar avatar bmoffatt avatar bwpsmith73 avatar calavera avatar carlzogh avatar deluan avatar dlsniper avatar dum0nt73 avatar ewbankkit avatar guiminyao avatar harrisonhjones avatar ianpyw avatar jmoney avatar joeke80215 avatar jspc avatar kdnakt avatar lyoung-confluent avatar philtay avatar piotrkubisa avatar roberth-k avatar shogo82148 avatar toshi0607 avatar wafuwafu13 avatar whithajess avatar zsombor-balogh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aws-lambda-go's Issues

Building for Windows

Might be helpful if you guys put in the readme that for Windows Developers you need to "set GOARCH=amd64" in addition to the "set GOOS=linux" command like this for cmd.exe.

set GOOS=linux
set GOARCH=amd64
go build -o main main.go
%USERPROFILE%\Go\bin\build-lambda-zip.exe -o main.zip main

Bug: CognitoIdentityID is empty on Lambda invoke of GO function

The CognitoIdentityID field in the lambda context structure for Go seems not to be working. These are direct invocations of lambda functions forwarded from Cloudfront. API Gateway is not being used.

I am sure the CognitoIdentity is part of my request, direct lambda calls are protected by IAM security. So I had to get through the IAM encryption check in order to invoke the lambda. I dumped my context.Context from go:

{
    "AwsRequestID": "92db745e-183c-11e8-be7d-c53e91fb11c8",
    "InvokedFunctionArn": "arn:aws:lambda:us-east-1:xxxxx:function:digi2API-dev-world",
    "Identity": {
        "CognitoIdentityID": "",
        "CognitoIdentityPoolID": ""
    },
    "ClientContext": {
        "Client": {
            "installation_id": "",
            "app_title": "",
            "app_version_code": "",
            "app_package_name": ""
        },
        "env": null,
        "custom": null
    }
}

When I make a similar call from the same front-end to a lambda written in node.js, the context looks like this, only change was editing the function name to call a different lambda.

{
    "callbackWaitsForEmptyEventLoop": true,
    "logGroupName": "/aws/lambda/digiAPI-dev-items",
    "logStreamName": "2018/02/21/[$LATEST]a8178cf4ab4a4108b285267bddd9a5d6",
    "functionName": "digiAPI-dev-items",
    "memoryLimitInMB": "512",
    "functionVersion": "$LATEST",
    "identity": {
        "cognitoIdentityId": "us-east-1:73134712-adbb-4432-8cfe-246a8eae6fab",
        "cognitoIdentityPoolId": "us-east-1:4f3f4619-737b-41ed-b0dd-8875cfcf27ab"
    },
    "invokeid": "e8e1d8dc-175e-11e8-a83c-39c3312d1082",
    "awsRequestId": "e8e1d8dc-175e-11e8-a83c-39c3312d1082",
    "invokedFunctionArn": "arn:aws:lambda:us-east-1:xxxxxxxx:function:digiAPI-dev-items
}

The example for this in the documentation also does not work for the same reason. Note the variable name is misspelled in the documentation.
https://docs.aws.amazon.com/lambda/latest/dg/lambda-dg.pdf

Accessing Invoke Context Information
Lambda functions have access to metadata about their environment and the invocation request. This
can be accessed at Package context. Should your handler include context.Context as a parameter,
Lambda will insert information about your function into the context's Value property. Note that you
need to import the lambdacontext library to access the contents of the context.Context object.
package main
import (
 "context"
 "log"
 "github.com/aws/aws-lambda-go/lambda"
 "github.com/aws/aws-lambda-go/lambdacontext"
)
func CognitoHandler(ctx context.Context) {
 lc, _ := lambdacontext.FromContext(ctx)
 log.Print(lc.Identity.CognitoPoolID)
}
func main() {
 lambda.Start(CognitoHandler)
}
In the example above, lc is the variable used to consume the information that the context object
captured and log.Print(lc.Identity.CognitoPoolID) prints that information, in this case, the
CognitoPoolID.

New release?

Would it be possible to cut a release for the new features? especially APIGatewayCustomAuthorizerRequestTypeRequest from #62 would be helpful

HTTPMethod is empty

Tried to use the events.APIGatewayProxyRequest.HTTPMethod but it returned ""

Here's the full handler

func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	fmt.Println("Received body: ", request.Body)
	switch request.HTTPMethod {
	case "POST":
		return events.APIGatewayProxyResponse{Body: request.Body, StatusCode: 200}, nil
	default: // GET
		response := events.APIGatewayProxyResponse{
			Body:       request.QueryStringParameters["value"],
			StatusCode: 200,
		}
		return response, nil
	}
}

AppSync Support

AppSync is currently in Preview, but it would be great to have support for AppSync Lambda Resolvers here. Here is the documentation.

The way I see it, is this library could support doing things as described in the docs - using field and arguments in the payload. It could support both Invoke and BatchInvoke operations, and therefore if using BatchInvoke, it would need to handle maintaining the order of the items sent in, etc.

Thoughts? I'd be willing to help out getting this done.

Request: a way to pass a parent context into lambda.Start

In porting a specimen Go lambda from a node.js "shim" based approach to this new native library, I find it's missing something from our shim-based library, which is a way to have a context.Context created in "main" made available in the handler function.

Sometimes, for logging, or whatever, it's useful to adorn a context in the main function to be used as the parent context for all event handler invocations.

One could use globals to pass context from main to the event handler, but that's not great for testing, etc.

Perhaps in addition to lambda.Start(handler) there could be lambda.StartWithContext(ctx, handler)? The passed in ctx could then be used in place of context.Background() in Function.Invoke.

handle stream error

How can i handle stream error, when an error occurs to the lambda function, the stream retry to trigger that lambda which make that the lambda stop execution if new image has been inserted to dynamodb. how can i handle this error?

Call from CodePipeline in Lambda

Hi,

I don't find anyway to structure my function so the user parameter is parsed from the Lambda Invoke in CodePipeline

User parameter in CodePipeline:

<distribID>,/*

Lambda function code:

package main

import (
	"errors"
	"strings"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"

	"github.com/aws/aws-lambda-go/lambda"
	"github.com/aws/aws-sdk-go/service/cloudfront"
)

// Response return struct
type Response struct {
	Message string `json:"message"`
	Ok      bool   `json:"ok"`
}

// ErrorBadRequest detailed message
const ErrorBadRequest = "BadRequest - Format: '<CloudfrontDistribID>,<path>'"

// OK detailed message
const OK = "Cache invalidated: "

// Handler Lambda runtime
func Handler(parameterString string) (Response, error) {

	parameters := strings.Split(parameterString, ",")

	if len(parameters) != 2 {
		return Response{Message: ErrorBadRequest, Ok: false}, errors.New(ErrorBadRequest)
	}
	cloudfrontDistribID := parameters[0]
	path := parameters[1]

	if cloudfrontDistribID == "" || path == "" {
		return Response{Message: ErrorBadRequest, Ok: false}, errors.New(ErrorBadRequest)
	}

	sess := session.Must(session.NewSession())
	svc := cloudfront.New(sess)

	newCallReference := time.Now().UTC().String()

	output, err := svc.CreateInvalidation(&cloudfront.CreateInvalidationInput{
		DistributionId: aws.String(cloudfrontDistribID),
		InvalidationBatch: &cloudfront.InvalidationBatch{
			CallerReference: aws.String(newCallReference),
			Paths: &cloudfront.Paths{
				Items:    []*string{aws.String(path)},
				Quantity: aws.Int64(1),
			},
		},
	})

	if err != nil {
		return Response{Message: err.Error(), Ok: false}, err
	}

	tempResp := OK
	tempResp += output.String()

	return Response{Message: tempResp, Ok: true}, nil
}

func main() {
	lambda.Start(Handler)
}

START RequestId: 257bc59a-06ac-11e8-bbfc-67d31ece2a2a Version: $LATEST
17:28:27
json: cannot unmarshal object into Go value of type string: UnmarshalTypeError null

How to recognize user by Authorize token

Thank you for reading this issue, the scenario is below.

User send a request by jwt.Token belong to Cogntio User Pool to API Gateway which is authorized but cannot recognize the request belonge to which user.
The "events.APIGatewayProxyResponse" doesn't provide information by default like there openId, email, etc.

How could I recognize user by Authorize token?

30 lambdas --> 30 mains?

I feel I must be missing something really obvious, so I want to check my understanding of the requirement to provide a main entry point for my lambda:

func main() { lambda.Start(MyLamb) }

For my serverless application, which happens to have 30 lambdas, do I really need to build 30 individual binaries and put them each into one big zip file to be uploaded (or, alternatively, 30 little zip files)?

Binary images from lambda via APIGateway / IsBase64Encoded behaves strangely

I am trying to return a PNG image from the lambda function, the request is received over the API Gateway.
Image is represented in the code as []byte. Here is my code:

func lambda(ctx context.Context, request events.APIGatewayProxyRequest)
(events.APIGatewayProxyResponse, error) {
contentType, contentBody, err := generateImage()
if err != nil {
...
}
return events.APIGatewayProxyResponse{StatusCode: http.StatusOK,
Body: base64.StdEncoding.EncodeToString(contentBody),
IsBase64Encoded: true,
Headers: map[string]string{"Access-Control-Allow-Origin": "'*'",
"Content-Type": "image/png" }},
nil
}

Similarly strange behavior is observed when I am returning HTML the same way (via base64.StdEncoding.EncodeToString with IsBase64Encoded). It seems that it is not being unencoded back into binary.

unmarchal DynamodbEventRecord

i know this is more like a question and not an issue, i would like to know how can i unmarchal DynamodbEventRecord into a certain struct type in golang?

Can you please provide some help to do that?

Best Regards,

Integrate repository with a CI system

Hi,

When sending PRs, it would be useful if the repository would be integrated with CI systems like CircleCI so that we can see if a PR fails or not. Thanks.

Problem With S3 Event

The S3Object struct has URLDecodedKey but it does not seem to be populated when processing request. Looking at the example event message structure this is not returned. The Key field is populated but spaces in filenames are replace with a '+'. Is this the expected behavior?

Logs from some loggers are not synced/flushed

Issue: when i use zerolog or zap loggers 60% of time logs are not synced, so they are not displayed in CloudWatch.

Code of my handler:

var handlerInitialized = false
var chiAdapter *chiadapter.ChiLambda
var logger *zerolog.Logger

func Handler(req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	if !handlerInitialized {
		logger = zerolog.New(os.Stderr)
		logger.Info("cold_start")

		api := server.NewAPI(&logger)
		chiAdapter = chiadapter.New(api.Router())
		handlerInitialized = true
	}

	return chiAdapter.Proxy(req)
}

func main() {
	lambda.Start(Handler)
}

used: https://github.com/awslabs/aws-lambda-go-api-proxy

Half of logs that comes from http Handlers and middlewares are not shown.

I found that only standard logger and https://github.com/apex/log work correctly.
I already asked this question in many places, and tried to use zap's logger.Sync() to flush, but it doesn't help.

Functions with multiple event triggers

Do you have an example of how the handler code might look like for a function that can be triggered by more than one event?

For example, let's say we have a function that can be triggered by both API Gateway and DynamoDB events.

Drop-in replacement for net/http

Any thoughts on having something like https://github.com/apex/gateway in here to act as a drop-in replacement for net/http? Happy to add some tests/refine (probably missing some stuff too) and send a pull-request.

May also be worth discussing the best way to pass the contextual information for this kind of scenario, maybe X-Something-Context: json here or more distinct fields?

KinesisFirehoseResponseRecord.Result value

Hello!
I'm tinkering with the new AWS lambda's go support. I created a very simple lambda function which (for ease of reading) simply passes-through the data.

According to the comment of KinesisFirehoseResponseRecord.Result's comment, the value should be one of TransformedStateOk, TransformedStateDropped or TransformedStateProcessingFailed.

Result string `json:"result"` // The status of the transformation. May be TransformedStateOk, TransformedStateDropped or TransformedStateProcessingFailed

Problem is there is no such constant. The most similar ones are at line 21-23

KinesisFirehoseTransformedStateOk = "TRANSFORMED_STATE_OK"

Using these constants though Firehose complains about Result not being Ok, Dropped or ProcessingFailed.

Is it correct to assume that we should use the KinesisFirehoseTransformedState* constants and that they're bugged?

Thanks

package main

import (
	"context"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

func handler(ctx context.Context, event events.KinesisFirehoseEvent) (events.KinesisFirehoseResponse, error) {
	var response = events.KinesisFirehoseResponse{}

	for _, record := range event.Records {
		// For now a simple pass-through

		var transformedRecord = events.KinesisFirehoseResponseRecord{
			RecordID: record.RecordID,
			Result:   "Ok", // Here comes the problem
			Data:     record.Data,
		}

		response.Records = append(response.Records, transformedRecord)
	}

	return response, nil
}

func main() {
	lambda.Start(handler)
}

Question: S3 access using ioutil.ReadFile

Just looking at the CodeStar go project and the handler use S3 to access the index.html and can't find how this is configured to use ioutil.ReadFile. Is there any information on this?

`func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {

index, err := ioutil.ReadFile("public/index.html")
if err != nil {
	return events.APIGatewayProxyResponse{}, err
}

return events.APIGatewayProxyResponse{
	StatusCode: 200,
	Body:       string(index),
	Headers: map[string]string{
		"Content-Type": "text/html",
	},
}, nil

}`

Problem with Custom Authorizers

I'm trying to implement a custom authorizer and so far, it has gone very well and it's all working perfectly fine.

However, the one major issue I am having is that I cannot return a custom error message if the authenticator fails. I am having the return the following for every error at the moment:

return &events.APIGatewayCustomAuthorizerResponse{}, errors.New("Unauthorized").

If I try any other error message, I get {"message": null} as the response on my client. Is there any way to customize this error message (preferably without using the AWS console as I'd like it to be automated)?

APIGatewayProxyRequest queryStringParameters does not support multiple parameter values

The URL in go's standard http.Request has a Query() accessor which returns a map[string][]string (see: https://github.com/golang/go/blob/master/src/net/url/url.go#L995). This allows one to send a request with ...&type=foo&type=bar... and get both values using http.Request.Query()["type"].

The QueryStringParameters field from APIGatewayProxyRequest on the other hand is defined as a map[string]string (see: https://github.com/aws/aws-lambda-go/blob/master/events/apigw.go#L11). Supplying ...&type=foo&type=bar... to a Lambda behind GatewayProxy only returns the last value for type - bar in this case.

A workaround is to supply the parameters as a list using a separator character as in: ...&type=foo,bar...

Can't update/delete custom resource: Invalid PhysicalResourceId

Hey there!

I have a lambda function that looks up a SSM parameter and returns it's value. This lambda function is triggered from a CloudFormation template by creating a custom resource. The CF stack launches correctly and works as expected although when I try to update or delete the stack, it fails saying "Invalid PhysicalResourceId".

I believe that the PhysicalResourceID in this block: https://github.com/aws/aws-lambda-go/blob/master/cfn/wrap.go#L33 should be set to the logStreamName (default PhysicalResourceID) if it is empty, no matter the request type. For now, I was able to get around with this by always setting the PhysicalResourceID in my Lambda function to the logStreamName.

[#76] implements the suggested change. I tested this and with this change update and delete actions work as expected.

Migrate type of Keys, NewImage and OldImage in DynamoDBStreamRecord to dynamodb.AttributeValue

Keys, NewImage and OldImage in DynamoDBStreamRecord currently have an internal DynamoDBAttributeValue type, however this is virtually the same type as AttributeValue in "github.com/aws/aws-sdk-go/service/dynamodb" but "less usable" since it doesn't have the convenience method, like Marshal and Unmarshal.

As @cmello pointed out in #54, aws-lambda-go doesn't depend on said package at the moment but I think we should explore the idea of either migrating the type and importing the SDK as a dependency, or copying the sub-packages over to this repo (don't like this idea), so we can have the same level of functionality.

For those wondering (@moedeveloper) what to do in the meantime, I found the following solution to be working quite well: https://gist.github.com/morcmarc/35194b39184977c2c44eb9fe063889a3

LexEvent - ResponseCard error

I am not sure if this is a bug.

I am using a Lambda function as fulfilment to AWS Lex. I want to send a response using the code below:

func scheduleMeeting(event events.LexEvent) (events.LexEvent, error) {

    //some code here

    response := events.LexEvent{
        DialogAction: &events.LexDialogAction{
            Type:             "Close",
            FulfillmentState: "Fulfilled",
            Message:          map[string]string{"contentType": "PlainText", "content": "Thank you!"},
        },
    }

    return response, nil
}

However, I am getting the following error:

An error has occurred: Invalid Lambda Response: Received invalid response from Lambda: Can not deserialize value of type ContentType from String "": value not one of declared Enum instance names: http://application/vnd.amazonaws.card.generic at Source: {"sessionAttributes":null,"dialogAction":{"type":"Close","fulfillmentState":"Fulfilled","message":{"content":"Thank you!","contentType":"PlainText"},"intentName":"","slots":null,"slotToElicit":"","responseCard":{"version":0,"contentType":"","genericAttachments":null}}}; line: 1, column: 239

This ContentType field and the Enum application/vnd.amazonaws.card.generic are on the ResponseCard field, which is optional according to the documentation.

build-lambda-zip command only takes one argument

The build-lambda-zip utility only takes one argument to include in the resultant zip file. There are cases where it is necessary to include additional files beyond the executable, for example we want to include a cert file that can be read by the lambda. There is no way to include that file in the zip that is built by build-lambda-zip.exe. An example of the desired behavior would be:

build-lambda-zip.exe -o test.zip test test.crt

which would result in test.zip containing both test and test.crt.

Returning error results in 502 from APIG

When the returned error value in not nil, the response results in a 502 error from API Gateway.
e.g.

func Handler(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    ...
    // some error occured
    err := errors.New("something bad happened")
    return events.APIGatewayProxyResponse{
	StatusCode: 400,
	Body:       "",
    }, err
}

This results in a 502 Bad Gateway with response:

{
    "message": "Internal server error"
}

And when using the test functionality in API Gateway:

... Execution failed due to configuration error: Malformed Lambda proxy response
Fri Apr 13 18:05:24 UTC 2018 : Method completed with status: 502

events.S3Event range

I was looking at the S3 Lambda example and I noticed that the records is a range: for _, record := range s3Event.Records {...}

I thought the Lambda events spawned a new process per event so I was wondering why there is a loop at all?

When can the handler receive multiple records? Is that possible? If so what would be the use case?

Add support for DMARC verification in SES Events

as per SES event received under the 'Receipt' struct:

      "receipt": {
        "timestamp": "2018-03-31T01:06:56.352Z",
        "processingTimeMillis": 716,
        "recipients": ["[email protected]"],
        "spamVerdict": {
          "status": "PASS"
        },
        "virusVerdict": {
          "status": "PASS"
        },
        "spfVerdict": {
          "status": "PASS"
        },
        "dkimVerdict": {
          "status": "PASS"
        },
        "dmarcVerdict": {
          "status": "PASS"
        },
        "action": {
          "type": "Lambda",
          "functionArn": "xxxxxxxxx",
          "invocationType": "RequestResponse"
        }
      }

and add the DMARC Verdict in the ses.go event?

type SimpleEmailReceipt struct {
	Recipients           []string                 `json:"recipients"`
	Timestamp            time.Time                `json:"timestamp"`
	SpamVerdict          SimpleEmailVerdict       `json:"spamVerdict"`
	DMARCVerdict         SimpleEmailVerdict       `json:"dmarcVerdict"`
	DKIMVerdict          SimpleEmailVerdict       `json:"dkimVerdict"`
	SPFVerdict           SimpleEmailVerdict       `json:"spfVerdict"`
	VirusVerdict         SimpleEmailVerdict       `json:"virusVerdict"`
	Action               SimpleEmailReceiptAction `json:"action"`
	ProcessingTimeMillis int64                    `json:"processingTimeMillis"`
}

Return response for Lex bot invalid

Seem to always hit an issue when i'm using a go runtime lambda for the fulfillment reponse.

An error has occurred: Invalid Lambda Response: Received invalid response from Lambda: Can not construct instance of IntentResponse: no String-argument constructor/factory method to deserialize from String value 

i'm returning this string from the handler function

{
  "sessionAttributes": {},
  "dialogAction": {
    "type": "Close",
    "fulfillmentState": "Fulfilled",
    "message": {
      "contentType": "PlainText",
      "content": "Hello World"
    }
  }
}

am i doing something wrong?

Unable to trigger PostConfirmation Cognito Event

Hello,

I'm trying to trigger a lambda written in Golang by Cognito event "PostConfirmation". It seems that the failure is caused by json conversion of Cognito event:

"PostConfirmation failed with error json: cannot unmarshal string into Go struct field CognitoEvent.version of type int."

Here's the Lambda that I'm trying to use:

package main

import (
	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
	"log"
)

func Handler(request events.CognitoEvent) (string, error) {
	log.Print("Received: ", request.EventType)
	return "Success", nil
}

func main() {
	lambda.Start(Handler)
}

Deployment .zip file permissions

I'm developing on Windows, and while Go allows for very easy cross-compilation, deployment is not as easy as it is shown currently in the blog.

Namely, the problem is that on Windows (even with Cygwin zip) it seems rather difficult to create a .zip that would work when uploaded to Lambda, resulting in the rather terse error:

fork/exec /var/task/handler.lambda: permission denied: PathError
null

I believe this is due to it being difficult to set the executable flag that gets embedded into the .zip file. With the flag missing, when Lambda unpacks the binary the result is a non-executable binary that gives out the error above, while no warning is raised while uploading.

Taking the exact same output (built on Windows) and chmod +x:ing in Linux and then zipping it results in a working Lambda function, as expected.

I'm not sure what the correct way to approach fixing this would be, but I would suggest going by Postel's robustness principle and being liberal in what to accept - eg. forcing the executable flag on after the handler is unpacked. This is especially because the permissions in .zip files is a rather complex issue and executable flags certainly are not at all familiar to developers on Windows, so it seems to me to be a pretty big stumbling block for a sizable share of developers.

For posterity, I triaged this by copying the required flags from the correct zip to add the required flags with archive/zip; the flags that resulted in a working .zip are;

fh := &zip.FileHeader{
	Name: "handler.lambda",
}
fh.CreatorVersion = 0x31e
fh.Flags = 0
fh.Extra = []uint8{0x55, 0x54, 0x5, 0x0, 0x3, 0x9d, 0x33, 0x5f, 0x5a, 0x75, 0x78, 0xb, 0x0, 0x1, 0x4, 0xe8, 0x3, 0x0, 0x0, 0x4, 0xe8, 0x3, 0x0, 0x0}
fh.ExternalAttrs = 0x81ed0000

Lambda's log - serialization error

Version of AWS Lambda for Go

commit 4013798

Version of Go (go version)

1.9.3

Issue

In the lambda's logs, I can see, for each message:
SerializationError: failed to decode query XML error response caused by: expected element type <ErrorResponse> but have <html>: baseError null

Steps to reproduce

Just create a lambda function which may or may not throw an error.
Then go to CloudWatchLog > Groups > /aws/lambda/your_function_here > All streams

P.S.
BTW I'm not able to read the error, should I read it from there?

Thanks

handler.validateReturns() panics on function with no return value

The validateReturns method panics with runtime: index out of range for a handler function with no return value. Tested with go v1.9.2

Adding this test case in lambda/handler_test.go:

{
	name:     "no return value should not result in error",
	expected: nil,
	handler: func() {
	},
},

results in

panic: runtime error: index out of range [recovered]
	panic: runtime error: index out of range

goroutine 18 [running]:
testing.tRunner.func1(0xc420152b40)
	/usr/local/go/src/testing/testing.go:711 +0x2d2
panic(0x138f900, 0x15f9800)
	/usr/local/go/src/runtime/panic.go:491 +0x283
reflect.(*rtype).Out(0x1369c00, 0x0, 0x1393940, 0xc420016a88)
	/usr/local/go/src/reflect/type.go:1043 +0xc7
github.com/aws/aws-lambda-go/lambda.validateReturns(0x15d3040, 0x1369c00, 0x1369c00, 0x0)
	/Users/mattman/go/src/github.com/aws/aws-lambda-go/lambda/handler.go:64 +0x1c6

Line 63 in handler.go needs to check for at least one return value before performing the type check.

	} else if handler.NumOut() > 0 {
		if !handler.Out(0).Implements(errorType) {

ResponseCard field on LexDialogAction struct should be a pointer

The ResponseCard field on LexDialogAction struct should be a pointer exactly like the Bot field on LexEvent. Currently you can not left the field "empty" so the JSON encoder adds the field which is not require and gives an error when responding to Lex, the response looks like this:
{
"dialogAction": {
"type": "Close",
"fulfillmentState": "Fulfilled",
"message": {
"content": "Your message here",
"contentType": "PlainText"
},
"responseCard": {}
}
}

But the expected response is this one:
{
"dialogAction": {
"type": "Close",
"fulfillmentState": "Fulfilled",
"message": {
"content": "Your message here",
"contentType": "PlainText"
}
}
}

The reason of this behavior is that the Marshal function (https://golang.org/pkg/encoding/json/#Marshal) does not consider an "empty struct" as a zero value, making it a pointer you just assign nil to it.

Hope this could help someone.

Is there a cloudwatch events example.

I see the cloudwatch_events.go file in the repo but there is no example for this. I have tried using the type but the import does not seem to work. My problem seems to be getting the details of the message.

Thanks, I am new to go so it could be my problem, but I think I am using thing correctly.
My use case is I am trying to use a cloudwatch_event to trigger my lambda.

Query string values cause unmarshalling error using SAM CLI 0.3.0

I'm using the SAM CLI v0.3.0 to test a Go lambda I've implemented using an API Gateway type for the template and as soon as I pass a query string value into the SAM path for one of my functions I get the error json: cannot unmarshal array into Go struct field APIGatewayProxyRequest.queryStringParameters of type string. I've tracked it down to the call at https://github.com/aws/aws-lambda-go/blob/master/lambda/handler.go#L22 that's failing because the payload it's receiving has {"queryStringParameters": {"name": ["Erik"]}} in it and https://github.com/aws/aws-lambda-go/blob/master/events/apigw.go#L11only defines it as a map[string]string.

I found issue #42 which mentions the same issue but it sounds like it's a request to support this feature that the SAM CLI has implemented and is breaking the unmarshalling?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.