# خطة تنفيذ Evolution API مع الحفاظ على الـ API الرسمي

## معلومات المشروع

- **الهدف:** إضافة Evolution API كـ Provider ثاني بجانب الـ API الرسمي الموجود
- **الشرط الأساسي:** عدم المساس بأي كود موجود
- **النتيجة:** تبديل بين الاثنين بتغيير سطر واحد في `.env`

-----

## المرحلة الأولى: تجهيز VPS على Liquid Web

### 1.1 متطلبات السيرفر

```
- Ubuntu 22.04 LTS
- RAM: 2 GB minimum
- Storage: 40 GB minimum
- Port مفتوح: 8080
```

### 1.2 تثبيت Docker

```bash
# تحديث الحزم
sudo apt update && sudo apt upgrade -y

# تثبيت Docker
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER

# تثبيت Docker Compose
sudo apt install docker-compose-plugin -y

# التحقق من التثبيت
docker --version
docker compose version
```

### 1.3 تثبيت Evolution API

```bash
# إنشاء مجلد المشروع
mkdir -p /opt/evolution-api && cd /opt/evolution-api

# تحميل الملفات
git clone https://github.com/EvolutionAPI/evolution-api .

# نسخ ملف الإعداد
cp .env.example .env
```

### 1.4 إعداد ملف .env الخاص بـ Evolution

```env
# السيرفر
SERVER_URL=https://YOUR_VPS_IP:8080
SERVER_PORT=8080

# الأمان
AUTHENTICATION_TYPE=apikey
AUTHENTICATION_API_KEY=YOUR_STRONG_SECRET_KEY_HERE

# قاعدة البيانات (MySQL الموجودة على VPS)
DATABASE_PROVIDER=mysql
DATABASE_CONNECTION_URI=mysql://evolution_user:evolution_pass@localhost:3306/evolution_db

# الواتساب
WA_BUSINESS_ID=
QRCODE_LIMIT=30
```

### 1.5 تشغيل Evolution API

```bash
# تشغيل الكونتينر
docker compose up -d

# التحقق من التشغيل
docker compose logs -f

# الوصول للواجهة
# http://YOUR_VPS_IP:8080/manager
```

### 1.6 ربط الرقم بـ QR

```bash
# إنشاء Instance جديد عبر API
curl -X POST http://YOUR_VPS_IP:8080/instance/create \
  -H "apikey: YOUR_STRONG_SECRET_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "instanceName": "main",
    "qrcode": true
  }'

# الرد هيجيب QR code امسحه من واتساب
```

-----

## المرحلة الثانية: تعديل Laravel (بدون المساس بالكود القديم)

### 2.1 إضافة متغيرات البيئة في .env

```env
# ==============================
# WhatsApp Provider Settings
# ==============================

# غير القيمة دي لتبديل بين الاثنين: 'official' أو 'evolution'
WHATSAPP_PROVIDER=official

# --- Official API (الموجود حالياً) ---
WHATSAPP_OFFICIAL_TOKEN=your_existing_token
WHATSAPP_OFFICIAL_PHONE_ID=your_existing_phone_id

# --- Evolution API (الجديد) ---
EVOLUTION_URL=http://YOUR_VPS_IP:8080
EVOLUTION_API_KEY=YOUR_STRONG_SECRET_KEY_HERE
EVOLUTION_INSTANCE=main
```

### 2.2 إنشاء ملف Config جديد

```bash
touch config/whatsapp.php
```

```php
<?php
// config/whatsapp.php

return [

    /*
    |--------------------------------------------------------------------------
    | WhatsApp Provider
    |--------------------------------------------------------------------------
    | 'official' => Meta Cloud API (الرقم الجديد)
    | 'evolution' => Evolution API (رقمك الحالي)
    */
    'provider' => env('WHATSAPP_PROVIDER', 'official'),

    /*
    |--------------------------------------------------------------------------
    | Official API Settings (الموجود حالياً - لا تعدل هنا)
    |--------------------------------------------------------------------------
    */
    'official' => [
        'token'    => env('WHATSAPP_OFFICIAL_TOKEN'),
        'phone_id' => env('WHATSAPP_OFFICIAL_PHONE_ID'),
        'base_url' => 'https://graph.facebook.com/v18.0',
    ],

    /*
    |--------------------------------------------------------------------------
    | Evolution API Settings (الجديد)
    |--------------------------------------------------------------------------
    */
    'evolution' => [
        'url'      => env('EVOLUTION_URL'),
        'api_key'  => env('EVOLUTION_API_KEY'),
        'instance' => env('EVOLUTION_INSTANCE', 'main'),
    ],

];
```

### 2.3 إنشاء WhatsApp Service الموحد

```bash
mkdir -p app/Services/WhatsApp
touch app/Services/WhatsApp/WhatsAppService.php
touch app/Services/WhatsApp/OfficialProvider.php
touch app/Services/WhatsApp/EvolutionProvider.php
touch app/Services/WhatsApp/WhatsAppProviderInterface.php
```

**Interface:**

```php
<?php
// app/Services/WhatsApp/WhatsAppProviderInterface.php

namespace App\Services\WhatsApp;

interface WhatsAppProviderInterface
{
    public function sendMessage(string $phone, string $message): array;
    public function sendTemplate(string $phone, string $template, array $params = []): array;
    public function parseWebhook(array $data): array;
}
```

**Official Provider (كودك الموجود مغلف هنا):**

```php
<?php
// app/Services/WhatsApp/OfficialProvider.php

namespace App\Services\WhatsApp;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class OfficialProvider implements WhatsAppProviderInterface
{
    private string $token;
    private string $phoneId;
    private string $baseUrl;

    public function __construct()
    {
        $this->token   = config('whatsapp.official.token');
        $this->phoneId = config('whatsapp.official.phone_id');
        $this->baseUrl = config('whatsapp.official.base_url');
    }

    public function sendMessage(string $phone, string $message): array
    {
        // ضع هنا كودك الموجود حالياً للإرسال
        $response = Http::withToken($this->token)
            ->post("{$this->baseUrl}/{$this->phoneId}/messages", [
                'messaging_product' => 'whatsapp',
                'to'                => $phone,
                'type'              => 'text',
                'text'              => ['body' => $message],
            ]);

        Log::info('WhatsApp Official Send', ['phone' => $phone, 'status' => $response->status()]);

        return $response->json();
    }

    public function sendTemplate(string $phone, string $template, array $params = []): array
    {
        // ضع هنا كود التمبليت الموجود حالياً
        $response = Http::withToken($this->token)
            ->post("{$this->baseUrl}/{$this->phoneId}/messages", [
                'messaging_product' => 'whatsapp',
                'to'                => $phone,
                'type'              => 'template',
                'template'          => [
                    'name'       => $template,
                    'language'   => ['code' => 'ar'],
                    'components' => $params,
                ],
            ]);

        return $response->json();
    }

    public function parseWebhook(array $data): array
    {
        // ضع هنا كود parse الـ webhook الموجود حالياً
        $entry   = $data['entry'][0] ?? [];
        $changes = $entry['changes'][0] ?? [];
        $value   = $changes['value'] ?? [];
        $message = $value['messages'][0] ?? [];

        return [
            'phone'    => $message['from'] ?? '',
            'message'  => $message['text']['body'] ?? '',
            'provider' => 'official',
        ];
    }
}
```

**Evolution Provider (الجديد):**

```php
<?php
// app/Services/WhatsApp/EvolutionProvider.php

namespace App\Services\WhatsApp;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class EvolutionProvider implements WhatsAppProviderInterface
{
    private string $url;
    private string $apiKey;
    private string $instance;

    public function __construct()
    {
        $this->url      = config('whatsapp.evolution.url');
        $this->apiKey   = config('whatsapp.evolution.api_key');
        $this->instance = config('whatsapp.evolution.instance');
    }

    public function sendMessage(string $phone, string $message): array
    {
        $response = Http::withHeaders([
            'apikey'       => $this->apiKey,
            'Content-Type' => 'application/json',
        ])->post("{$this->url}/message/sendText/{$this->instance}", [
            'number'  => $phone,
            'text'    => $message,
        ]);

        Log::info('WhatsApp Evolution Send', ['phone' => $phone, 'status' => $response->status()]);

        return $response->json();
    }

    public function sendTemplate(string $phone, string $template, array $params = []): array
    {
        // Evolution مش بيدعم Templates رسمية، بنبعت رسالة نصية عادية
        return $this->sendMessage($phone, $template);
    }

    public function parseWebhook(array $data): array
    {
        return [
            'phone'    => $data['data']['key']['remoteJid'] ?? '',
            'message'  => $data['data']['message']['conversation']
                       ?? $data['data']['message']['extendedTextMessage']['text']
                       ?? '',
            'provider' => 'evolution',
        ];
    }
}
```

**WhatsApp Service الرئيسي:**

```php
<?php
// app/Services/WhatsApp/WhatsAppService.php

namespace App\Services\WhatsApp;

class WhatsAppService
{
    private WhatsAppProviderInterface $provider;

    public function __construct()
    {
        $this->provider = match(config('whatsapp.provider')) {
            'evolution' => new EvolutionProvider(),
            default     => new OfficialProvider(),
        };
    }

    public function sendMessage(string $phone, string $message): array
    {
        return $this->provider->sendMessage($phone, $message);
    }

    public function sendTemplate(string $phone, string $template, array $params = []): array
    {
        return $this->provider->sendTemplate($phone, $template, $params);
    }

    public function parseWebhook(array $data): array
    {
        return $this->provider->parseWebhook($data);
    }
}
```

### 2.4 تسجيل الـ Service في Service Provider

```php
// app/Providers/AppServiceProvider.php
// أضف داخل دالة register()

use App\Services\WhatsApp\WhatsAppService;

public function register(): void
{
    $this->app->singleton(WhatsAppService::class, function () {
        return new WhatsAppService();
    });
}
```

-----

## المرحلة الثالثة: الـ Webhook

### 3.1 إضافة Routes

```php
// routes/api.php

// Webhook للـ Official API (الموجود - لا تعدل)
Route::get('/webhook/whatsapp/official', [WebhookController::class, 'verify']);
Route::post('/webhook/whatsapp/official', [WebhookController::class, 'handleOfficial']);

// Webhook للـ Evolution API (الجديد)
Route::post('/webhook/whatsapp/evolution', [WebhookController::class, 'handleEvolution']);
```

### 3.2 تعديل WebhookController

```php
<?php
// app/Http/Controllers/WebhookController.php

namespace App\Http\Controllers;

use App\Services\WhatsApp\WhatsAppService;
use Illuminate\Http\Request;

class WebhookController extends Controller
{
    public function __construct(private WhatsAppService $whatsApp) {}

    // ============================
    // Official API Webhook (موجود - لا تعدل)
    // ============================
    public function verify(Request $request)
    {
        // كود الـ verification الموجود حالياً
        $mode      = $request->query('hub_mode');
        $token     = $request->query('hub_verify_token');
        $challenge = $request->query('hub_challenge');

        if ($mode === 'subscribe' && $token === env('WHATSAPP_VERIFY_TOKEN')) {
            return response($challenge, 200);
        }

        return response('Forbidden', 403);
    }

    public function handleOfficial(Request $request)
    {
        // كود معالجة الـ webhook الموجود حالياً
        $parsed = $this->whatsApp->parseWebhook($request->all());
        $this->distributeToEmployee($parsed);
        return response()->json(['status' => 'ok']);
    }

    // ============================
    // Evolution API Webhook (جديد)
    // ============================
    public function handleEvolution(Request $request)
    {
        // Evolution بيبعت event نوعه MESSAGE_RECEIVED
        if ($request->input('event') !== 'messages.upsert') {
            return response()->json(['status' => 'ignored']);
        }

        // مش رسالة جاية من الشركة نفسها
        if ($request->input('data.key.fromMe') === true) {
            return response()->json(['status' => 'ignored']);
        }

        $parsed = $this->whatsApp->parseWebhook($request->all());
        $this->distributeToEmployee($parsed);

        return response()->json(['status' => 'ok']);
    }

    // ============================
    // منطق التوزيع (الموجود حالياً)
    // ============================
    private function distributeToEmployee(array $data): void
    {
        // كودك الموجود حالياً للتوزيع على الموظفين
        // ما في أي تغيير هنا
    }
}
```

### 3.3 إعداد Webhook في Evolution

```bash
# بعد تشغيل Evolution، اضبط الـ webhook عبر API

curl -X POST http://YOUR_VPS_IP:8080/webhook/set/main \
  -H "apikey: YOUR_STRONG_SECRET_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://YOUR_LARAVEL_APP/api/webhook/whatsapp/evolution",
    "webhook_by_events": false,
    "webhook_base64": false,
    "events": [
      "MESSAGES_UPSERT"
    ]
  }'
```

-----

## المرحلة الرابعة: الاستخدام في الكود

### في أي مكان في التطبيق:

```php
// مثال في أي Controller

use App\Services\WhatsApp\WhatsAppService;

class NotificationController extends Controller
{
    public function __construct(private WhatsAppService $whatsApp) {}

    public function sendToClient(Request $request)
    {
        // نفس الكود بيشتغل مع الاثنين تلقائياً
        $result = $this->whatsApp->sendMessage(
            phone: '966512345678',
            message: 'مرحباً، تم استلام طلبك'
        );

        return response()->json($result);
    }
}
```

-----

## المرحلة الخامسة: Nginx على VPS (لو محتاج HTTPS)

```nginx
# /etc/nginx/sites-available/evolution

server {
    listen 80;
    server_name YOUR_VPS_IP;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
```

```bash
# تفعيل الـ config
sudo ln -s /etc/nginx/sites-available/evolution /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

# SSL مجاني
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d YOUR_DOMAIN
```

-----

## ملخص التبديل بين الاثنين

```env
# لاستخدام الـ API الرسمي (رقم جديد)
WHATSAPP_PROVIDER=official

# لاستخدام Evolution (رقمك الحالي)
WHATSAPP_PROVIDER=evolution
```

ثم:

```bash
php artisan config:clear
php artisan cache:clear
```

-----

## Checklist التنفيذ

### VPS

- [ ] Docker مثبت
- [ ] Evolution API شغال على port 8080
- [ ] QR Code متمسوح من واتساب
- [ ] Webhook URL مسجل في Evolution

### Laravel

- [ ] `config/whatsapp.php` متعمل
- [ ] `.env` متعمل فيه المتغيرات الجديدة
- [ ] `WhatsAppProviderInterface.php` متعمل
- [ ] `OfficialProvider.php` متعمل (كودك القديم مغلف فيه)
- [ ] `EvolutionProvider.php` متعمل
- [ ] `WhatsAppService.php` متعمل
- [ ] `AppServiceProvider` متعدل
- [ ] Route جديد للـ Evolution webhook متضاف
- [ ] `WebhookController` متعدل

### اختبار

- [ ] ارسل رسالة تجريبية عبر Evolution API
- [ ] تأكد إن الـ webhook بيوصل لـ Laravel
- [ ] تأكد إن التوزيع على الموظفين شغال
- [ ] جرب التبديل لـ Official وتأكد إن كل حاجة شغالة

-----

## ملاحظات مهمة

1. **لا تحذف أي كود قديم** - الـ OfficialProvider بيغلف كودك الموجود بدون تعديل
1. **الـ Webhook URLs الاتنين شغالين** - مش هيتعارضوا
1. **قاعدة البيانات** - Evolution محتاج database منفصلة أو schema منفصل
1. **الـ QR** - لو السيرفر اتوقف هتحتاج تعمل scan تاني، استخدم `keep_alive` في الإعداد
1. **الخطر** - Evolution غير رسمي، متبعتش رسائل bulk كتير في وقت قصير