Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Google Api Laravel Package

tomshaw/google-api

Laravel Google OAuth 2.0 service client with configurable token storage (DB or custom), published config, and migrations. Integrates google/apiclient-services and supports Composer cleanup to include only the Google APIs you need (e.g., Gmail, Calendar).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:

    composer require tomshaw/google-api
    

    Add the pre-autoload script to composer.json to optimize API service loading:

    "scripts": {
        "pre-autoload-dump": "Google\\Task\\Composer::cleanup"
    }
    

    Specify required Google APIs in extra:

    "extra": {
        "google/apiclient-services": ["Gmail", "Calendar"]
    }
    
  2. Publish config:

    php artisan vendor:publish --provider="TomShaw\GoogleApi\Providers\GoogleApiServiceProvider" --tag=config
    

    Configure config/google-api.php with:

    • auth_config: Path to your Google OAuth credentials JSON.
    • service_scopes: Required scopes (e.g., ['https://www.googleapis.com/auth/calendar']).
    • token_storage_adapter: Defaults to DatabaseTokenStorage (run migrations if used).
  3. First OAuth Flow:

    // routes/web.php
    Route::get('/auth/google', [GoogleAuthController::class, 'index']);
    Route::get('/auth/google/callback', [GoogleAuthController::class, 'callback']);
    

First Use Case: Fetch Calendar Events

use TomShaw\GoogleApi\Services\CalendarService;

class CalendarController extends Controller
{
    public function listEvents(CalendarService $calendar)
    {
        $events = $calendar->listEvents('primary');
        return response()->json($events);
    }
}

Implementation Patterns

1. OAuth Workflow

  • Authorization URL: Use GoogleClient::createAuthUrl() to generate OAuth URLs with custom scopes.
    $authUrl = $client->createAuthUrl(['https://www.googleapis.com/auth/gmail.readonly']);
    
  • Callback Handling: Exchange auth code for tokens:
    $accessToken = $client->fetchAccessTokenWithAuthCode($request->get('code'));
    $client->setAccessToken($accessToken);
    

2. Service Integration

  • Dependency Injection: Inject service adapters (e.g., CalendarService, GmailService) into controllers:
    public function __construct(private CalendarService $calendar) {}
    
  • Fluent Methods: Chain methods for API calls:
    $calendar->events()
              ->setMaxResults(10)
              ->setTimeMin('2023-01-01T00:00:00Z')
              ->list();
    

3. Token Management

  • Storage Adapters: Extend StorageAdapterInterface for custom storage (e.g., Redis):
    class RedisTokenStorage implements StorageAdapterInterface {
        public function save($token) { /* ... */ }
        public function find($userId) { /* ... */ }
    }
    
    Update config:
    'token_storage_adapter' => App\Services\RedisTokenStorage::class,
    
  • Refresh Tokens: Automatically refresh expired tokens via middleware:
    $client->setAccessToken($token)->fetch(); // Auto-refreshes if needed
    

4. Error Handling

  • Middleware for OAuth: Validate tokens before API calls:
    public function handle(Request $request, Closure $next) {
        if (!$client->getAccessToken()) {
            return redirect()->route('auth.google');
        }
        return $next($request);
    }
    
  • API Errors: Catch Google_Service_Exception for API-specific errors:
    try {
        $calendar->events()->list();
    } catch (Google_Service_Exception $e) {
        Log::error($e->getMessage());
    }
    

Gotchas and Tips

Pitfalls

  1. API Service Bloat:

    • Only include needed services in composer.json extra to avoid loading unused APIs.
    • Fix: Use Google\Task\Composer::cleanup to prune unused services.
  2. Token Expiry:

    • Offline tokens expire after 1 hour by default. Use access_type: 'offline' and approval_prompt: 'auto' in config to enable refresh tokens.
    • Tip: Store refresh tokens securely and implement a token refresh middleware.
  3. Scope Mismatches:

    • Ensure service_scopes in config match those requested in createAuthUrl().
    • Debug: Check OAuth error responses for missing scope errors.
  4. Database Storage:

    • If using DatabaseTokenStorage, ensure the google_api_tokens table exists (run migrations).
    • Migration: Published with the package under database/migrations/.

Debugging Tips

  • Enable Debugging: Set GOOGLE_APPLICATION_CREDENTIALS environment variable to log API requests:
    export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
    
  • Log Token Errors: Wrap token operations in try-catch:
    try {
        $token = $client->getAccessToken();
    } catch (Exception $e) {
        Log::error('Token fetch failed: ' . $e->getMessage());
    }
    

Extension Points

  1. Custom Services:
    • Extend GoogleService to add domain-specific methods:
    class CustomCalendarService extends GoogleService {
        public function getUserEvents($userId) {
            return $this->client->calendar->events->listCalendarEvents($userId);
        }
    }
    
  2. Middleware for API Calls:
    • Create middleware to validate tokens or transform responses:
    public function handle($request, Closure $next) {
        $response = $next($request);
        return $response->header('X-Google-API', 'Processed');
    }
    
  3. Event Listeners:
    • Listen for token refresh events:
    public function handle(TokenRefreshed $event) {
        Log::info('Token refreshed for user: ' . $event->userId);
    }
    

Performance

  • Lazy-Load Services: Initialize services only when needed to reduce memory usage:
    if ($request->has('calendar')) {
        $calendar = app(CalendarService::class);
    }
    
  • Batch API Calls: Use setMaxResults() and pagination for large datasets:
    $events = $calendar->events()->setMaxResults(100)->list();
    while ($events->getNextPageToken()) {
        $events = $calendar->events()->setPageToken($events->getNextPageToken())->list();
    }
    

Security

  • Scope Minimization: Request only the scopes necessary for your app (e.g., avoid https://www.googleapis.com/auth/userinfo.profile if unused).
  • Token Revocation: Implement a route to revoke tokens:
    $client->deleteAccessToken(); // Clears stored token
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle
dmstr/api-platform-utils-bundle
dmstr/api-configuration-bundle
chrisdev/ux-components
baks-dev/finances
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle