2

I have a single lambda function which responds to two different SQS queues invoking it (the second one is a back-off queue) and so I want to dynamically determine which queue the message came from, so that I can remove it once it has been processed.

I am able to create the EventSourceMapping to trigger the lambda from both queues, but I cannot see how I cleanly retrieve the QueueURL I need in order to perform a DeleteMessage call. I am using the AWS Golang SDK.

There is the EventSourceArn in the body of the event messages and it seems I could use GetQueueURL but that would be an additional API call.

The only way to avoid that (I can think of) is to pass both queue URLs in as environment variables and use the queue name from EventSourceArn to find it.

Is there a better way that this? Is there something hiding in the context that isn't documented?

2 Answers 2

2

You can rebuild the queue URL from its ARN which you have in the event as EventSourceARN.

package main

import (
    "context"
    "fmt"

    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
    "github.com/aws/aws-sdk-go/aws/arn"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/sqs"
)

var client *sqs.SQS

func main() {
  client = sqs.New(session.Must(session.NewSessionWithOptions(session.Options{
        SharedConfigState: session.SharedConfigEnable,
    })))
    lambda.Start(Handle)
}

func Handle(ctx context.Context, event events.SQSEvent) {  
    for _, record := range event.Records {
        // Process message
        fmt.Printf(record.Body)

        // Rebuild Queue URL from ARN 
        queueArn, _ := arn.Parse(record.EventSourceARN)
        queueUrl := fmt.Sprintf("https://sqs.%v.amazonaws.com/%v/%v", queueArn.Region, queueArn.AccountID, queueArn.Resource)

        // Delete message from queue
        client.DeleteMessage(&sqs.DeleteMessageInput{
            QueueUrl:      &queueUrl,
            ReceiptHandle: &record.ReceiptHandle,
        })
    }
}

If you are using a non-standard AWS partition (e.g. China) you will also need to change the root domain of the URL to match.

Sign up to request clarification or add additional context in comments.

Comments

1

If you are using lambda, SQS and an event-source-mapping, then you don't have to manually delete objects from sqs: When your function successfully processes a batch, Lambda deletes its messages from the queue

Just return a success code, and the message will automatically be deleted from the relevant SQS queue

1 Comment

Thanks. I guess I was trying to make sure I could delete particular messages from the batch but I don't necessarily need to.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.