1. Go to this page and download the library: Download partridgerocks/gmail-client library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
partridgerocks / gmail-client example snippets
use PartridgeRocks\GmailClient\Facades\GmailClient;
// Get recent messages
$messages = GmailClient::listMessages();
// Get a specific message
$message = GmailClient::getMessage('message-id');
// Send an email
$email = GmailClient::sendEmail(
'[email protected]',
'Subject line',
'<p>Email body in HTML format</p>'
);
use PartridgeRocks\GmailClient\Facades\GmailClient;
// 1. Get the authorization URL
$authUrl = GmailClient::getAuthorizationUrl(
config('gmail-client.redirect_uri'),
config('gmail-client.scopes'),
[
'access_type' => 'offline',
'prompt' => 'consent'
]
);
// 2. Redirect the user to the authorization URL
return redirect($authUrl);
// 3. In your callback route, exchange the code for tokens
public function handleCallback(Request $request)
{
$code = $request->get('code');
// Exchange code for tokens
$tokens = GmailClient::exchangeCode(
$code,
config('gmail-client.redirect_uri')
);
// Store tokens securely for the authenticated user
auth()->user()->update([
'gmail_access_token' => $tokens['access_token'],
'gmail_refresh_token' => $tokens['refresh_token'] ?? null,
'gmail_token_expires_at' => now()->addSeconds($tokens['expires_in']),
]);
return redirect()->route('dashboard');
}
// Generate a link to the Gmail authentication page
<a href="{{ route('gmail.auth.redirect') }}">Connect Gmail</a>
use PartridgeRocks\GmailClient\Facades\GmailClient;
// Authenticate with a stored token
GmailClient::authenticate($accessToken);
// List recent messages (returns a collection of Email data objects)
$messages = GmailClient::listMessages(['maxResults' => 10]);
foreach ($messages as $message) {
echo "From: {$message->from}\n";
echo "Subject: {$message->subject}\n";
echo "Date: {$message->internalDate->format('Y-m-d H:i:s')}\n";
echo "Body: {$message->body}\n";
}
// With query parameters (using Gmail search syntax)
$messages = GmailClient::listMessages([
'q' => 'from:[email protected] after:2023/01/01 has:attachment',
'maxResults' => 20
]);
// Get a specific message by ID
$email = GmailClient::getMessage('message-id');
echo "Subject: {$email->subject}\n";
echo "From: {$email->from}\n";
echo "Snippet: {$email->snippet}\n";
echo "Body: {$email->body}\n";
// Access message headers
foreach ($email->headers as $name => $value) {
echo "{$name}: {$value}\n";
}
// Check for specific labels
if (in_array('INBOX', $email->labelIds)) {
echo "This message is in the inbox\n";
}
// Send a simple email
$email = GmailClient::sendEmail(
'[email protected]',
'Email subject',
'<p>This is the email body in HTML format.</p>'
);
// Send with additional options
$email = GmailClient::sendEmail(
'[email protected]',
'Email with options',
'<p>This email
// Get comprehensive account metrics in 1-2 API calls
$stats = GmailClient::getAccountStatistics([
'unread_limit' => 25, // Show exact count up to 25, then "25+"
'today_limit' => 15, // Today's messages limit
'day_count' => 8, // Today's messages
// 'labels_count' => 42, // Total labels
// 'estimated_total' => 15000, // Total mailbox size estimate
// 'api_calls_made' => 2, // Actual API calls used
// 'last_updated' => '2024-01-01T12:00:00Z',
// 'partial_failure' => false, // True if some metrics failed
// ]
// Performance comparison:
// Before: 3-5 API calls per account, 2-5s load time
// After: 1-2 API calls per account, <1s load time
$health = GmailClient::getAccountHealth();
// Returns:
// [
// 'connected' => true,
// 'status' => 'healthy', // healthy, unhealthy, rate_limited, etc.
// 'api_quota_remaining' => 250, // Remaining API calls (if available)
// 'last_successful_call' => '2024-01-01T12:00:00Z',
// 'errors' => [], // Array of error messages
// ]
// Use for dashboard health indicators
if ($health['status'] === 'rate_limited') {
// Handle rate limiting gracefully
$retryAfter = $health['retry_after'] ?? 60;
}
// Get an email message
$email = GmailClient::getMessage('message-id');
// Access parsed contact information
$sender = $email->fromContact;
echo "Sender: {$sender->name} <{$sender->email}>\n";
echo "Domain: {$sender->domain}\n";
// Access recipient contacts
foreach ($email->toContacts as $contact) {
echo "To: {$contact->getDisplayName()} - {$contact->email}\n";
}
// Get all contacts involved in the email
$allContacts = $email->getAllContacts();
// Find contacts from specific domain (useful for CRM)
$externalContacts = array_filter(
$allContacts,
fn($contact) => !$contact->isFromDomain('mycompany.com')
);
// Get unique domains for company identification
$domains = $email->getContactDomains();
// Returns: ['example.com', 'client.com', 'mycompany.com']
// Check if email involves specific company
if ($email->hasContactFromDomain('important-client.com')) {
// Handle VIP client email
}
// Get all contacts from a domain
$clientContacts = $email->getContactsFromDomain('acme-corp.com');
// Find all emails from a specific company
$companyEmails = collect($emails)->filter(function ($email) {
return $email->hasContactFromDomain('target-company.com');
});
// Extract contact data for CRM import
$crmData = [];
foreach ($emails as $email) {
foreach ($email->getAllContacts() as $contact) {
if (!$contact->isFromDomain('mycompany.com')) {
$crmData[] = [
'name' => $contact->name,
'email' => $contact->email,
'company_domain' => $contact->domain,
'first_contact' => $email->internalDate,
];
}
}
}
// Group contacts by company domain
$contactsByCompany = collect($emails)
->flatMap(fn($email) => $email->getAllContacts())
->groupBy('domain')
->map(fn($contacts) => $contacts->unique('email'));
// List all labels
$labels = GmailClient::listLabels();
foreach ($labels as $label) {
echo "Label: {$label->name} (ID: {$label->id})\n";
echo "Type: {$label->type}\n";
if ($label->messagesTotal !== null) {
echo "Messages: {$label->messagesTotal} ({$label->messagesUnread} unread)\n";
}
}
// Get a specific label
$label = GmailClient::getLabel('label-id');
// Create a new label
$newLabel = GmailClient::createLabel('Important Clients', [
'labelListVisibility' => 'labelShow',
'messageListVisibility' => 'show',
'color' => [
'backgroundColor' => '#16a765',
'textColor' => '#ffffff'
]
]);
// Update a label (using the LabelResource directly)
$updatedLabel = GmailClient::labels()->update($label->id, [
'name' => 'VIP Clients',
'color' => [
'backgroundColor' => '#4986e7',
'textColor' => '#ffffff'
]
]);
// Delete a label
GmailClient::labels()->delete($label->id);
use PartridgeRocks\GmailClient\GmailClient;
public function index(GmailClient $gmailClient)
{
$gmailClient->authenticate($accessToken);
$messages = $gmailClient->listMessages();
// ...
}
use PartridgeRocks\GmailClient\Builders\GmailClientBuilder;
use PartridgeRocks\GmailClient\Contracts\MessageServiceInterface;
// Using builder pattern
$client = GmailClientBuilder::create()
->withToken($accessToken)
->withConfig($customConfig)
->build();
// Using service injection
class EmailController extends Controller
{
public function __construct(private MessageServiceInterface $messageService) {}
public function dashboard()
{
$recentMessages = $this->messageService->findRecent(10);
return view('dashboard', compact('recentMessages'));
}
}
// In your User model
public function connectGmail($accessToken, $refreshToken = null, $expiresAt = null)
{
$this->gmail_access_token = $accessToken;
$this->gmail_refresh_token = $refreshToken;
$this->gmail_token_expires_at = $expiresAt;
$this->save();
}
public function getGmailClient()
{
if (empty($this->gmail_access_token)) {
throw new \Exception('Gmail not connected');
}
return app(GmailClient::class)->authenticate(
$this->gmail_access_token,
$this->gmail_refresh_token,
$this->gmail_token_expires_at ? new \DateTime($this->gmail_token_expires_at) : null
);
}
// In your controller
public function listEmails()
{
$gmailClient = auth()->user()->getGmailClient();
return $gmailClient->listMessages(['maxResults' => 20]);
}
// Get a paginator for messages
$paginator = GmailClient::listMessages(['maxResults' => 25], true);
// Get the first page
$firstPage = $paginator->getNextPage();
// Check if there are more pages
if ($paginator->hasMorePages()) {
// Get the next page
$secondPage = $paginator->getNextPage();
}
// Or get all pages at once (use cautiously with large datasets)
$allMessages = $paginator->getAllPages();
// You can also transform the results using the DTO
use PartridgeRocks\GmailClient\Data\Responses\EmailDTO;
$emails = $paginator->transformUsingDTO(EmailDTO::class);
// Lazy loading is the most memory-efficient approach for large datasets
$messages = GmailClient::listMessages(lazy: true);
// Process messages one by one without loading everything into memory
foreach ($messages as $message) {
processMessage($message);
// You can stop iteration at any point
if ($someCondition) {
break;
}
}
// For even more efficiency, you can get only message IDs without full details
$messageIds = GmailClient::listMessages(lazy: true, fullDetails: false);
foreach ($messageIds as $messageData) {
echo "Message ID: {$messageData['id']}\n";
// Load full details only for specific messages if needed
if (needsFullDetails($messageData)) {
$fullMessage = GmailClient::getMessage($messageData['id']);
}
}
// ✅ Safe for dashboards - returns empty collection on any error
$labels = GmailClient::safeListLabels();
$messages = GmailClient::safeListMessages(['q' => 'is:unread']);
// ✅ Returns null instead of throwing NotFoundException
$message = GmailClient::safeGetMessage('message-id');
// ✅ Connection health check - never throws exceptions
if (GmailClient::isConnected()) {
// Safe to proceed with Gmail operations
}
// ✅ Account overview with fallback data
$summary = GmailClient::getAccountSummary();
// Returns: ['connected' => true, 'labels_count' => 15, 'has_unread' => true, 'errors' => []]
// ✅ Statistics with graceful degradation
$stats = GmailClient::safeGetAccountStatistics();
// Returns fallback data if API fails: ['unread_count' => '?', 'partial_failure' => true]
use PartridgeRocks\GmailClient\Exceptions\AuthenticationException;
use PartridgeRocks\GmailClient\Exceptions\NotFoundException;
use PartridgeRocks\GmailClient\Exceptions\RateLimitException;
use PartridgeRocks\GmailClient\Exceptions\ValidationException;
try {
$message = GmailClient::getMessage('non-existent-id');
} catch (NotFoundException $e) {
// Handle not found error
echo "Message not found: " . $e->getMessage();
} catch (AuthenticationException $e) {
// Handle authentication errors
echo "Authentication error: " . $e->getMessage();
if ($e->getError()->code === 'token_expired') {
// Refresh the token
$tokens = GmailClient::refreshToken($refreshToken);
}
} catch (RateLimitException $e) {
// Handle rate limit errors
$retryAfter = $e->getRetryAfter();
echo "Rate limit exceeded. Retry after {$retryAfter} seconds.";
} catch (ValidationException $e) {
// Handle validation errors
echo "Validation error: " . $e->getMessage();
}
// Refresh an expired token
$tokens = GmailClient::refreshToken($refreshToken);
// The client is automatically authenticated with the new token
// Update the tokens in your storage
$user->update([
'gmail_access_token' => $tokens['access_token'],
'gmail_refresh_token' => $tokens['refresh_token'] ?? $user->gmail_refresh_token,
'gmail_token_expires_at' => now()->addSeconds($tokens['expires_in']),
]);
'performance' => [
'enable_smart_counting' => true, // Enable smart count estimation
'count_estimation_threshold' => 50, // Show exact count up to this limit
'default_cache_ttl' => 300, // Cache TTL in seconds (future use)
'max_concurrent_requests' => 3, // Max concurrent API requests (future use)
'enable_circuit_breaker' => true, // Enable circuit breaker pattern (future use)
'api_timeout' => 30, // API request timeout in seconds
],
'multi_account' => [
'max_accounts_per_user' => 5, // Maximum Gmail accounts per user
'health_check_interval' => 3600, // Health check interval in seconds
'enable_bulk_operations' => true, // Enable bulk operations (future use)
],
use Saloon\Laravel\Facades\Saloon;
use Saloon\Http\Faking\MockResponse;
// In your test setup
public function setUp(): void
{
parent::setUp();
// Mock all Gmail API responses
Saloon::fake([
'*gmail.googleapis.com*' => MockResponse::make([
'messages' => [
[
'id' => 'test-id-123',
'threadId' => 'thread-123',
'snippet' => 'This is a test email',
]
]
], 200),
]);
}