首页 > 解决方案 > 当我使用 PHP curl 向 Google Nest 设备的 SDM API 发送命令时出现“收到无效的 JSON 有效负载”错误

问题描述

我喜欢使用 SDM API 的命令功能。我必须在 PHP 中执行 Google 文档需要以下语法:

curl -X POST \
  'https://smartdevicemanagement.googleapis.com/v1/enterprises/project-id/devices/device-id:executeCommand' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer access-token' \
  --data-raw '{
    "command" : "sdm.devices.commands.CameraLiveStream.GenerateRtspStream",
    "params" : {}
  }'

我的 PHP 代码如下所示:

$sub ['eventId'] = $event_id;
$PostData_array = array('command' => "sdm.devices.commands.CameraLiveStream.GenerateRtspStream" ,
                'params' => $sub               
                );
$PostData = json_encode ($PostData_array);


$curl_handle=curl_init();
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, array('Accept: application/json'));
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, array('Authorization: Bearer '.$access_token ));
curl_setopt($curl_handle, CURLOPT_POST, true);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $PostData);
curl_setopt($curl_handle, CURLOPT_URL,$url);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);  
$fileContent = curl_exec($curl_handle);
curl_close($curl_handle);

此命令生成以下错误(我将事件 ID 替换为 XYZ):

Array
(
    [error] => Array
        (
            [code] => 400
            [message] => Invalid JSON payload received. Unknown name "{"command":"sdm.devices.commands.CameraLiveStream.GenerateRtspStream","params":{"eventId":"XYZ...."}}": Cannot bind query parameter. Field '{"command":"sdm' could not be found in request message.
            [status] => INVALID_ARGUMENT
            [details] => Array
                (
                    [0] => Array
                        (
                            [@type] => type.googleapis.com/google.rpc.BadRequest
                            [fieldViolations] => Array
                                (
                                    [0] => Array
                                        (
                                            [description] => Invalid JSON payload received. Unknown name "{"command":"sdm.devices.commands.CameraLiveStream.GenerateRtspStream","params":{"eventId":"XYZ..."}}": Cannot bind query parameter. Field '{"command":"sdm' could not be found in request message.
                                        )

                                )

                        )

                )

        )

)

我已经完成了以下测试:

Google 提供了一个终端功能,它允许我输入文档中描述的原始语法(见上文),而无需依赖 PHP Curl。

成功手动测试后,我使用我的 PHP 代码创建 RAW 数据:

$sub ['eventId'] = $event_id;
$PostData_array = array('command' => "sdm.devices.commands.CameraLiveStream.GenerateRtspStream" ,
                'params' => $sub               
                );

$PostData = json_encode ($PostData_array);

和网址:

 $url = 'https://smartdevicemanagement.googleapis.com/v1/enterprises/'.$project_id.'/devices/'.$device_id.':executeCommand'; 

我手动将字符串复制到这个结构中:

curl -X POST \
  '' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer ' \
  --data-raw ''

       

然后我将以下代码复制粘贴到终端中并且它工作(敏感信息已删除):

curl -X POST \
  'https://smartdevicemanagement.googleapis.com/v1/enterprises/f779e361..../devices/AVP.......:executeCommand' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer ya29........' \
  --data-raw '{"command":"sdm.devices.commands.CameraLiveStream.GenerateRtspStream","params":{"eventId":"Ci........."}}'

所以错误必须来自我的卷曲代码:

$curl_handle=curl_init();
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, array('Accept: application/json'));
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, array('Authorization: Bearer '.$access_token ));
curl_setopt($curl_handle, CURLOPT_POST, true);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $PostData);
curl_setopt($curl_handle, CURLOPT_URL,$url);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);  
$fileContent = curl_exec($curl_handle);
curl_close($curl_handle);

标签: phpphp-curlnest-device-accessgoogle-sdm-api

解决方案


OK 问题已解决。我的标题哪里错了。正确的卷曲代码是这样的:

$curl_handle=curl_init();

$headers = array(
    "POST  HTTP/1.0",
    "Content-type: application/json",
    "Accept: application/json",
    "Content-length: ".strlen($PostData),
    "Authorization:  Bearer ".$access_token
);
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl_handle, CURLOPT_POST, true);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $PostData);
curl_setopt($curl_handle, CURLOPT_URL,$url);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);  
$fileContent = curl_exec($curl_handle);
curl_close($curl_handle);

感谢大家的回复,它帮助我朝着正确的方向前进


推荐阅读