123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- <?php
- namespace App\Services\Smm;
- use App\Services\Contracts\SmmPlatformInterface;
- use Carbon\Carbon;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\Http;
- use Illuminate\Support\Facades\Log;
- use Illuminate\Support\Facades\Session;
- class FacebookService implements SmmPlatformInterface
- {
- protected $configData;
- protected $graphVersion = 'v19.0';
- public function __construct($configData)
- {
- $this->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) {}
- }
|