Take care, messages received by SQS look different if sent by SNS


« Back to overview

A good practice is to send messages to SNS, and then connect one or more SQS queue to receive and handle the message.

When you publish message payloads this way, the message as received by SQS looks different compared to when you send the message directly, if RawMessageDelivery is set to off.

You should be aware of this, you should NOT expect the message you send to sns to appear unmodified in the sqs message body. Also you should take care not to mix sending messages to the sqs queue by direct means and through sns - this may easily lead to confusion about the schema of the expected message in sqs.

Below, it is assumed that the message body is always 'foobar'.
I used localstack for testing.


The message received by SQS when you send directly to SQS

# send the message example
aws sqs send-message --queue-url=http://localstack:4566/000000000042/test --message-body=foobar

# receive the message example
aws sqs receive-message --queue-url=http://localstack:4566/000000000042/test

# output
{
    "Messages": [
        {
            "MessageId": "c1a2cf61-5290-40d8-9242-0070be7f1f0c",
            "ReceiptHandle": "MDE4MjM5Y2QtOWQ2Yy00MDM1LWJlNzktM2NjN2MyOGZhNzRlIGFybjphd3M6c3FzOmV1LWNlbnRyYWwtMTowMDAwMDAwMDAwNDI6dGVzdCBjMWEyY2Y2MS01MjkwLTQwZDgtOTI0Mi0wMDcwYmU3ZjFmMGMgMTY5MTI2MTY5Ni44OTE0MDI3",
            "MD5OfBody": "3858f62230ac3c915f300c664312c63f",
            "Body": "foobar"
        }
    ]
}

The message received by SQS when you send through SQS

# send the message to sqs
aws sns publish --topic-arn arn:aws:sns:eu-central-1:000000000042:test-topic --message "foobar"

# receive the message from the queue subscribed to sqs
{
    "Messages": [
        {
            "MessageId": "dbe45d55-278b-4f9c-ab48-18cb2fd67cbb",
            "ReceiptHandle": "NTNlNDczODUtZDRjZC00ZjEzLWJlNTAtYjBiY2M3YzI2Nzk3IGFybjphd3M6c3FzOmV1LWNlbnRyYWwtMTowMDAwMDAwMDAwNDI6dGVzdCBkYmU0NWQ1NS0yNzhiLTRmOWMtYWI0OC0xOGNiMmZkNjdjYmIgMTY5MTI2MTc4OS43MjA4MDU0",
            "MD5OfBody": "2bd4d24dfe77e02aefe17831460a5c0f",
            "Body": "{\"Type\": \"Notification\", \"MessageId\": \"ec7a5a24-b4fc-4460-a913-25f281029ee9\", \"TopicArn\": \"arn:aws:sns:eu-central-1:000000000042:test-topic\", \"Message\": \"foobar\", \"Timestamp\": \"2023-08-05T18:56:20.10
6Z\", \"SignatureVersion\": \"1\", \"Signature\": \"EXAMPLEpH+..\", \"SigningCertURL\": \"https://sns.us-east-1.amazonaws.com/SimpleNotificationService-0000000000000000000000.pem\", \"UnsubscribeURL\": \"http://localhost:4566/?Action=Unsub
scribe&SubscriptionArn=arn:aws:sns:eu-central-1:000000000042:test-topic:a77920fb-e548-4952-9091-3a97ac28ccf6\"}"
        }
    ]
}

As you can see, the body of the sqs message now contains a json encoded string of the SNS notification.
When this string is decoded, the SNS notification is exposed and you can get the body/payload from that decoded message.

Below is the json decoded message in the body of the SQS message:


{
   "Type":"Notification",
   "MessageId":"ec7a5a24-b4fc-4460-a913-25f281029ee9",
   "TopicArn":"arn:aws:sns:eu-central-1:000000000042:test-topic",
   "Message":"foobar",
   "Timestamp":"2023-08-05T18:56:20.10
6Z",
   "SignatureVersion":"1",
   "Signature":"EXAMPLEpH+..",
   "SigningCertURL":"https://sns.us-east-1.amazonaws.com/SimpleNotificationService-0000000000000000000000.pem",
   "UnsubscribeURL":"http://localhost:4566/?Action=Unsub
scribe&SubscriptionArn=arn:aws:sns:eu-central-1:000000000042:test-topic:a77920fb-e548-4952-9091-3a97ac28ccf6"
}

By the way....

For those interested a show log how I created the sns topic, sqs queue and connected them, through localstack.

Localstack is a great way to test AWS services in a sandbox running on your own dev computer.


awslocal sns create-topic --name test-topic
awslocal sqs create-queue --queue=test

# get the sqs queue arn (=arn:aws:sqs:eu-central-1:000000000042:test)
awslocal sqs get-queue-attributes --queue-url http://localstack:4566/000000000042/test --attribute-names QueueArn

# subscribe the sqs queue to the sns topic
awslocal sns subscribe --topic-arn arn:aws:sns:eu-central-1:000000000042:test-topic --protocol sqs --notification-endpoint arn:aws:sqs:eu-central-1:000000000042:test