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

Wasenderapi Symfony Laravel Package

art-fatal/wasenderapi-symfony

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the package:
    composer require wasenderapi/wasenderapi-symfony
    
  2. Configure the bundle:
    • Add to config/bundles.php:
      WasenderApi\SymfonyBundle\WasenderApiBundle::class => ['all' => true],
      
    • Create config/packages/wasenderapi.yaml with your API credentials:
      wasenderapi:
          api_key: '%env(WASENDERAPI_API_KEY)%'
          personal_access_token: '%env(WASENDERAPI_PERSONAL_ACCESS_TOKEN)%'
          base_url: 'https://www.wasenderapi.com/api'
          webhook:
              secret: '%env(WASENDERAPI_WEBHOOK_SECRET)%'
              path: '/wasender/webhook'
      
  3. Set environment variables in .env:
    WASENDERAPI_API_KEY=your_api_key_here
    WASENDERAPI_PERSONAL_ACCESS_TOKEN=your_token_here
    WASENDERAPI_WEBHOOK_SECRET=your_webhook_secret_here
    
  4. Register the webhook route in config/routes.yaml:
    wasenderapi_webhook:
        resource: '@WasenderApiBundle/Resources/config/routing.xml'
    

First Use Case: Sending a Text Message

Inject the WasenderApiClient into a controller or service and send a message:

use WasenderApi\SymfonyBundle\Client\WasenderApiClient;

class WhatsAppController
{
    public function __construct(private WasenderApiClient $wasender) {}

    public function sendWelcomeMessage()
    {
        $this->wasender->sendText('1234567890', 'Welcome to our service!');
        return new Response('Message sent!');
    }
}

Implementation Patterns

Dependency Injection Workflow

  • Preferred: Use dependency injection for type safety and testability.
    public function __construct(WasenderApiClient $wasender) {}
    
  • Multiple sessions: Use direct instantiation with different API keys:
    $client = new WasenderApiClient('api_key_for_session_1');
    

Message Sending Patterns

  • DTOs for complex payloads: Use DTOs for clarity and validation:
    $client->sendImage(
        new SendImageMessageData('123', 'https://example.com/image.png', 'Caption')
    );
    
  • Batch operations: Combine with Symfony’s CommandBus or Messenger for async processing.

Webhook Integration

  • Event-driven architecture: Subscribe to events for real-time updates:
    class WasenderEventSubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents(): array
        {
            return [MessageReceived::class => 'handleIncomingMessage'];
        }
    }
    
  • Route validation: Ensure the webhook route is protected and validates signatures:
    # config/routes.yaml
    wasenderapi_webhook:
        path: /wasender/webhook
        methods: [POST]
        defaults: { _controller: 'WasenderApiBundle:Webhook:handle' }
    

Media Handling

  • Base64 vs. file uploads: Choose based on use case (e.g., base64 for dynamic content, files for static assets):
    $client->uploadMediaFile('data:image/png;base64,...'); // Dynamic
    $client->uploadMediaFile('/path/to/file.png');         // Static
    

Rate Limiting

  • Retry logic: Use RetryConfig for transient failures:
    $retryConfig = new RetryConfig(true, 3); // Retry 3 times
    $client->sendText('123', 'Hello', [], $retryConfig);
    

Gotchas and Tips

Pitfalls

  1. Webhook Signature Mismatch:
    • Ensure WASENDERAPI_WEBHOOK_SECRET matches the secret in WasenderAPI dashboard.
    • Debug with:
      // In your webhook handler, log the signature comparison:
      $isValid = $this->wasender->verifyWebhookSignature(
          $request->getContent(),
          $request->headers->get('x-webhook-signature')
      );
      
  2. Rate Limiting (HTTP 429):
    • Enable retries with RetryConfig to avoid dropped messages.
    • Monitor response headers for Retry-After to adjust delays.
  3. Session Management:
    • Personal access tokens are required for session operations. Regenerate tokens via:
      $client->regenerateApiKey($sessionId);
      
  4. Group JIDs:
    • Group operations require valid JIDs (e.g., group@g.us). Fetch via getGroups() first.
    • Avoid hardcoding JIDs; store them dynamically in your database.

Debugging Tips

  • Enable Guzzle Debugging: Add to config/packages/wasenderapi.yaml:

    wasenderapi:
        debug: '%kernel.debug%'
    

    This logs HTTP requests/responses to var/log/dev.log.

  • Event Dispatcher: Use Symfony’s EventDispatcher to log all webhook events:

    public function onMessageReceived(MessageReceived $event): void
    {
        $this->logger->info('Message received', ['payload' => $event->getPayload()]);
    }
    

Extension Points

  1. Custom Events: Extend the event system by creating your own event classes and dispatching them in subscribers:

    $dispatcher->dispatch(new CustomWasenderEvent($payload));
    
  2. Middleware: Add Guzzle middleware for logging, caching, or modifying requests:

    $client->getGuzzleClient()->getEmitter()->attach(
        new \GuzzleHttp\Middleware::tap(function ($request) {
            $this->logger->debug('WasenderAPI request', ['url' => $request->getUri()]);
        })
    );
    
  3. DTO Validation: Extend DTOs to add custom validation (e.g., phone number format):

    use Symfony\Component\Validator\Constraints as Assert;
    
    class SendTextMessageData
    {
        #[Assert\NotBlank]
        #[Assert\Regex('/^\+?[0-9]{10,15}$/')]
        public string $recipient;
        // ...
    }
    

Configuration Quirks

  • Base URL Overrides: Override base_url in config if using a custom WasenderAPI endpoint (e.g., staging):
    wasenderapi:
        base_url: 'https://staging.wasenderapi.com/api'
    
  • Environment-Specific Tokens: Use Symfony’s %env() with placeholders for multi-environment setups:
    wasenderapi:
        api_key: '%env(WASENDERAPI_API_KEY_%kernel.environment%)%'
    

Performance Tips

  • Batch Webhook Processing: Use Symfony’s Messenger to process webhooks asynchronously:
    $bus->dispatch(new WasenderWebhookMessage($payload));
    
  • Caching: Cache group/contact metadata if frequently accessed:
    $cache->get('group_metadata_' . $groupJid, function () use ($client, $groupJid) {
        return $client->getGroupMetadata($groupJid);
    });
    
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.
nasirkhan/laravel-sharekit
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony