使用Django Signal通过AWS SNS发邮件遇Message参数类型错误
解决Django信号中AWS SNS发送JSON消息的参数验证错误
这个问题的核心是你对SNS Message 参数的格式要求理解有偏差——当设置 MessageStructure='json' 时,Message 必须是序列化后的JSON字符串,而不是你当前传入的Python字典类型,这才触发了参数验证失败的错误。
错误原因详解
AWS SNS文档里提到的"使用JSON对象",指的是符合JSON语法的字符串,而非Python原生的dict。boto3的客户端会严格校验参数类型,直接传字典会被判定为无效类型,就会出现你看到的Invalid type for parameter Message错误。
解决方案
只需要两步就能修复:
- 导入Python内置的
json模块 - 把你要发送的消息内容用
json.dumps()转换成JSON字符串
修正后的完整代码
import boto3 import json # 新增导入json模块 from properties.models import PropertyList from django.db.models.signals import post_save, post_delete from django.dispatch import receiver @receiver(post_save, sender=PropertyList) def send_property_details(sender, instance, created, **kwargs): if created: sns = boto3.client('sns') # 构造支持多协议的消息结构,可针对不同订阅协议设置专属内容 message_payload = { # default:当没有对应协议的消息时,使用这个默认内容 "default": json.dumps({ "name": instance.title, "description": instance.description }), # 可选:如果要给邮箱订阅者发送更友好的文本格式,可以添加email字段 "email": f"新房产已创建:\n名称:{instance.title}\n描述:{instance.description}" } response = sns.publish( TopicArn='你的TopicArn值', # 填入你的实际TopicArn Message=json.dumps(message_payload), # 把整个消息结构转成JSON字符串 MessageStructure='json', Subject='New Property Created', MessageAttributes={ 'default':{ 'DataType':'String', 'StringValue':instance.title } }, ) print(response['MessageId'])
额外说明
- 如果你的所有订阅协议只需要接收相同的结构化JSON内容,可以简化消息结构,比如直接用
Message=json.dumps({"default": {"name": instance.title, "description": instance.description}}) - 确保你的SNS主题订阅的协议支持JSON格式消息,比如邮箱订阅会优先使用
message_payload里的email字段内容,如果没有则回退到default字段的内容
内容的提问来源于stack exchange,提问作者Ahmed El-Mahdy
相关产品推荐
相关产品推荐

