516 lines
20 KiB
PHP
516 lines
20 KiB
PHP
<?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 updateAdsMerchantRelation($data,$sendMq = 0)
|
||
// {
|
||
// $tableName = 'bps_ads_merchant_relation';
|
||
// $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps.' . $tableName;
|
||
//
|
||
// $sql = "
|
||
// UPDATE {$tableName}
|
||
// SET
|
||
// user_id = :user_id,
|
||
// is_unbind = :is_unbind,
|
||
// updated_at = CURRENT_TIMESTAMP
|
||
// WHERE
|
||
// platform = 2
|
||
// AND merchant_id = :merchant_id
|
||
// AND account_id = :account_id
|
||
// ";
|
||
//
|
||
// ThinkDb::execute($sql, [
|
||
// 'user_id' => (string)$data['user_id'],
|
||
// 'is_unbind' => $data['is_unbind'] ?? 'f',
|
||
// 'merchant_id' => (string)$data['merchant_id'],
|
||
// 'account_id' => (string)$data['account_id'],
|
||
// 'user_id' => (string)$data['user_id'],
|
||
// ]);
|
||
//
|
||
// // 如果需要发送队列
|
||
// if ($sendMq == 1) {
|
||
// $this->queueNew([
|
||
// 'merchant_id' => $data['merchant_id'],
|
||
// 'account_id' => $data['account_id']
|
||
// ]);
|
||
// }
|
||
// }
|
||
|
||
//保存或更新某个主体部广告账号
|
||
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,
|
||
platform_user_id = EXCLUDED.platform_user_id,
|
||
platform_user_name = EXCLUDED.platform_user_name,
|
||
account_name = EXCLUDED.account_name,
|
||
access_token = EXCLUDED.access_token,
|
||
refresh_token = EXCLUDED.refresh_token,
|
||
is_unbind = EXCLUDED.is_unbind,
|
||
is_del = 'f',
|
||
ext_info = EXCLUDED.ext_info,
|
||
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 updateAccountLastSyncTime($merchantId, $accountId): void
|
||
{
|
||
$tableName = 'bps_ads_merchant_relation';
|
||
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
|
||
|
||
//更新last_sync_time 赋值当前时间戳
|
||
$data = [
|
||
'merchant_id' => $merchantId,
|
||
'account_id' => $accountId,
|
||
'last_sync_time' => time()
|
||
];
|
||
$sql = "
|
||
UPDATE {$tableName}
|
||
SET last_sync_time = :last_sync_time
|
||
where paltform = 2 and merchant_id = :merchant_id and account_id = :account_id
|
||
";
|
||
ThinkDb::execute($sql, $data);
|
||
}
|
||
|
||
|
||
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';
|
||
}
|
||
|
||
|
||
} |