Browse Source

社媒对接

moshaorui 5 days ago
parent
commit
4e4959e347
4 changed files with 504 additions and 267 deletions
  1. 37 89
      app/Services/Smm/TwitterService.php
  2. 2 1
      composer.json
  3. 464 177
      composer.lock
  4. 1 0
      public/client_secret.json

+ 37 - 89
app/Services/Smm/TwitterService.php

@@ -130,119 +130,67 @@ class TwitterService implements SmmPlatformInterface
 
 
     public function postVideo($message, $videoPath, $accessToken = null)
-
     {
-
         try {
-
-            $this->twitterOAuth->setTimeouts(10, 30);
-
-            //转为本地路径
-
+            $this->twitterOAuth->setTimeouts(10, 120);
+            $this->twitterOAuth->setApiVersion('1.1');
             $videoPath = toStoragePath($videoPath);
-
-            if (!file_exists($videoPath)) {
-
-                throw new \Exception("视频文件不存在: {$videoPath}");
-
+            // Verify file exists and is readable
+            if (!file_exists($videoPath) || !is_readable($videoPath)) {
+                throw new Exception("Video file does not exist or is not readable: $videoPath");
             }
 
-            // 获取视频 MIME 类型
-            $mimeType = mime_content_type($videoPath);
-            if (strpos($mimeType, 'video/') !== 0) {
 
-                throw new \Exception("文件不是有效的视频文件。MIME 类型: " . $mimeType);
+            // Upload video with chunked upload
+            $uploadedMedia = $this->twitterOAuth->upload('media/upload', [
+                'media' => $videoPath,
+                'media_category' => 'tweet_video'
+            ],['chunkedUpload'=>true]);
 
-            }
-
-            // 获取视频文件大小 (以字节为单位)
-            $fileSize = filesize($videoPath);
+            $code = $this->twitterOAuth->getLastHttpCode();
 
-            // 1.1版本上传媒体文件 - 初始化上传
-            $initParams = [
-                'command' => 'INIT',
-                'media_type' => $mimeType,
-                'media_category' => 'tweet_video',
-                'total_bytes' => $fileSize,
-            ];
-            $uploadedInit = $this->twitterOAuth->upload('media/upload', $initParams, true);
+            if (isset($uploadedMedia->error) || $code != 200) {
+                throw new \Exception('媒体上传失败: ' . json_encode($uploadedMedia));
+            }
 
-            if (!isset($uploadedInit->media_id_string)) {
+            $mediaId = $uploadedMedia->media_id_string;
 
-                throw new \Exception('视频上传初始化失败: ' . json_encode($uploadedInit));
 
-            }
-            $mediaId = $uploadedInit->media_id_string;
-
-            // 分段上传视频
-            $fileHandle = fopen($videoPath, 'r');
-            $segmentId = 0;
-            while (!feof($fileHandle)) {
-                $chunk = fread($fileHandle, 1024 * 1024); // 每次上传 1MB
-                $segmentParams = [
-                    'command' => 'APPEND',
-                    'media_id' => $mediaId,
-                    'segment_index' => $segmentId,
-                    'media' => $chunk,
-                ];
-                $uploadedSegment = $this->twitterOAuth->upload('media/upload', $segmentParams, true);
-                if (!empty($uploadedSegment->error)) {
-                    fclose($fileHandle);
-                    throw new \Exception('视频分段上传失败: ' . json_encode($uploadedSegment));
-                }
-                $segmentId++;
-            }
-            fclose($fileHandle);
-
-            // 1.1版本上传媒体文件 - 完成上传
-            $finalizeParams = [
-                'command' => 'FINALIZE',
-                'media_id' => $mediaId,
-            ];
-            $uploadedFinalize = $this->twitterOAuth->upload('media/upload', $finalizeParams, true);
-            if (isset($uploadedFinalize->processing_info)) {
-                $processingInfo = $uploadedFinalize->processing_info;
-                $checkStatusSecs = $processingInfo->check_after_secs;
-                $status = $processingInfo->state;
-
-                while ($status !== 'succeeded' && $status !== 'failed') {
-                    sleep($checkStatusSecs);
-                    $statusParams = [
+            // 检查媒体处理状态
+            $processingInfo = $uploadedMedia->processing_info ?? null;
+            if ($processingInfo && $processingInfo->state === 'pending') {
+                $checkAfter = $processingInfo->check_after_secs;
+                sleep($checkAfter);
+                do {
+                    $status = $this->twitterOAuth->get("media/upload", [
                         'command' => 'STATUS',
-                        'media_id' => $mediaId,
-                    ];
-                    $uploadedStatus = $this->twitterOAuth->upload('media/upload', $statusParams, true);
-                    if (!empty($uploadedStatus->error)) {
-                        throw new \Exception('获取视频上传状态失败: ' . json_encode($uploadedStatus));
+                        'media_id' => $mediaId
+                    ]);
+                    dd($status);
+                    if (isset($status->error)) {
+                        throw new \Exception("媒体状态检查失败: " . json_encode($status));
                     }
-                    $processingInfo = $uploadedStatus->processing_info;
-                    $checkStatusSecs = $processingInfo->check_after_secs;
-                    $status = $processingInfo->state;
-                    if ($status === 'failed') {
-                        throw new \Exception('视频上传失败,Twitter 处理失败: ' . json_encode($uploadedStatus));
+                    $processingInfo = $status->processing_info ?? null;
+                    if (!$processingInfo || $processingInfo->state === 'failed') {
+                        throw new \Exception("媒体处理失败: " . json_encode($status));
                     }
-                }
-            } elseif (isset($uploadedFinalize->error)) {
-                throw new \Exception('视频上传完成步骤失败: ' . json_encode($uploadedFinalize));
+                    if ($processingInfo->state !== 'succeeded') {
+                        sleep($processingInfo->check_after_secs ?? 5);
+                    }
+                } while ($processingInfo->state !== 'succeeded');
             }
 
 
+
             // 2.0版本发布推文
             $this->twitterOAuth->setApiVersion('2');
             $tweet = $this->twitterOAuth->post('tweets', [
                 'text' => $message,
-                'media' => ['media_ids' => [$mediaId]],
+                'media' => ['media_ids' => [$mediaId]]
             ]);
 
-            if (isset($tweet->errors)) {
-                throw new \Exception('推文发布失败: ' . json_encode($tweet->errors));
-            }
+            dd($tweet);
 
-            return ['status' => true,
-                'data' => [
-                    'responseIds' => [$tweet->data->id],
-                ]
-            ];
         } catch (\Exception $e) {
             return ['status' => false, 'data' => $e->getMessage()];
         }

+ 2 - 1
composer.json

@@ -6,10 +6,11 @@
     "license": "MIT",
     "require": {
         "php": "^8.0.2",
+        "abraham/twitteroauth": "^7.0",
         "alphasnow/aliyun-oss-laravel": "^4.7",
         "dcat-plus/laravel-admin": "^1.2",
-        "facebook/graph-sdk": "5.7.0",
         "fguillot/json-rpc": "^1.3",
+        "google/apiclient": "^2.0",
         "guzzlehttp/guzzle": "^7.2",
         "laravel/framework": "^9.19",
         "laravel/sanctum": "^3.0",

File diff suppressed because it is too large
+ 464 - 177
composer.lock


+ 1 - 0
public/client_secret.json

@@ -0,0 +1 @@
+{"web":{"client_id":"9844894521-9ntqto525r5aavlaqkacj9qagv0vbci3.apps.googleusercontent.com","project_id":"smiling-memory-419602","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"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","redirect_uris":["https://www.ex.com/dist/callback/youtube","https://www.ex.com/2.php"]}}

Some files were not shown because too many files changed in this diff