configData = $configData; } public function login() { $permissions = [ 'publish_video', 'pages_manage_cta', 'pages_show_list', 'business_management', 'pages_read_engagement', 'pages_manage_metadata', 'pages_read_user_content', 'pages_manage_ads', 'pages_manage_posts', 'pages_manage_engagement', ]; $query = http_build_query([ 'client_id' => env('SSM_FACEBOOK_APP_ID'), 'redirect_uri' => env('DIST_SITE_URL').'/dist/callback/facebook', 'response_type' => 'code', 'scope' => implode(',', $permissions), 'state' => csrf_token(), ]); return ['status' => true, 'data' => ['url' => "https://www.facebook.com/{$this->graphVersion}/dialog/oauth?{$query}"]]; } public function loginCallback(Request $request) { // 验证 state 防止 CSRF if ($request->state !== csrf_token()) { return ['status' => false, 'data' => 'Invalid state parameter']; } try { // 获取短期访问令牌 $response = Http::asForm()->post("https://graph.facebook.com/{$this->graphVersion}/oauth/access_token", [ 'client_id' => env('SSM_FACEBOOK_APP_ID'), 'client_secret' => env('SSM_FACEBOOK_APP_SECRET'), 'redirect_uri' => env('DIST_SITE_URL').'/dist/callback/facebook', 'code' => $request->code, ]); if ($response->failed()) { throw new \Exception($response->json('error.message')); } $shortToken = $response->json('access_token'); // 转换为长期令牌 $longTokenResponse = Http::get("https://graph.facebook.com/{$this->graphVersion}/oauth/access_token", [ 'grant_type' => 'fb_exchange_token', 'client_id' => env('SSM_FACEBOOK_APP_ID'), 'client_secret' => env('SSM_FACEBOOK_APP_SECRET'), 'fb_exchange_token' => $shortToken, ]); if ($longTokenResponse->failed()) { throw new \Exception($longTokenResponse->json('error.message')); } $longToken = $longTokenResponse->json('access_token'); //当前时间加60天 $expiresAt = Carbon::now()->addDays(60)->format('Y-m-d H:i:s'); // 获取用户信息 $userInfo = $this->getFacebookUser($longToken); if (!$userInfo['status']) { return $userInfo; } return [ 'status' => true, 'data' => [ 'accessToken' => $longToken, 'accessToken_expiresAt' => $expiresAt, 'userName' => $userInfo['data']['name'], 'userId' => $userInfo['data']['id'] ] ]; } catch (\Exception $e) { return ['status' => false, 'data' => $e->getMessage()]; } } public function postImage($message, $imagePaths, $accessToken) { try { $pagesInfo = $this->getAccountsInfo($accessToken); if (!$pagesInfo['status']) { return $pagesInfo; } $results = []; foreach ($pagesInfo['data'] as $page) { $mediaIds = []; foreach ($imagePaths as $imagePath) { // 上传图片 $uploadResponse = Http::withToken($page['pageAccessToken']) ->attach('source', file_get_contents($imagePath), basename($imagePath)) ->post("https://graph.facebook.com/{$this->graphVersion}/{$page['id']}/photos", [ 'published' => false, ]); if ($uploadResponse->failed()) { return ['status' => false, 'data' => $uploadResponse->json('error.message')]; } $mediaIds[] = ['media_fbid' => $uploadResponse->json('id')]; } // 发布帖子 $postResponse = Http::withToken($page['pageAccessToken']) ->post("https://graph.facebook.com/{$this->graphVersion}/{$page['id']}/feed", [ 'message' => $message, 'attached_media' => json_encode($mediaIds), ]); if ($postResponse->failed()) { return ['status' => false, 'data' => $postResponse->json('error.message')]; } $results[] = $postResponse->json('id'); } return ['status' => true, 'data' => [ 'responseIds' => $results, ]]; } catch (\Exception $e) { return ['status' => false, 'data' => $e->getMessage()]; } } public function postVideo($message, $videoPath, $accessToken) { try { $pagesInfo = $this->getAccountsInfo($accessToken); if (!$pagesInfo['status']) { return $pagesInfo; } $results = []; foreach ($pagesInfo['data'] as $page) { $response = Http::withToken($page['pageAccessToken']) ->attach('source', file_get_contents($videoPath), basename($videoPath)) ->post("https://graph.facebook.com/{$this->graphVersion}/{$page['id']}/videos", [ 'description' => $message, ]); if ($response->failed()) { throw new \Exception($response->json('error.message')); } $results[] = $response->json('id'); } return ['status' => true, 'data' => [ 'responseIds' => $results, ]]; } catch (\Exception $e) { return ['status' => false, 'data' => $e->getMessage()]; } } private function getFacebookUser($accessToken) { try { $response = Http::withToken($accessToken) ->get("https://graph.facebook.com/{$this->graphVersion}/me", [ 'fields' => 'name,id' ]); if ($response->failed()) { throw new \Exception($response->json('error.message')); } return [ 'status' => true, 'data' => $response->json() ]; } catch (\Exception $e) { return ['status' => false, 'data' => $e->getMessage()]; } } public function getAccountsInfo($accessToken) { try { $response = Http::withToken($accessToken) ->get("https://graph.facebook.com/{$this->graphVersion}/me/accounts"); if ($response->failed()) { throw new \Exception($response->json('error.message')); } $pages = collect($response->json('data'))->map(function ($page) { return [ 'id' => $page['id'], 'name' => $page['name'], 'pageAccessToken' => $page['access_token'], ]; })->toArray(); if (empty($pages)) { throw new \Exception('No pages found'); } return ['status' => true, 'data' => $pages]; } catch (\Exception $e) { return ['status' => false, 'data' => $e->getMessage()]; } } // 其他接口方法保持空实现 public function getComments($postId) {} public function replyToComment($commentId) {} public function deleteComment($commentId) {} }