向Alexa Event Gateway发送事件时遇JSON格式错误求助
Alexa Motion Sensor Skill 发送ChangeReport事件时JSON格式错误排查
问题描述
我正在为运动传感器开发Alexa Skill,尝试向Alexa Event Gateway发送Alexa.ChangeReport事件时,持续收到Malformed JSON错误。已严格遵循亚马逊《MotionSensor Interface Documentation》中的ChangeReport事件格式编写代码,但仍提示JSON格式有误。目前暂未实现令牌刷新逻辑,但已确认所用令牌有效,求排查思路。
代码示例
motion_state=get_motion_state_from_iot() acc_token = payload['state']['desired']['LWA_Access_Token'] message_id = str(uuid.uuid4()) current_time = datetime.datetime.utcnow().isoformat() + "Z" event_data = urllib.parse.urlencode( { "event": { "header": { "namespace": "Alexa", "name": "ChangeReport", "messageId": message_id, "payloadVersion": "3" }, "endpoint": { "scope": { "type": "BearerToken", "token": acc_token }, "endpointId": endpoint_id }, "payload": { "change": { "cause": { "type": "PHYSICAL_INTERACTION" }, "properties": [ { "namespace": "Alexa.MotionSensor", "name": "detectionState", "value": motion_state, "timeOfSample": current_time, "uncertaintyInMilliseconds": 0 } ] } } }, "context": { "properties": [ { "namespace": "Alexa.EndpointHealth", "name": "connectivity", "value": { "value": "OK" }, "timeOfSample": current_time, "uncertaintyInMilliseconds": 0 } ] } } ).encode("utf-8") url = "https://api.eu.amazonalexa.com/v3/events" headers = { 'Authorization': f'Bearer {acc_token}', 'Content-Type': 'application/json' } posting = urllib.request.Request(url, event_data, headers, "POST") try: with urllib.request.urlopen(posting) as response: lwa_tokens = json.loads(response.read().decode("utf-8")) return ("Success!") except HTTPError as http_error: return(f"An error occurred: {http_error.read().decode('utf-8')}")
错误信息
解码后的错误信息:
{"header":{"namespace":"System","name":"Exception","messageId":"01ca3509-734d-49ba-a89c-40cf93e2c0ae"},"payload":{"code":"INVALID_REQUEST_EXCEPTION","description":"The request was malformed."}}
排查思路
核心问题:错误使用URL编码处理JSON数据
代码中使用urllib.parse.urlencode()处理事件数据是错误的,这个方法用于生成URL查询参数格式的字符串(如key=value&key2=value2),但请求头声明了Content-Type: application/json,导致发送的内容不是合法JSON,直接触发格式错误。
正确做法是用json.dumps()将Python字典序列化为JSON字符串,再编码为utf-8:import json # 替换原有的urlencode代码段 event_data = json.dumps({ # 保留原事件字典内容不变 }).encode("utf-8")其他潜在检查点
- 确认
motion_state的值是合法枚举:DETECTED或NOT_DETECTED,自定义值会导致请求无效。 - 检查
endpoint_id与Alexa开发者控制台中注册的端点ID完全一致,注意大小写和特殊字符。 - 验证
current_time格式符合ISO 8601标准(例如2024-05-20T12:34:56.789Z),确保无额外字符。 - 确认令牌权限包含
alexa::events:write,这是发送事件的必需权限。
- 确认
内容的提问来源于stack exchange,提问作者Mohammed Bin Saleem
相关产品推荐
相关产品推荐

