> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hypersender.com/llms.txt
> Use this file to discover all available pages before exploring further.

# WhatsApp Webhook Job

> How to override the default WhatsApp webhook job in Hypersender Laravel SDK.

# Overview

This page explains how Hypersender handles incoming WhatsApp webhooks, the default job that processes them, and how to register your own job class.

## How it works

<Steps>
  <Step title="Route">
    The incoming webhook hits your app on the route configured at `hypersender-config.whatsapp_webhook_route` (default: `whatsapp/webhook`).
  </Step>

  <Step title="Controller">
    `Hypersender\Http\Controllers\WhatsappWebhookController` resolves the job class from config and dispatches it:

    * Config key: `hypersender-config.whatsapp_webhook_job`
    * The controller validates:
      * The class exists and is a string
      * The class implements `Hypersender\Contracts\WhatsappWebhookJobInterface`
    * The controller dispatches the job with two named arguments:
      * `payload: $request->payload()`
      * `secret: $request->secret()`
  </Step>
</Steps>

<Warning>
  Because the controller uses named arguments, your job’s constructor must accept parameters named `payload` and `secret`.
</Warning>

## The default job

Out of the box, the package ships with `Hypersender\Jobs\ProcessWhatsappWebhookJob`, which implements the interface `Hypersender\Contracts\WhatsappWebhookJobInterface`.

### Key details

<Steps>
  <Step title="Constructor signature">
    ```php theme={null}
    public function __construct(
        public array $payload,
        public ?string $secret = null
    ) { }
    ```
  </Step>

  <Step title="Queue routing">
    If `hypersender-config.whatsapp_queue` is set, the job is queued there.
  </Step>

  <Step title="Handling">
    Validates the `event` field and dispatches an application event via `WhatsappWebhookEventEnum` mapping.
  </Step>
</Steps>

## Using your own job class

You can replace the default job with your own implementation. Follow these steps:

<Steps>
  <Step title="Implement the interface">
    Your job must implement `Hypersender\Contracts\WhatsappWebhookJobInterface` (a marker interface). This is enforced by the controller.
  </Step>

  <Step title="Match the constructor names">
    Your job’s constructor must accept the same named parameters that the controller provides:

    ```php theme={null}
    use Hypersender\Contracts\WhatsappWebhookJobInterface;
    use Illuminate\Bus\Queueable;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Foundation\Bus\Dispatchable;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Queue\SerializesModels;

    namespace App\Jobs;

    class MyWhatsappWebhookJob implements ShouldQueue, WhatsappWebhookJobInterface
    {
        use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

        public function __construct(public array $payload, public ?string $secret = null)
        {
            // Optional: route to a specific queue
            if ($queue = config('hypersender-config.whatsapp_queue')) {
                $this->onQueue($queue);
            }
        }

        public function handle(): void
        {
            // Your custom processing logic here
            // $this->payload contains the webhook body
            // $this->secret contains the Authorization secret (if sent)
        }
    }
    ```
  </Step>

  <Step title="Register your job class">
    You can register it either in your config or via environment variable.

    * Via `.env`:

    ```env theme={null}
    HYPERSENDER_WHATSAPP_WEBHOOK_JOB=App\Jobs\MyWhatsappWebhookJob
    ```

    * Or by publishing/editing the config `config/hypersender-config.php`:

    ```php theme={null}
    'whatsapp_webhook_job' => env('HYPERSENDER_WHATSAPP_WEBHOOK_JOB', App\Jobs\MyWhatsappWebhookJob::class),
    ```
  </Step>
</Steps>

<Tip>
  Make sure the class is autoloadable and available to your app (e.g., in `app/Jobs`).
</Tip>

## Can I use my own interface?

Yes! your job class can implement any additional interfaces you want for your own architecture. However, the package still requires your job to implement `Hypersender\\Contracts\\WhatsappWebhookJobInterface` because the controller enforces this at runtime. Swapping out that required interface via configuration is not supported. If you need to enforce your own contract, simply implement both interfaces on your job class.

## Related configuration

* API key: `HYPERSENDER_WHATSAPP_API_KEY`
* Instance ID: `HYPERSENDER_WHATSAPP_INSTANCE_ID`
* Webhook Authorization secret: `HYPERSENDER_WHATSAPP_WEBHOOK_AUTHORIZATION_SECRET`
* Webhook route: `HYPERSENDER_WHATSAPP_WEBHOOK_ROUTE` (defaults to `whatsapp/webhook`)
* Webhook job: `HYPERSENDER_WHATSAPP_WEBHOOK_JOB` (defaults to `Hypersender\Jobs\ProcessWhatsappWebhookJob`)
* Queue name: `HYPERSENDER_WHATSAPP_QUEUE` (defaults to `default`)

## Validation rules enforced by the controller

If the configured job class is invalid, the controller aborts the request with HTTP `500`:

* Not a string or class does not exist
* Does not implement `Hypersender\Contracts\WhatsappWebhookJobInterface`

## Payload expectations

The default job expects an `event` string at `payload['event']`. If it is missing or not a string, the default job will report and fail the job. If you write a custom job, you can apply your own validation.

## Quick checklist

* Custom job implements `Hypersender\Contracts\WhatsappWebhookJobInterface`
* Constructor signature matches the named args: `__construct(array $payload, ?string $secret = null)`
* `HYPERSENDER_WHATSAPP_WEBHOOK_JOB` is set (or config updated)
* Optional: set `HYPERSENDER_WHATSAPP_QUEUE` to route jobs to a specific queue

## Troubleshooting

* 500 error on webhook: Ensure the configured job class exists and implements `WhatsappWebhookJobInterface`.
* Constructor argument mismatch: Because dispatch uses named args, your constructor parameter names must be exactly `payload` and `secret`.
* Queue not used: Verify `HYPERSENDER_WHATSAPP_QUEUE` (or config) and that your job calls `$this->onQueue(...)` in the constructor (or elsewhere) if you want to force a specific queue.

## TL;DR

* Default job: `Hypersender\Jobs\ProcessWhatsappWebhookJob` implements `Hypersender\Contracts\WhatsappWebhookJobInterface` and is used by default.
* Bring your own: Create a job that implements the interface, accepts `payload` and `secret` in the constructor, and register it via `HYPERSENDER_WHATSAPP_WEBHOOK_JOB` or in `config/hypersender-config.php`.
