112 lines
3.2 KiB
PHP
Executable File
112 lines
3.2 KiB
PHP
Executable File
<?php
|
|
|
|
namespace Common\Settings\Mail;
|
|
|
|
use File;
|
|
use Google\Service\Gmail\Message;
|
|
use Google\Service\Gmail\WatchRequest;
|
|
use Google\Service\Gmail\WatchResponse;
|
|
use Google_Client;
|
|
use Google_Service_Gmail;
|
|
|
|
class GmailClient
|
|
{
|
|
private Google_Service_Gmail $gmail;
|
|
|
|
private Google_Client $googleClient;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->buildGoogleClient();
|
|
}
|
|
|
|
public static function tokenPath(): string
|
|
{
|
|
return storage_path('app/tokens/gmail.json');
|
|
}
|
|
|
|
public static function tokenExists(): bool
|
|
{
|
|
return file_exists(self::tokenPath());
|
|
}
|
|
|
|
public function sendEmail(string $rawContent): Message
|
|
{
|
|
$encoded = strtr(base64_encode($rawContent), ['+' => '-', '/' => '_']);
|
|
$msg = new Message();
|
|
$msg->setRaw($encoded);
|
|
return $this->gmail->users_messages->send('me', $msg);
|
|
}
|
|
|
|
public function listHistory(int $historyId): array
|
|
{
|
|
$response = $this->gmail->users_history->listUsersHistory('me', [
|
|
'startHistoryId' => $historyId,
|
|
]);
|
|
|
|
$messageIds = collect($response['history'])
|
|
->map(function ($history) {
|
|
$msg = $history['messagesAdded'][0]['message'] ?? null;
|
|
$labels = $msg['labelIds'] ?? [];
|
|
|
|
if ($msg && !in_array('SENT', $labels)) {
|
|
return $msg['id'];
|
|
}
|
|
})
|
|
->filter();
|
|
|
|
if ($messageIds->isEmpty()) {
|
|
return [];
|
|
}
|
|
|
|
$this->googleClient->setUseBatch(true);
|
|
$batch = $this->gmail->createBatch();
|
|
|
|
$messageIds->each(function ($msgId) use ($batch) {
|
|
$request = $this->gmail->users_messages->get('me', $msgId, [
|
|
'format' => 'raw',
|
|
]);
|
|
$batch->add($request);
|
|
});
|
|
|
|
$this->googleClient->setUseBatch(false);
|
|
|
|
return array_values($batch->execute());
|
|
}
|
|
|
|
public function watch(): WatchResponse
|
|
{
|
|
$payload = new WatchRequest();
|
|
$payload->topicName = settings('incoming_email.gmail.topicName');
|
|
$payload->labelIds = ['UNREAD'];
|
|
$payload->labelFilterAction = 'include';
|
|
return $this->gmail->users->watch('me', $payload);
|
|
}
|
|
|
|
private function buildGoogleClient(): void
|
|
{
|
|
$this->googleClient = new Google_Client();
|
|
$this->googleClient->setClientId(config('services.google.client_id'));
|
|
$this->googleClient->setClientSecret(
|
|
config('services.google.client_secret'),
|
|
);
|
|
|
|
if (self::tokenExists()) {
|
|
$tokenJson = file_get_contents(self::tokenPath());
|
|
$accessToken = json_decode($tokenJson, true);
|
|
$this->googleClient->setAccessToken($accessToken);
|
|
}
|
|
|
|
if ($this->googleClient->isAccessTokenExpired()) {
|
|
$newToken = $this->googleClient->fetchAccessTokenWithRefreshToken(
|
|
$this->googleClient->getRefreshToken(),
|
|
);
|
|
$oldToken = json_decode(File::get(self::tokenPath()), true);
|
|
$mergedToken = array_merge($oldToken, $newToken);
|
|
File::put(self::tokenPath(), json_encode($mergedToken));
|
|
}
|
|
|
|
$this->gmail = new Google_Service_Gmail($this->googleClient);
|
|
}
|
|
}
|