Send message from Lambda to SQS in Go

Issue

I’m looking to send a message to an SQS queue from a Lambda function written in Go, which in the AWS console I have configured so that the SQS queue is connected as a Destination.

screenshot of console

The code sample I’ve seen (here) suggests I need to load a config, create a client and get a queueURL before issuing the message via a call to SendMsg. This approach works fine when running the code locally, but seems unnecessary within the Lambda given I’m connecting the SQS queue in the console. Do I need to tell my Lambda to find the queueURL when I’ve connected to it as a destination already?

As an aside, I tried this approach but was receiving the following error when running the code from within the Lambda. Invoking the code outside of a Lambda locally would find the queueURL without issue.

{
  "errorMessage": "operation error SQS: GetQueueUrl, https response error StatusCode: 400, RequestID: 2f725471-ec4e-5380-99ed-0f708c1fcfa4, AWS.SimpleQueueService.NonExistentQueue: ",
  "errorType": "OperationError"
}

This led me to look at the flip side, where I have a Lambda which is consuming from the queue and thereby has the SQS queue configured as a trigger. I simply need to iterate over the sqsEvent.Records without having to specify config, client or queueURL as I presume this is handled in the console behind the scenes, i.e.

package main

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

func handler(ctx context.Context, sqsEvent events.SQSEvent) error {

    for _, message := range sqsEvent.Records {
        fmt.Printf("The message %s for event source %s = %s \n", message.MessageId, message.EventSource, message.Body)
    }

    return nil
}

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

Is there a way of sending a message to a queue from within the Lambda without having to find the queueURL first?

Solution

I have configured so that the SQS queue is connected as a Destination.

Sending a message doesn’t need you to define a destination per se – destinations are for passing asynchronous Lambda function invocation results. Basically – if you don’t explicitly need them (and you know when you do), they won’t be what you need.

Give your Lambda permission to send messages to the queue, & use SendMessage using the AWS SDK to send messages. No destinations needed.

AWS.SimpleQueueService.NonExistentQueue

The error message suggests it’s not finding the queue, maybe double-check if you’re looking in the right region.

I simply need to iterate over the sqsEvent.Records without having to specify config, client or queueURL as I presume this is handled in the console behind the scenes, i.e.

Yes, this is abstracted away – ultimately, your Lambda function is invoked by events and setting Amazon SQS as a trigger allows it to pass events to your function.

Is there a way of sending a message to a queue from within the Lambda without having to find the queueURL first?

Let’s rephrase it as – is there a way of sending a letter to someone without having to find their address? Of course not, as we need to know where the letter needs to go.

The same concept applies to SQS queues.

Answered By – Ermiya Eskandary

Answer Checked By – Clifford M. (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.