ToutiaoAdapter.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <?php
  2. namespace app\adapter;
  3. // 头条-适配器
  4. use app\process\Http;
  5. use GuzzleHttp\Client;
  6. use support\think\Db;
  7. class ToutiaoAdapter
  8. {
  9. public function OAuth($callback)
  10. {
  11. $authCode = $callback['auth_code'];
  12. $cmid = $callback['state']['cmid'];
  13. $Account = Db::connect('db_advert')->name('ad_advertiser_app')->select()->toArray();
  14. $Account = array_column($Account, null, 'id');
  15. // 1. 根据cmid获取appid和secret
  16. $appId = $Account[$cmid]['app_id'];
  17. $secret = $Account[$cmid]['app_secret'];
  18. $tokenUrl = $Account[$cmid]['token_url'];
  19. // 2. 授权access_token 和 refresh_token
  20. $url = $tokenUrl;
  21. $header = ['Content-Type: application/json'];
  22. $request_data = json_encode([
  23. 'app_id'=>$appId,
  24. 'secret'=>$secret,
  25. 'grant_type'=>'auth_code',
  26. 'auth_code'=>$authCode,
  27. ]);
  28. $httpClient = new Client(['timeout' => 10]);
  29. $res = $httpClient->request('POST', $url, [
  30. 'json' => $request_data,
  31. 'headers' => $header,
  32. ]);
  33. $result = json_decode($res->getBody(), true);
  34. $data = $result['data'] ?? [];
  35. // 执行验证callback, 返回授权后的字段,跟数据库对应
  36. return [
  37. "advertiser_id" => $data['advertiser_id'],
  38. "advertiser_ids" => $data['advertiser_ids'],
  39. "access_token" => $data['access_token'],
  40. "refresh_token" => $data['refresh_token'],
  41. "refresh_token_expires_in" => $data['refresh_token_expires_in'],
  42. "expires_in" => $data['expires_in'],
  43. "cmid" => $cmid,
  44. ];
  45. }
  46. // 写入授权结果
  47. public function writeOAuthResult($data)
  48. {
  49. // 写入ad_advertiser_bm表
  50. if ($data['access_token']){
  51. $accounts = $data['advertiser_ids'];
  52. foreach($accounts as $account_id){
  53. $record = Db::connect('db_advert')->name('ad_advertiser_bm')
  54. ->where('advertiser_id', $account_id)
  55. ->find();
  56. if (!$record){
  57. $record = [
  58. 'advertiser_id' => $account_id,
  59. 'advertiser_name' => $account_id,
  60. 'access_token' => $data['access_token'],
  61. 'refresh_token' => $data['refresh_token'],
  62. ];
  63. Db::connect('db_advert')->name('ad_advertiser_bm')->insert($record);
  64. }else{
  65. Db::connect('db_advert')->name('ad_advertiser_bm')->where('advertiser_id', $account_id)->update([
  66. 'access_token' => $data['access_token'],
  67. 'refresh_token' => $data['refresh_token'],
  68. 'advertiser_id' => $account_id,
  69. 'advertiser_name' => $account_id,
  70. ]);
  71. }
  72. }
  73. }
  74. }
  75. // 获取子账号列表
  76. public function getSubAccounts($oathInfo)
  77. {
  78. $advertiserId = $oathInfo['advertiser_id'];
  79. $accessToken = $oathInfo['access_token'];
  80. $appId = $oathInfo['app_id'];
  81. // 根据授权返回的 advertiser_id 和 access_token 获取子账号列表
  82. $url = 'https://ad.oceanengine.com/open_api/2/majordomo/advertiser/select/';
  83. $header = [
  84. 'Access-Token' => $accessToken,
  85. 'Content-Type' => 'application/json',
  86. ];
  87. $requestData = [
  88. 'advertiser_id' => $advertiserId,
  89. ];
  90. $url = $url."?".http_build_query($requestData);
  91. $httpClient = new Client(['timeout' => 10]);
  92. $res = $httpClient->request('GET', $url, [
  93. 'headers' => $header,
  94. ]);
  95. $result = json_decode($res->getBody(), true);
  96. $list = $result['data']['list'] ?? [];
  97. $toutiaoAccountList = Db::connect('db_advert')->name('ad_advertiser_list')->where('media_id', 1)->select()->toArray();
  98. $toutiaoAccountMap = array_column($toutiaoAccountList, null, 'advertiser_id');
  99. foreach($list as $val){
  100. if(!isset($toutiaoAccountMap[$val['advertiser_id']])){
  101. Db::connect('db_advert')->name('ad_advertiser_list')->insert([
  102. 'advertiser_id' => $val['advertiser_id'],
  103. 'advertiser_name' => $val['advertiser_name'],
  104. 'app_id'=>$appId,
  105. 'bmid' => $advertiserId,
  106. 'media_id' => 1,
  107. ]);
  108. }
  109. }
  110. }
  111. // 刷新 token
  112. public function refreshToken($data)
  113. {
  114. $cmid = $data['cmid'];
  115. $advertiserId = $data['advertiser_id'];
  116. $accountApp = Db::connect('db_advert')->name('ad_advertiser_app')->where('id', $cmid)->find();
  117. $refreshToken = Db::connect('db_advert')->name('ad_advertiser_bm')->where('advertiser_id', $advertiserId)->value('refresh_token');
  118. if($refreshToken){
  119. $url = $accountApp['refresh_url'];
  120. $header = ['Content-Type: application/json'];
  121. $request_data = json_encode([
  122. 'app_id'=>$accountApp['app_id'],
  123. 'secret'=>$accountApp['app_secret'],
  124. 'grant_type'=>'refresh_token',
  125. 'refresh_token'=>$refreshToken
  126. ]);
  127. $httpClient = new Client(['timeout' => 10]);
  128. $res = $httpClient->request('POST', $url, [
  129. 'json' => $request_data,
  130. 'headers' => $header,
  131. ]);
  132. $result = json_decode($res->getBody(), true);
  133. $data = $result['data'] ?? [];
  134. // 更新管家的token相关
  135. if ($data['access_token']){
  136. Db::connect('db_advert')->name('ad_advertiser_bm')->where('advertiser_id', $advertiserId)->update([
  137. 'access_token' => $data['access_token'],
  138. 'refresh_token' => $data['refresh_token'],
  139. 'refresh_token_expires_in' => $data['refresh_token_expires_in'],
  140. 'expires_in' => $data['expires_in'],
  141. ]);
  142. }
  143. }
  144. return $data;
  145. }
  146. // 获取小时消耗
  147. public function getHourlyCost($advertiserId, $accessToken, $date): array
  148. {
  149. $page = 1;
  150. $data = [];
  151. do {
  152. $url = 'https://ad.oceanengine.com/open_api/v3.0/report/custom/get/';
  153. $request_data = [
  154. 'advertiser_id'=>$advertiserId,
  155. 'dimensions'=>json_encode(["cdp_project_id","cdp_project_name","ad_platform_cdp_project_action_track_url","ad_platform_cdp_project_download_url","stat_time_hour"]),
  156. 'metrics'=>json_encode(["stat_cost","show_cnt","click_cnt","convert_cnt"]),
  157. 'filters'=>'[{"operator":4,"values":["0"],"field":"stat_cost","type":3}]',
  158. 'start_time'=>$date,
  159. 'end_time'=>$date,
  160. 'order_by'=>json_encode([]),
  161. 'page'=>$page,
  162. 'page_size'=>100,
  163. ];
  164. $options = [
  165. "headers" => [
  166. 'Access-Token' => $accessToken,
  167. 'Content-Type' => 'application/json',
  168. ]
  169. ];
  170. $url = $url."?".http_build_query($request_data);
  171. $httpClient = new Client(['timeout' => 10]);
  172. $res = $httpClient->request('GET', $url, $options);
  173. $result = json_decode($res->getBody(), true);
  174. if (empty($result['data']['rows'])) {
  175. break;
  176. }
  177. $data = array_merge($data, $result['data']['rows']);
  178. $totalPage = $result['data']['page_info']['total_page'] ?? 1;
  179. $page++;
  180. } while ($page <= $totalPage);
  181. return $data;
  182. }
  183. // 获取媒体消耗
  184. public function getVideoCost($advertiserId, $accessToken, $date): array
  185. {
  186. $page = 1;
  187. $data = [];
  188. do {
  189. $url = 'https://ad.oceanengine.com/open_api/v3.0/report/custom/get/';
  190. $request_data = [
  191. 'advertiser_id'=>$advertiserId,
  192. 'dimensions'=>json_encode(["ad_platform_material_name","material_id","cdp_project_id","cdp_project_name","stat_time_day", "ad_platform_cdp_project_action_track_url"]),
  193. 'metrics'=>json_encode(["stat_cost","show_cnt","click_cnt","active","active_register","active_pay","valid_play","download_finish_cnt","total_play", "stat_pay_amount"]),
  194. 'filters'=>'[{"field":"image_mode","type":1,"operator":0,"values":["5","15"]},{"operator":4,"values":["0"],"field":"stat_cost","type":3}]',
  195. 'start_time'=>$date,
  196. 'end_time'=>$date,
  197. 'order_by'=>json_encode([]),
  198. 'page'=>1,
  199. 'page_size'=>100,
  200. ];
  201. $options = [
  202. "headers" => [
  203. 'Access-Token' => $accessToken,
  204. 'Content-Type' => 'application/json',
  205. ]
  206. ];
  207. $url = $url."?".http_build_query($request_data);
  208. $httpClient = new Client(['timeout' => 10]);
  209. $res = $httpClient->request('GET', $url, $options);
  210. $result = json_decode($res->getBody(), true);
  211. if (empty($result['data']['rows'])) {
  212. break;
  213. }
  214. $data = array_merge($data, $result['data']['rows']);
  215. $totalPage = $result['data']['page_info']['total_page'] ?? 1;
  216. $page++;
  217. } while ($page <= $totalPage);
  218. return $data;
  219. }
  220. public function getVideo($advertiserId, $accessToken, $materialIds): array
  221. {
  222. $url = 'https://api.oceanengine.com/open_api/2/file/video/get/';
  223. $request_data = [
  224. 'advertiser_id'=>$advertiserId,
  225. 'filtering' => json_encode([
  226. "material_ids" => $materialIds,
  227. ]),
  228. ];
  229. $options = [
  230. "headers" => [
  231. 'Access-Token' => $accessToken,
  232. 'Content-Type' => 'application/json',
  233. ]
  234. ];
  235. $url = $url."?".http_build_query($request_data);
  236. $httpClient = new Client(['timeout' => 10]);
  237. $res = $httpClient->request('GET', $url, $options);
  238. $result = json_decode($res->getBody(), true);
  239. return $result['data']['list'] ?? [];
  240. }
  241. }