petitpress/gps-messenger-bundle
Laravel bundle for GPS Messenger: send and receive location-based messages, integrate tracking updates, and manage messaging workflows via simple configuration. Designed to drop into existing apps with minimal setup for GPS-enabled notifications and events.
Installation
composer require petitpress/gps-messenger-bundle
Add to config/bundles.php:
return [
// ...
Petitpress\GpsMessengerBundle\PetitpressGpsMessengerBundle::class => ['all' => true],
];
Configuration Publish the default config:
php bin/console petitpress:gps-messenger:config:init
Update config/packages/petitpress_gps_messenger.yaml with your Google Cloud credentials and project ID:
petitpress_gps_messenger:
client:
project_id: "your-project-id"
key_file: "%kernel.project_dir%/config/google-credentials.json"
transports:
gps_async:
dsn: "gps://default/async-topic"
options:
subscription: "async-subscription"
First Use Case Define a message class:
namespace App\Message;
class SendEmailMessage
{
public function __construct(public string $email, public string $subject) {}
}
Configure the transport in config/packages/messenger.yaml:
messenger:
transports:
gps_async: "%env(MESSENGER_TRANSPORT_DSN)%"
routing:
'App\Message\SendEmailMessage': gps_async
Dispatch a message:
$bus->dispatch(new SendEmailMessage('user@example.com', 'Welcome!'));
Dispatch Messages
Use the gps_async transport for background tasks (e.g., emails, reports):
$bus->dispatch(new GenerateReportMessage($userId));
Handle Messages Create a worker to process messages:
php bin/console messenger:consume gps_async -vv
Or use a cron job for scheduled consumption.
Retry Logic Leverage Symfony Messenger’s retry mechanism via config:
messenger:
transports:
gps_async:
dsn: "gps://default/retry-topic"
options:
retry_strategy:
max_retries: 3
delay: 1000
Error Handling
Subscribe to Petitpress\GpsMessengerBundle\Event\MessageFailedEvent to log failures:
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class GpsMessengerSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
MessageFailedEvent::class => 'onMessageFailed',
];
}
public function onMessageFailed(MessageFailedEvent $event): void
{
// Log or notify (e.g., Slack)
}
}
Batching Process messages in batches for efficiency:
messenger:
transports:
gps_async:
options:
batch_size: 50
Environment-Specific Config
Use .env for dynamic DSNs:
transports:
gps_async: "%env(MESSENGER_GPS_DSN)%"
MESSENGER_GPS_DSN=gps://staging-topic
Credentials Management
key_file paths to version control. Use environment variables or secure vaults.roles/pubsub.publisher and roles/pubsub.subscriber).Subscription Management
php bin/console petitpress:gps-messenger:subscription:create async-subscription async-topic
Message Size Limits
Timeouts
options:
timeout: 30.0
Check Subscription Backlog Use the GCP Console or CLI to inspect pending messages:
gcloud pubsub subscriptions pull async-subscription --auto-ack --limit 1
Enable Debugging
Add to config/packages/monolog.yaml:
handlers:
gps_messenger:
type: stream
path: "%kernel.logs_dir%/gps_messenger.log"
level: debug
channels: ["messenger"]
Common Errors
Custom Middleware Add middleware to transform messages before sending:
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
use Symfony\Component\Messenger\Envelope;
class AddMetadataMiddleware implements MiddlewareInterface
{
public function handle(Envelope $envelope, callable $next): Envelope
{
$envelope = $next($envelope);
$envelope = $envelope->with(new Metadata(['source' => 'laravel-app']));
return $envelope;
}
}
Register in config/packages/messenger.yaml:
messenger:
middleware:
- App\Middleware\AddMetadataMiddleware
Dynamic Routing Route messages dynamically based on conditions:
$bus->dispatch(new MyMessage(), ['transport' => $user->isPremium() ? 'gps_premium' : 'gps_async']);
Testing Mock the transport in tests:
use Petitpress\GpsMessengerBundle\Transport\GpsTransport;
$transport = $this->createMock(GpsTransport::class);
$transport->method('send')->willReturn(new Envelope(new MyMessage()));
$this->container->set(GpsTransport::class, $transport);
How can I help you explore Laravel packages today?