Files
finance_app/app/Console/Commands/TestGmailFetch.php
henry yo 85972f950c feat: 前端分離+功能api化
1. 新增資產管理CRUD、googleOAuth登入
2. 更改原記帳controller
2026-06-25 14:19:07 +08:00

116 lines
3.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\User;
use Google\Client as GoogleClient;
use Google\Service\Gmail;
use Illuminate\Support\Facades\Log;
class TestGmailFetch extends Command
{
protected $signature = 'gmail:test-fetch';
protected $description = '測試抓取最新的一筆發票或刷卡信件,並輸出至 Log 中';
public function handle()
{
// 1. 抓取你剛才綁定成功的使用者(假設 ID 為 1
$user = User::find(1);
if (!$user || !$user->google_refresh_token) {
$this->error('找不到使用者,或該使用者尚未擁有 google_refresh_token');
return;
}
$this->info("🔄 正在初始化 Google Client 并刷新 Token...");
// 2. 初始化 Google Client
$client = new GoogleClient();
$client->setClientId(config('services.google.client_id'));
$client->setClientSecret(config('services.google.client_secret'));
// 用 refresh_token 去跟 Google 交換新的短期 access_token
$client->refreshToken($user->google_refresh_token);
$accessToken = $client->getAccessToken();
// 順手把新的 token 蓋回資料庫(防呆)
$user->update([
'google_access_token' => $accessToken['access_token'],
'google_token_expires_at' => now()->addSeconds($accessToken['expires_in']),
]);
// 3. 呼叫 Gmail 服務
$gmailService = new Gmail($client);
$this->info("🔍 正在透過標籤精準搜尋信用卡消費通知...");
$searchQuery = 'label:信用卡 -is:spam -is:trash';
$response = $gmailService->users_messages->listUsersMessages('me', [
'maxResults' => 1, // 先抓一筆來看內文
'q' => $searchQuery
]);
$messages = $response->getMessages();
if (empty($messages)) {
$this->warn('❌ 找不到任何符合關鍵字的信件!請確認你的 Gmail 裡有這種類型的信。');
return;
}
$msgId = $messages[0]->getId();
$this->info("🎯 成功找到信件 ID: {$msgId},正在下載詳細內容...");
// 4. 抓取信件完整細節
$message = $gmailService->users_messages->get('me', $msgId, ['format' => 'full']);
$payload = $message->getPayload();
$headers = $payload->getHeaders();
// 解析主旨
$subject = '';
foreach ($headers as $header) {
if ($header->getName() === 'Subject') {
$subject = $header->getValue();
break;
}
}
// 解析內文 (處理可能存在的多重 Multipart 結構)
$body = $this->getDecodedBody($payload);
// 5. 🟢 核心現形:把內容原封不動地噴進 Log
Log::info("=== 【GMAIL 測試抓取成功】 ===");
Log::info("主旨: " . $subject);
Log::info("信件 ID: " . $msgId);
Log::info("=== 原始內文開始 ===");
Log::info($body);
Log::info("=== 原始內文結束 ===");
$this->info("✅ 抓取完畢!真實內容已成功寫入 storage/logs/laravel.log快去打開瞧瞧吧");
}
/**
* 輔助方法:遞迴解析 Gmail 的 Body 內容
*/
private function getDecodedBody($part)
{
$body = $part->getBody();
if ($body && $body->getData()) {
// Gmail 的 base64 比較特殊,需要把 - 和 _ 換回來
$sanitizedData = str_replace(['-', '_'], ['+', '/'], $body->getData());
return base64_decode($sanitizedData);
}
$parts = $part->getParts();
if ($parts) {
foreach ($parts as $subPart) {
$result = $this->getDecodedBody($subPart);
if ($result) return $result;
}
}
return '';
}
}