# Simple WhatsApp Queue - Panduan Penggunaan

## Konfigurasi

### 1. Tambahkan ke `.env`

```env
#==========================================================================
# WHATSAPP QUEUE - SIMPLE CONFIGURATION
#==========================================================================

# Max messages per WABA per minute (default: 60)
WA_QUEUE_MESSAGES_PER_MINUTE=60

# Queue name for message jobs (send-template-ingest, send-template-async)
WA_QUEUE_NAME=whatsapp

# Queue name khusus campaign (terpisah dari send-template-ingest)
WA_QUEUE_CAMPAIGN_NAME=campaign

# Max retries for failed messages
WA_QUEUE_MAX_RETRIES=3

# Job timeout (seconds)
WA_QUEUE_TIMEOUT=60

# Enable logging
WA_QUEUE_LOGGING=true

# Log channel (null = default Laravel channel)
WA_QUEUE_LOG_CHANNEL=
```

### 2. Queue Driver

Pastikan sudah menggunakan database queue:

```env
QUEUE_CONNECTION=database
```

Atau jika menggunakan Redis:

```env
QUEUE_CONNECTION=redis
```

---

## Contoh Penggunaan

### 1. Kirim Satu Pesan Template

```php
use App\Services\Queue\SimpleMessageQueue;
use App\Models\Client;
use App\Models\Template;

$queue = app(SimpleMessageQueue::class);

$client = Client::find(1);
$template = Template::where('template_name', 'hello_world')->first();

$message = $queue->enqueue(
    client: $client,
    template: $template,
    to: '6281234567890',
    bodyParams: ['John Doe'],
    headerParams: [],
    buttonParams: []
);

// $message->id = ID pesan
// $message->scheduled_at = Waktu dijadwalkan
// $message->queue_status = 'pending' atau 'delayed'
```

### 2. Kirim Batch Pesan

```php
use App\Services\Queue\SimpleMessageQueue;
use App\Models\Client;
use App\Models\Template;

$queue = app(SimpleMessageQueue::class);

$client = Client::find(1);
$template = Template::where('template_name', 'promo_broadcast')->first();

$recipients = [
    '6281234567890',
    '6281234567891',
    '6281234567892',
    // ... bisa ratusan nomor
];

$messages = $queue->enqueueBatch(
    client: $client,
    template: $template,
    recipients: $recipients,
    bodyParams: ['Promo Spesial'],
);

// $messages = Collection of Message models
// Pesan akan dijadwalkan otomatis:
// - 60 pesan pertama: langsung
// - 61-120: menit ke-2
// - 121-180: menit ke-3
// dst.
```

### 3. Kirim Pesan Teks (Session)

```php
use App\Services\Queue\SimpleMessageQueue;
use App\Models\Client;
use App\Models\WabaPool;

$queue = app(SimpleMessageQueue::class);

$client = Client::find(1);
$waba = WabaPool::find(1);

$message = $queue->enqueueText(
    client: $client,
    pool: $waba,
    to: '6281234567890',
    text: 'Halo, ada yang bisa dibantu?'
);
```

### 4. Cek Rate Limit Stats

```php
use App\Services\Queue\SimpleWabaRateLimiter;

$rateLimiter = app(SimpleWabaRateLimiter::class);

$stats = $rateLimiter->getStats($wabaPoolId);
// [
//     'waba_pool_id' => 1,
//     'current_minute' => '2026-01-15 12:30',
//     'messages_sent' => 45,
//     'max_per_minute' => 60,
//     'remaining' => 15,
//     'is_at_limit' => false,
// ]
```

### 5. Cek Queue Stats

```php
use App\Services\Queue\SimpleMessageQueue;

$queue = app(SimpleMessageQueue::class);

$stats = $queue->getQueueStats($clientId);
// [
//     'pending' => 10,
//     'sending' => 2,
//     'sent_today' => 150,
//     'failed_today' => 3,
// ]
```

---

## Menjalankan Worker

### Development

```bash
# Semua queue: template-ingest, whatsapp, campaign
php artisan queue:work --queue=template-ingest,whatsapp,campaign
```

### Production (Supervisor)

Queue terpisah: `template-ingest` (api/v1/send-template-ingest), `whatsapp` (kirim pesan), `campaign` (campaign).

```ini
[program:whatsapp-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/app/artisan queue:work --queue=template-ingest,whatsapp,campaign --sleep=3 --tries=3 --timeout=60
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
numprocs=2
redirect_stderr=true
stdout_logfile=/var/log/supervisor/whatsapp-worker.log
stopwaitsecs=3600
```

---

## Flow Diagram

```
┌─────────────────────────────────────────────────────────────────┐
│                    SIMPLE MESSAGE QUEUE FLOW                     │
└─────────────────────────────────────────────────────────────────┘

┌──────────────┐     ┌──────────────────────┐     ┌───────────────┐
│   Request    │────▶│  SimpleMessageQueue  │────▶│    Message    │
│ (Controller) │     │      enqueue()       │     │    (DB)       │
└──────────────┘     └──────────────────────┘     └───────────────┘
                              │                          │
                              ▼                          │
                     ┌──────────────────────┐            │
                     │ SimpleWabaRateLimiter│            │
                     │ calculateScheduledTime│            │
                     └──────────────────────┘            │
                              │                          │
                              ▼                          │
                     ┌──────────────────────┐            │
                     │   Is Quota Full?     │            │
                     └──────────────────────┘            │
                        │              │                 │
                        ▼              ▼                 │
                   ┌────────┐    ┌──────────┐           │
                   │  NO    │    │   YES    │           │
                   │ (now)  │    │ (delay)  │           │
                   └────────┘    └──────────┘           │
                        │              │                 │
                        └──────┬───────┘                 │
                               ▼                         │
                     ┌──────────────────────┐            │
                     │   Dispatch Job       │◀───────────┘
                     │ SimpleWhatsAppJob    │
                     │   delay($scheduledAt)│
                     └──────────────────────┘
                               │
                               ▼
                     ┌──────────────────────┐
                     │   Laravel Queue      │
                     │   (database/redis)   │
                     └──────────────────────┘
                               │
                               ▼
                     ┌──────────────────────┐
                     │   Queue Worker       │
                     │ php artisan queue:work│
                     └──────────────────────┘
                               │
                               ▼
                     ┌──────────────────────┐     ┌───────────────┐
                     │ SimpleWhatsAppJob    │────▶│ Rate Limit    │
                     │      handle()        │     │    Check      │
                     └──────────────────────┘     └───────────────┘
                               │                        │
                               │         ┌──────────────┤
                               │         ▼              ▼
                               │    ┌────────┐    ┌──────────┐
                               │    │ Allowed│    │ Blocked  │
                               │    └────────┘    └──────────┘
                               │         │              │
                               │         ▼              ▼
                               │    ┌────────┐    ┌──────────┐
                               │    │  Send  │    │  Delay   │
                               │    └────────┘    │ to next  │
                               │         │        │  minute  │
                               │         ▼        └──────────┘
                               │    ┌────────────────────┐
                               │    │   Meta Graph API   │
                               │    │   sendRawPayload() │
                               │    └────────────────────┘
                               │              │
                               │              ▼
                               │    ┌────────────────────┐
                               │    │   Update Message   │
                               │    │   status = sent    │
                               │    └────────────────────┘
                               │              │
                               │              ▼
                               │    ┌────────────────────┐
                               │    │   Charge Client    │
                               │    │   (BillingService) │
                               │    └────────────────────┘
                               │
                               ▼
                          ┌────────┐
                          │  DONE  │
                          └────────┘
```

---

## Rate Limit Logic

```
Contoh: WABA ID 1, Max 60 pesan/menit

Menit 1 (12:00):
├── Pesan 1-60  → scheduled_at: 12:00:xx (langsung)
└── Pesan 61-70 → scheduled_at: 12:01:00 (delay ke menit berikutnya)

Menit 2 (12:01):
├── Pesan 61-120 → scheduled_at: 12:01:xx
└── Pesan 121+   → scheduled_at: 12:02:00

Worker memproses:
1. Ambil job dari queue
2. Cek rate limit: apakah WABA masih punya quota di menit ini?
   - YA → kirim langsung
   - TIDAK → release job dengan delay ke menit berikutnya
3. Kirim ke Meta API
4. Update status message
5. Charge billing
```

---

## Perbedaan dengan Sistem Lama

| Fitur | Lama (Kompleks) | Baru (Simple) |
|-------|-----------------|---------------|
| Base Delay | 10-25 detik random | ❌ Tidak ada |
| Batch Penalty | +10s per 50 pesan | ❌ Tidak ada |
| Quality Penalty | Adaptive delay | ❌ Tidak ada |
| Jitter | Random delay | ❌ Tidak ada |
| Anti-Spam | Content hash, duplicate check | ❌ Tidak ada |
| Rate Limit | Per WABA + Client + Agent | ✅ 60/menit/WABA |
| Logic | Kompleks | ✅ Sederhana |

---

## Logging

Setiap operasi di-log:

```log
[2026-01-15 12:00:00] local.INFO: WabaRateLimiter: Enqueue {
    "message_id": 123,
    "waba_pool_id": 1,
    "recipient": "6281234567890",
    "scheduled_at": "2026-01-15T12:00:00+07:00",
    "status": "pending",
    "delay_seconds": 0
}

[2026-01-15 12:00:01] local.INFO: WabaRateLimiter: Check {
    "message_id": 123,
    "waba_pool_id": 1,
    "recipient": "6281234567890",
    "allowed": true,
    "current_count": 45,
    "max_per_minute": 60,
    "remaining": 15
}

[2026-01-15 12:00:02] local.INFO: WabaRateLimiter: Sent {
    "message_id": 123,
    "waba_pool_id": 1,
    "recipient": "6281234567890",
    "meta_message_id": "wamid.xxx",
    "status": "sent"
}
```

---

## Troubleshooting

### Pesan tidak terkirim

1. Cek worker berjalan:
```bash
php artisan queue:work --queue=whatsapp --verbose
```

2. Cek job di database:
```sql
SELECT * FROM jobs WHERE queue = 'whatsapp' ORDER BY id DESC LIMIT 10;
```

3. Cek failed jobs:
```sql
SELECT * FROM failed_jobs ORDER BY failed_at DESC LIMIT 10;
```

### Rate limit terlalu ketat

Ubah di `.env`:
```env
WA_QUEUE_MESSAGES_PER_MINUTE=100
```

### Pesan delay terlalu lama

Rate limit 60/menit berarti:
- 100 pesan = ~2 menit
- 500 pesan = ~9 menit
- 1000 pesan = ~17 menit

Jika perlu lebih cepat, tingkatkan `WA_QUEUE_MESSAGES_PER_MINUTE`.
