Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON encoding error publishing SNS message with Boto 3

I am trying to send a simple JSON message to an Amazon SNS topic in Boto 3. However, I keep getting a _jsonparsefailure in the tag of the message and I only receive the default value. Here is my code:

    mess = {'default': 'default', 'this': 'that'}
    jmess = json.JSONEncoder().encode(mess)

    response = self.boto_client.publish(
        TopicArn = self.TopicArn,
        MessageStructure = 'json',
        Message = jmess
    )

I have also tried json.dumps(), which produces the same result.

    mess = {'default': 'default', 'this': 'that'}
    jmess = json.dumps(mess)

    response = self.boto_client.publish(
        TopicArn = self.TopicArn,
        MessageStructure = 'json',
        Message = jmess
    )

I seem to be following all of the guidelines set by the documentation, and I'm not getting an exception when I run the script. There are SQS queues that subscribe to the topic, and I am pulling the result data straight from the console.

like image 237
g_grillz Avatar asked Jan 28 '16 20:01

g_grillz


3 Answers

It turns out the message needs to look like this:

json.dumps({"default": "my default", "sqs": json.dumps({"this": "that"})})

Amazon has horrible documentation in this regard.

You can also remove the MessageStructure='json'and send just json.dumps({'this':'that'}) if you set the SQS queue to receive just the raw message. This is simply done through the console.

like image 145
g_grillz Avatar answered Nov 08 '22 23:11

g_grillz


This is how I fixed it:

message = {"record_id": "my_id", "name": "value"}
json_message = json.dumps({"default":json.dumps(message)})
sns_client.publish("topic_arn", Subject="test", MessageStructure="json", Message=json_message)

SNS expects "default" as the key which contains the message to be published.

like image 23
Raghav salotra Avatar answered Nov 09 '22 01:11

Raghav salotra


In Boto 3 (I'm using v1.4.7) this is the format:

sns.publish(TopicArn="topic_arn", Message=json.dumps({"this": "that"},ensure_ascii=False))

There isn't any need for the protocol definition, i.e. "default" unless you are delivering different structures per protocol, i.e., JSON for Lambda and HTML for email.

like image 2
irishguy Avatar answered Nov 09 '22 01:11

irishguy