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 Chat Notifier Laravel Package

symfony/google-chat-notifier

Symfony Notifier integration for Google Chat. Configure a googlechat:// DSN with access key/token and target space, optionally providing a thread_key to group messages into a single thread.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package

    composer require symfony/google-chat-notifier
    

    For Laravel, ensure compatibility with Symfony’s Notifier component (v6+).

  2. Configure the DSN Add to .env:

    GOOGLE_CHAT_DSN=googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE_NAME?thread_key=THREAD_ID
    
    • Replace ACCESS_KEY/ACCESS_TOKEN with your Google Chat API credentials.
    • SPACE_NAME is the Google Chat space ID (e.g., ABC123).
    • thread_key (optional) groups messages into a thread.
  3. First Notification (Laravel) Use Laravel’s Bus or Events to trigger a notification:

    use Symfony\Component\Notifier\NotifierInterface;
    use Symfony\Component\Notifier\Message\ChatMessage;
    
    // In a Laravel service or event listener:
    $notifier = app(NotifierInterface::class);
    $notifier->send(new ChatMessage('Hello from Laravel!', (new ChatTransport())->withDsn(env('GOOGLE_CHAT_DSN'))));
    
  4. First Notification (Symfony)

    use Symfony\Component\Notifier\NotifierInterface;
    use Symfony\Component\Notifier\Message\ChatMessage;
    
    $notifier = new NotifierInterface([new GoogleChatTransport(env('GOOGLE_CHAT_DSN'))]);
    $notifier->send(new ChatMessage('Hello from Symfony!'));
    

First Use Case: Deployment Alerts

  1. Create a Laravel Event

    // Event
    class DeploymentStarted implements ShouldBroadcast
    {
        public function broadcastOn(): array
        {
            return [new GoogleChatChannel()];
        }
    }
    
  2. Broadcast the Event

    // In a controller or job:
    event(new DeploymentStarted('v1.2.0'));
    
  3. Handle the Event with a Listener

    use Symfony\Component\Notifier\Message\ChatMessage;
    
    class GoogleChatDeploymentListener
    {
        public function handle(DeploymentStarted $event)
        {
            $notifier = app(NotifierInterface::class);
            $notifier->send(new ChatMessage(
                "Deployment started: {$event->version}",
                (new GoogleChatTransport(env('GOOGLE_CHAT_DSN')))
                    ->withOption('thread_key', 'deployments')
            ));
        }
    }
    

Implementation Patterns

1. Transport Configuration

  • DSN Structure:

    googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE_NAME?thread_key=THREAD_ID
    
    • Use default for the transport name if only one space is configured.
    • For multiple spaces, define multiple DSNs in .env and switch dynamically:
      $transport = new GoogleChatTransport(env('GOOGLE_CHAT_DSN_ONCALL'));
      
  • Dynamic Threading: Use thread_key to group related messages (e.g., incident_123). Reset threads by omitting the key or using a new one.

2. Message Customization

  • Rich Cards: Leverage Google Chat’s card schema for interactive messages:

    $message = new ChatMessage('Incident Alert!');
    $message->card([
        'header' => ['title' => 'Critical Issue'],
        'sections' => [
            ['widgets' => [
                ['buttons' => [
                    ['textButton' => ['text' => 'Acknowledge', 'onClick' => ['openLink' => 'https://jira.com/123']]],
                ]],
            ]],
        ],
    ]);
    
  • Attachments: Add files (e.g., logs, screenshots) via base64-encoded data or URLs:

    $message->attachment('data:image/png;base64,' . base64_encode(file_get_contents('error.png')));
    

3. Integration with Laravel Ecosystem

  • Events: Use Laravel’s dispatch() to trigger notifications:

    dispatch(new GoogleChatNotification('New user registered: ' . $user->email));
    
  • Queues: Queue notifications for async delivery:

    GoogleChatNotification::dispatch($message)
        ->delay(now()->addMinutes(5))
        ->onQueue('notifications');
    
  • Tasks: Combine with Laravel Tasks for scheduled alerts:

    Task::create()
        ->name('daily-metrics')
        ->everyMinute()
        ->run(function () {
            $notifier = app(NotifierInterface::class);
            $notifier->send(new ChatMessage('Daily metrics report', ...));
        });
    

4. Symfony Integration

  • Dependency Injection: Register the transport in services.yaml:

    services:
        Symfony\Component\Notifier\NotifierInterface:
            arguments:
                - ['@google_chat.transport']
    
        google_chat.transport:
            class: Symfony\Component\Notifier\Bridge\GoogleChat\GoogleChatTransport
            arguments:
                - '%env(GOOGLE_CHAT_DSN)%'
    
  • Messenger Component: Use Symfony’s Messenger to handle notifications as messages:

    use Symfony\Component\Messenger\MessageBusInterface;
    
    $bus->dispatch(new ChatNotificationMessage('Hello from Messenger!'));
    

5. Testing

  • Mock the Transport:

    $transport = $this->createMock(GoogleChatTransport::class);
    $transport->method('send')->willReturn(true);
    
    $notifier = new NotifierInterface([$transport]);
    $notifier->send(new ChatMessage('Test'));
    
  • DSN Validation: Test DSN parsing in isolation:

    $dsn = 'googlechat://key:token@default/space?thread_key=123';
    $transport = new GoogleChatTransport($dsn);
    $this->assertEquals('space', $transport->getSpace());
    

Gotchas and Tips

Pitfalls

  1. DSN Format Sensitivity:

    • Gotcha: Extra spaces or missing @default in the DSN will throw InvalidArgumentException.
    • Fix: Validate the DSN format:
      if (!preg_match('/^googlechat:\/\/[^@]+@default\/[^?]+(\?[^#]*)?$/', $dsn)) {
          throw new \InvalidArgumentException('Invalid Google Chat DSN format.');
      }
      
  2. Thread Key Handling:

    • Gotcha: If thread_key is omitted, each message creates a new thread. Google Chat may rate-limit rapid thread creation.
    • Fix: Use a static thread_key for grouped alerts (e.g., incidents) or regenerate it periodically.
  3. Authentication Expiry:

    • Gotcha: Google Chat API tokens expire. The package does not auto-refresh tokens.
    • Fix: Implement a token refresh flow in a Laravel job or Symfony command:
      // Example: Refresh token via Google API client
      $client = new Google_Client(['client_id' => 'YOUR_ID', 'client_secret' => 'YOUR_SECRET']);
      $client->fetchAccessTokenWithRefreshToken($refreshToken);
      
  4. Rate Limiting:

    • Gotcha: Google Chat enforces quotas (e.g., 100 messages/minute).
    • Fix: Implement exponential backoff in the transport:
      use Symfony\Component\HttpClient\RetryableHttpClient;
      use Symfony\Contracts\HttpClient\RetryStrategyInterface;
      
      $client = new RetryableHttpClient(
          new RetryStrategyInterface(function (RetryableHttpClient $client, int $retries, int $maxRetries) {
              return $retries < $maxRetries ? 1000 : 0; // Retry after 1s
          })
      );
      
  5. Message Length Limits:

    • Gotcha: Google Chat truncates messages > 2000 characters.
    • Fix: Split long messages into sections or use attachments for details.

Debugging Tips

  1. Enable HTTP Logging: Configure Symfony’s HttpClient to log requests:

    $client = HttpClient::create([
        'headers' => ['User-Agent' => 'Laravel/GoogleChatNotifier'],
        'debug' => true, // Logs requests to `var/log/http_client.log`
    ]);
    
  2. Validate API Responses: Check for Google Chat-specific errors (e.g., 403 Forbidden for invalid scopes):

    try {
        $response = $transport->send($message);
    } catch (\Symfony\Contracts\HttpClient\Exception\ClientException
    
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle