如何将Google Business Messages的cURL OAuth2头转换为PHP cURL实现?
用PHP cURL实现Google Business Messages消息回复
你提到的-H "$(oauth2l header --json ./service_account_key.json businessmessages)"本质是生成针对Google Business Messages API的OAuth2 Bearer授权头。oauth2l工具帮你完成了从服务账号密钥获取访问令牌的流程,在PHP里我们可以自己实现这个逻辑,不用依赖该工具。
方案一:使用Google PHP客户端库(推荐,更稳定)
Google官方的google/apiclient库可以自动处理服务账号的令牌获取,避免手动编写复杂的JWT签名逻辑:
- 先通过Composer安装依赖:
composer require google/apiclient
- 编写代码获取令牌并发送回复:
<?php require __DIR__ . '/vendor/autoload.php'; // 加载服务账号密钥文件 $client = new Google\Client(); $client->setAuthConfig('./service_account_key.json'); // 设置Business Messages的API权限范围 $client->addScope('https://www.googleapis.com/auth/businessmessages'); // 以服务账号身份请求令牌 $client->fetchAccessTokenWithAssertion(); $accessToken = $client->getAccessToken()['access_token']; // 构造回复消息的请求体 $messagePayload = [ 'messageId' => uniqid('msg_'), // 生成唯一消息ID 'text' => '这是来自PHP的回复消息', 'representative' => [ 'avatarImage' => 'https://example.com/avatar.png', // 可选:客服头像URL 'displayName' => '客服小助手' ] ]; // 目标对话ID(从入站消息的webhook请求体中获取) $conversationId = 'YOUR_CONVERSATION_ID'; $apiUrl = "https://businessmessages.googleapis.com/v1/conversations/{$conversationId}/messages"; // 初始化cURL $ch = curl_init($apiUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($messagePayload)); // 设置请求头,包括授权头和Content-Type curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer {$accessToken}", 'Content-Type: application/json' ]); // 执行请求并处理响应 $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($httpCode !== 200) { echo "请求失败,状态码:{$httpCode},响应内容:{$response}"; } else { echo "消息发送成功,响应:{$response}"; } curl_close($ch); ?>
方案二:纯cURL手动实现令牌获取(无需第三方库)
如果不想依赖Composer包,可以手动生成JWT并请求访问令牌:
步骤1:生成JWT签名
需要使用服务账号密钥中的私钥,以RS256算法生成JWT:
<?php function generateJwt($serviceAccountKey) { $header = json_encode(['alg' => 'RS256', 'typ' => 'JWT']); $now = time(); $payload = json_encode([ 'iss' => $serviceAccountKey['client_email'], 'scope' => 'https://www.googleapis.com/auth/businessmessages', 'aud' => 'https://oauth2.googleapis.com/token', 'exp' => $now + 3600, // 令牌有效期1小时 'iat' => $now ]); // 编码成Base64URL格式 $base64Header = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header)); $base64Payload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload)); // 用私钥签名 $signature = ''; openssl_sign($base64Header . '.' . $base64Payload, $signature, $serviceAccountKey['private_key'], OPENSSL_ALGO_SHA256); $base64Signature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature)); return $base64Header . '.' . $base64Payload . '.' . $base64Signature; } ?>
步骤2:获取访问令牌并发送消息
<?php // 加载服务账号密钥 $serviceAccountKey = json_decode(file_get_contents('./service_account_key.json'), true); $jwt = generateJwt($serviceAccountKey); // 请求访问令牌 $tokenUrl = 'https://oauth2.googleapis.com/token'; $tokenPayload = http_build_query([ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', 'assertion' => $jwt ]); $tokenCh = curl_init($tokenUrl); curl_setopt($tokenCh, CURLOPT_RETURNTRANSFER, true); curl_setopt($tokenCh, CURLOPT_POST, true); curl_setopt($tokenCh, CURLOPT_POSTFIELDS, $tokenPayload); $tokenResponse = json_decode(curl_exec($tokenCh), true); curl_close($tokenCh); if (!isset($tokenResponse['access_token'])) { die('获取令牌失败:' . json_encode($tokenResponse)); } $accessToken = $tokenResponse['access_token']; // 构造并发送回复消息 $conversationId = 'YOUR_CONVERSATION_ID'; $apiUrl = "https://businessmessages.googleapis.com/v1/conversations/{$conversationId}/messages"; $messagePayload = [ 'messageId' => uniqid('msg_'), 'text' => '纯cURL实现的回复消息', 'representative' => [ 'displayName' => 'PHP客服' ] ]; $ch = curl_init($apiUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($messagePayload)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer {$accessToken}", 'Content-Type: application/json' ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); echo $httpCode === 200 ? "发送成功:{$response}" : "失败,状态码{$httpCode}:{$response}"; curl_close($ch); ?>
关键注意事项
- 确保服务账号已被授予Google Business Messages的相关权限,并且已关联到你的商家账号。
conversationId需要从入站消息的Webhook请求体中获取(通常在conversation.id字段)。- 令牌有效期为1小时,建议缓存令牌避免重复请求。
内容的提问来源于stack exchange,提问作者Phil Barnes
相关产品推荐
相关产品推荐

