webman_ad/app/service/GoogleOAuthService.php

457 lines
18 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\service;
use GuzzleHttp\Client;
use think\facade\Db as ThinkDb;
use app\model\BpsAdsMerchantRelation;
use app\model\ThirdUserAdvertiser;
use app\model\ThirdUser;
use Webman\Event\Event;
use Webman\RedisQueue\Redis;
use Webman\RedisQueue\Client as QueueClient;
use app\event\GoogleAdsCustomers;
class GoogleOAuthService
{
/*
* 获取google主体账号信息
*
*/
public function getGoogleAccountInfo($accessToken)
{
// 'id' => '用户的Google ID',
// 'email' => '用户的电子邮件地址',
// 'verified_email' => true, // 邮箱是否已验证
// 'name' => '用户的全名',
// 'given_name' => '用户的名字',
// 'family_name' => '用户的姓氏',
// 'picture' => '用户头像的URL',
// 'locale' => '用户的语言偏好',
$client = new Client();
try {
$options = [
"headers" => [
'Authorization' => 'Bearer ' . $accessToken,
],
];
$userInfo = json_decode($client->request('Get', 'https://www.googleapis.com/oauth2/v2/userinfo', $options)->getBody()->getContents(), true);
// // Process user info...
// dump($userInfo,666);
return $userInfo;
} catch (\GuzzleHttp\Exception\ClientException $e) {
error_log('Client error: ' . $e->getMessage());
if ($e->hasResponse()) {
error_log('Response: ' . $e->getResponse()->getBody());
}
} catch (\Exception $e) {
// Handle other exceptions
error_log('Error: ' . $e->getMessage());
}
}
public function getAuthUrl($state = '')
{
$clientId = getenv('GOOGLE_CLIENT_ID');
$redirectUri = getenv('GOOGLE_REDIRECT_URI');
$scope = 'https://www.googleapis.com/auth/adwords https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email';
$responseType = 'code';
$accessType = 'offline';
// $state = 'state_parameter_passthrough_value'; // 可选保护防止CSRF
// 将state保存到会话或数据库中稍后验证
// $_SESSION['oauth_state'] = $state; // 使用PHP会话来保存state
// $authUrl = "https://accounts.google.com/o/oauth2/v2/auth?client_id=$clientId&redirect_uri=$redirectUri&scope=$scope&response_type=$responseType&state=$state";
if (!empty($state)) {
// 生成随机的state参数防止CSRF攻击
// $state = bin2hex(random_bytes(16)); // 生成一个随机字符串
// $this->saveThirdUser($state);
$authUrl = "https://accounts.google.com/o/oauth2/v2/auth?client_id=$clientId&redirect_uri=$redirectUri&scope=$scope&response_type=$responseType&access_type=$accessType&state=$state";
} else {
$authUrl = "https://accounts.google.com/o/oauth2/v2/auth?client_id=$clientId&redirect_uri=$redirectUri&scope=$scope&response_type=$responseType&access_type=$accessType";
}
return $authUrl;
}
public function getThirdUserByRandomCode($state)
{
$tableName = 'bps_third_user';
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
$result = ThinkDb::name($tableName)->where('random_code', $state)->find();
return $result;
}
public function getRefreshToken($authCode)
{
$client = new Client();
$response = $client->post('https://oauth2.googleapis.com/token', [
'form_params' => [
'code' => $authCode,
'client_id' => getenv('GOOGLE_CLIENT_ID'),
'client_secret' => getenv('GOOGLE_CLIENT_SECRET'),
'redirect_uri' => getenv('GOOGLE_REDIRECT_URI'),
'grant_type' => 'authorization_code',
],
]);
return json_decode($response->getBody(), true);
}
public function saveThirdUser($state)
{
//发起授权前新记录到bps_third_user表
$data = [
'random_code' => $state,
'is_default' => 't',
'third_type' => 'google',
];
$tableName = 'bps_third_user';
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
$sql = " INSERT INTO {$tableName}
(random_code, is_default, third_type)
VALUES (:random_code, :is_default, :third_type";
ThinkDb::execute($sql, $data);
}
public function getCustomerListNew(string $merchant_id = '')
{
// dump($merchant_id,555);
//$userId = $options['uid']; // 获取用户ID
$customers = BpsAdsMerchantRelation::alias('bamr')
->where('bamr.merchant_id', $merchant_id)
// ->where('bamr.is_unbind', 'f')
->where('bamr.is_del', 'f')
->where('bamr.platform', 2)
->field('bamr.account_id, bamr.account_name,bamr.is_unbind,bamr.currency')
// ->field('')
->select(); // 执行查询
// dump($customers,555);
// 打印调试 SQL 查询
// $sql = $customers->getLastSql();
// dump($sql);
// 如果没有找到符合条件的用户,返回空数组
if ($customers->isEmpty()) {
return [];
}
// dump($customers->toArray());
return $customers->toArray();
}
//保存或更新某个主体部广告账号 废弃2025-2-13
public function saveThirdUserAdvertiser($customer_id, $third_user_id, $login_customer_id, $customer, $merchant_id)
{
// 确保 customer_id 和 third_user_id 是字符串
$customer_id = (string)$customer_id;
$tableName = 'bps_third_user_advertiser';
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
$data = [
'doc_' => $third_user_id,
'advertiser_id' => $customer_id,
'advertiser_name' => $customer['descriptive_name'],
'google_login_customer_id' => $login_customer_id,
'merchant_id' => $merchant_id,
'currency' => $customer['currency'],
];
if ($customer['manager'] === true) {
$data['google_manager'] = 't';
} else {
$data['google_manager'] = 'f';
}
if ($customer['test_account'] === true) {
$data['google_test_account'] = 't';
} else {
$data['google_test_account'] = 'f';
}
// dump($data);
$sql = "
INSERT INTO {$tableName}
(advertiser_id,advertiser_name, doc_,google_login_customer_id,google_manager,google_test_account,merchant_id,currency)
VALUES (:advertiser_id, :advertiser_name,:doc_,:google_login_customer_id,:google_manager,:google_test_account,:merchant_id,:currency)
ON CONFLICT (advertiser_id,doc_)
DO UPDATE SET
advertiser_name = EXCLUDED.advertiser_name,
google_login_customer_id = EXCLUDED.google_login_customer_id,
google_manager = EXCLUDED.google_manager,
google_test_account = EXCLUDED.google_test_account,
currency = EXCLUDED.currency,
merchant_id = EXCLUDED.merchant_id
";
// dump($sql,$data);
ThinkDb::execute($sql, $data);
}
//保存或更新某个主体部广告账号
public function saveThirdUserAdvertiserNew($data,$sendMq = 0)
{
// 确保 account_id 和 merchant_id 是字符串
$data['account_id'] = (string)$data['account_id'];
$data['merchant_id'] = (string)$data['merchant_id'];
$data['user_id'] = (string)$data['user_id'];
$tableName = 'bps_ads_merchant_relation';
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps.' . $tableName;
// 构造插入或更新的数据
$insertData = [
'platform' => 2, // 假设google平台值为2根据实际情况调整
'merchant_id' => $data['merchant_id'],
'user_id' => $data['user_id'],
'account_id' => $data['account_id'],
'access_token' => $data['access_token'],
'refresh_token' => $data['refresh_token'],
'account_name' => $data['account_name'],
'currency' => $data['currency'],
'platform_user_id' => $data['platform_user_id']??'',
'platform_user_name' => $data['platform_user_name']??'',
'is_unbind' => $data['is_unbind']??'f',
'ext_info' => $data['ext_info']??'{}',
];
// dump($insertData,2525);
// 构造SQL语句
$sql = "
INSERT INTO {$tableName}
(platform, merchant_id, user_id,access_token, refresh_token,account_id, account_name, currency, ext_info,platform_user_id, platform_user_name,is_unbind)
VALUES (:platform, :merchant_id,:user_id, :access_token, :refresh_token, :account_id, :account_name, :currency, :ext_info,:platform_user_id, :platform_user_name,:is_unbind)
ON CONFLICT (platform,merchant_id,account_id)
DO UPDATE SET
user_id = EXCLUDED.user_id,
account_name = EXCLUDED.account_name,
access_token = EXCLUDED.access_token,
refresh_token = EXCLUDED.refresh_token,
is_unbind = EXCLUDED.is_unbind,
currency = EXCLUDED.currency,
updated_at = CURRENT_TIMESTAMP";
// 执行SQL语句
ThinkDb::execute($sql, $insertData);
// dump(ThinkDb::getLastSql(),2525);
//如果要异步更新改广告账号数据的话。
if($sendMq == 1){
// Event::emit(GoogleAdsCustomers::add_queue, $data);
$options = [];
$options['merchant_id'] = $data['merchant_id'];
$options['account_id'] = $data['account_id'];
// $options['refresh_token'] = $data['refresh_token'];
// $options['login_customer_id'] = json_decode($data['ext_info'],true)['login_customer_id']??'';
$this->queueNew($options);
}
}
public function updateThirdUserDefault($third_user_id, $is_default = 't'): void
{
$tableName = 'bps_third_user';
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
$data = [
'is_default' => $is_default,
'id' => $third_user_id,];
$sql = "
UPDATE {$tableName}
SET is_default = :is_default
WHERE id = :id
";
ThinkDb::execute($sql, $data);
}
//废弃2025-2-13
public function saveRefreshToken($refreshToken, $state = '')
{
// 使用ThinkORM保存数据到bps_third_user表
// $thirdUser = new \App\Models\ThirdUser();
// $thirdUser->access_token = $accessToken;
// $thirdUser->is_default = true;
// $thirdUser->random_code = bin2hex(random_bytes(16)); // 生成随机码
// $thirdUser->third_type = 'google';
// $thirdUser->user_id = $userId;
// $thirdUser->save();
$data = [
'access_token' => $refreshToken,
'is_default' => 'f',
'third_type' => 'google',
];
$tableName = 'bps_third_user';
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
if (!empty($state)) {
$thirdUser = ThirdUser::where('merchant_id', $state)->where('third_type', 'google')->find(); // 获取第一个结果
// dump($thirdUser); return ($uid);
if ($thirdUser) {
$data['id'] = $thirdUser->id;
$sql = "
UPDATE {$tableName}
SET
access_token = :access_token,
is_default = :is_default,
third_type = :third_type
WHERE id = :id
";
} else {
$data['merchant_id'] = $state;
$sql = "
INSERT INTO {$tableName}
(access_token, is_default, third_type, merchant_id)
VALUES (:access_token, :is_default, :third_type, :merchant_id)
";
}
} else {
$sql = "
INSERT INTO {$tableName}
(access_token, is_default, third_type)
VALUES (:access_token, :is_default, :third_type)
";
}
ThinkDb::execute($sql, $data);
$options = [];
$options['refresh_token'] = $refreshToken;
Event::emit(GoogleAdsCustomers::add_queue, $data);
$this->queue($options);
}
public function saveRefreshTokenNew($refreshToken,$accessToken, $merchantId,$userId)
{
$data = [
'refresh_token' => $refreshToken,
'access_token' => $accessToken,
'merchant_id' => $merchantId,
'user_id' => $userId,
// 'is_default' => 'f',
// 'third_type' => 'google',
];
$options = [];
$options['refresh_token'] = $refreshToken;
// dump($data,$options);
Event::emit(GoogleAdsCustomers::add_queue, $data);
// $this->queue($options);
}
public function initNewGoogleAdsAccountData($refreshToken)
{
$options = [];
$options['refresh_token'] = $refreshToken;
// Event::emit(GoogleAdsCustomers::add_queue, $data);
$this->queue($options);
}
public function revokeToken($accessToken, $merchantId)
{
$client = new Client();
$client->post('https://oauth2.googleapis.com/revoke', [
'form_params' => [
'token' => $accessToken,
],
]);
// 在数据库中删除或标记该`access_token(其实是refresh_token)`为无效
BpsAdsMerchantRelation::where('merchant_id', $merchantId)->where('platform',2)->delete();
//
// $tableName = 'bps_third_user';
// $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
// $sql = "UPDATE {$tableName} SET access_token = :access_token WHERE id = :id";
// $data = [
// 'access_token' => '', // 这里的 $accessToken 是您想要匹配的值
// 'id' => $third_user_id, // 这里的 $accessToken 是您想要匹配的值
// ];
// // 执行 SQL 语句
// $result = ThinkDb::execute($sql, $data);
//// ThirdUser::where('access_token', $accessToken)->delete();
}
public function useRefreshToken($refreshToken)
{
$client = new Client();
$response = $client->post('https://oauth2.googleapis.com/token', [
'form_params' => [
'refresh_token' => $refreshToken,
'client_id' => getenv('GOOGLE_CLIENT_ID'),
'client_secret' => getenv('GOOGLE_CLIENT_SECRET'),
'grant_type' => 'refresh_token',
],
]);
$data = json_decode($response->getBody(), true);
return $data['access_token'];
}
/**
* 批量获取全部Google广告账号数据
* 作废2025-2-13
*/
public function getGoogleAdCustomersBak($options = [])
{
if (!empty($options['refresh_token'])) {
$refreshToken = $options['refresh_token'];
// 获取符合条件的客户ID数组
$customers = ThirdUserAdvertiser::alias('tua')
->join('bps.bps_third_user tu', 'tua.doc_ = tu.id') // 连接 bps_third_user 表
->where('tu.third_type', 'google') // 筛选 third_type 为 google 的记录
->where('tu.access_token', $refreshToken) // 筛选 third_type 为 google 的记录
->field('CAST(tua.advertiser_id AS BIGINT) as customer_id,tua.google_login_customer_id as login_customer_id,tua.google_test_account as test_account,tua.google_manager as manager, tu.access_token as refresh_token') // 获取 advertiser_id 字段
->select(); // 执行查询
} else {
// 获取符合条件的客户ID数组
$customers = ThirdUserAdvertiser::alias('tua')
->join('bps.bps_third_user tu', 'tua.doc_ = tu.id') // 连接 bps_third_user 表
->where('tu.third_type', 'google') // 筛选 third_type 为 google 的记录
->field('CAST(tua.advertiser_id AS BIGINT) as customer_id,tua.google_login_customer_id as login_customer_id,tua.google_test_account as test_account,tua.google_manager as manager, tu.access_token as refresh_token') // 获取 advertiser_id 字段
->select(); // 执行查询
}
// 如果没有找到符合条件的广告主,抛出异常
if ($customers->isEmpty()) {
return [];
// throw new ApiException('No customers found for google third type');
}
// 转换为简单的数组(提取 advertiser_id
return $customers->toArray();
}
//废弃2025-2-13
public function queue($options = []): string
{
// 队列名
// $queue = GoogleAdsCustomers::add_queue;
$queue2 = GoogleAdsCustomers::init_queue;
// 数据,可以直接传数组,无需序列化
// $options = ['to' => 'tom@gmail.com', 'content' => 'hello'];
// 投递消息
// Redis::send($queue, $options['data']);
QueueClient::send($queue2, $options); //异步投递 延后15秒
// 投递延迟消息消息会在60秒后处理
// Redis::send($queue, $options['data'], 60);
return $queue2 . ' redis queue ok';
}
public function queueNew($options = []): string
{
// 队列名
// $queue = GoogleAdsCustomers::add_queue;
$queue2 = GoogleAdsCustomers::init_queue;
// 数据,可以直接传数组,无需序列化
// $options = ['to' => 'tom@gmail.com', 'content' => 'hello'];
// 投递消息
// Redis::send($queue, $options['data']);
QueueClient::send($queue2, $options); //异步投递 延后15秒
// 投递延迟消息消息会在60秒后处理
// Redis::send($queue, $options['data'], 60);
return $queue2 . ' redis queue ok';
}
}