> For the complete documentation index, see [llms.txt](https://klassdocs.gitbook.io/klassapp-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://klassdocs.gitbook.io/klassapp-documentation/docs/dev.md).

# dev

**Archived (historical).** This Docsify tree documents the **old Evolution API** WhatsApp stack and DigitalOcean-era ops. Production today is **Laravel Cloud** + **Meta WhatsApp Cloud API**. Do not follow these pages for current setup.

Current references: [DeepWiki](https://deepwiki.com/KlassApp-Foundation/KlassApp) (architecture) · repo [`README.md`](/klassapp-documentation/readme.md) (Quick Start) · [`docs/README.md`](/klassapp-documentation/docs.md) (docs map). Content below is kept for history until a refresh pass; pages will be rewritten or removed then.

## KlassApp WhatsApp Integration

The WhatsApp layer connects KlassApp to parents and staff via the WhatsApp Business Platform through a self-hosted [Evolution API](https://doc.evolution-api.com/) instance. It handles outbound notifications (grades, fees, attendance), inbound interactive menus, a cost-optimized message queue leveraging Meta's 24-hour service window, and an admin delivery dashboard.

***

### Architecture Overview

```
[WhatsApp User] ↔ Evolution API ↔ [Laravel Webhook / Outbound Service]
                                       ↕
                              WhatsAppService (HTTP transport)
                                       ↕
                           OutboundWhatsAppService (business logic)
                                       ↕
                           MessageDeliveryLog (DB tracking)
                           WhatsAppPendingNotification (queue)

[Admin Browser] → WhatsAppDashboardController → MessageDeliveryLog (read)
[n8n/Typebot]   → WhatsAppController endpoints   → Student data (grades, fees, etc.)
```

* **Evolution API** — self-hosted middleware that bridges WhatsApp's Business API and KlassApp via HTTP webhooks. Manages connection states, QR pairing, and message delivery receipts.
* **WhatsAppService** — low-level HTTP transport. Sends text, template, list, and media messages via Evolution API endpoints. Logs every outbound to `message_delivery_log`.
* **OutboundWhatsAppService** — business logic layer for proactive notifications. Implements the cost-optimized queue pattern: sends immediately if the 24-hour service window is open (free), otherwise queues for later delivery.
* **WhatsAppController** — stateless data API used by n8n/Typebot (or any conversation flow engine). Endpoints resolve users by phone, return grades/fees/attendance, and send interactive menus.
* **WhatsAppDashboardController** — admin-only delivery dashboard showing KPIs, daily volume trends, and flow-type breakdowns.
* **WhatsAppPendingNotification** — database-backed queue for cost-optimized outbound delivery.

***

### Quick Start

1. **Set environment variables** in `.env`:

   ```ini
   EVOLUTION_API_URL=http://localhost:8081
   EVOLUTION_API_KEY=your-evolution-api-key
   WHATSAPP_HMAC_SECRET=your-hmac-secret
   WHATSAPP_BUSINESS_NUMBER=+256793844906
   ```
2. **Run migrations**:

   ```bash
   php artisan migrate
   ```
3. **Configure Evolution API webhooks**:
   * Message webhook → `POST https://your-app.com/api/whatsapp/inbound`
   * Delivery status webhook → `POST https://your-app.com/api/whatsapp/delivery`
   * Both webhooks must include the `apikey` header matching `EVOLUTION_API_KEY`
4. **Add the queue processor to crontab**:

   ```cron
   * * * * * cd /path/to/app && php artisan schedule:run >> /dev/null 2>&1
   ```

   This runs `whatsapp:send-pending --flush-open` every 15 minutes (defined in `Console/Kernel.php`).
5. **Verify inbound** — send any message to the business WhatsApp number. The bot should reply with a menu.
6. **Link an admin phone** — navigate to Admin → Settings → WhatsApp Phone in the admin panel to link a user's WhatsApp number.
7. **Test fee reminders**:

   ```bash
   php artisan whatsapp:send-fee-reminders --dry-run
   ```

   Remove `--dry-run` to send live.

***

### Documentation Index

| Doc                                                                                       | Purpose                                                           | Audience          |
| ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------- |
| [setup.md](/klassapp-documentation/docs/dev/setup.md)                                     | Evolution API deployment, env config, webhook setup               | Ops / Admin       |
| [api-reference.md](/klassapp-documentation/docs/dev/api-reference.md)                     | Webhook payloads, endpoint signatures, response codes             | Developer         |
| [interactive-menu.md](/klassapp-documentation/docs/dev/interactive-menu.md)               | List Message menu, role routing, keyword handling                 | Admin / Developer |
| [cost-optimization.md](/klassapp-documentation/docs/dev/cost-optimization.md)             | 24-hour service window, notification queue, Meta pricing          | Ops / Admin       |
| [admin-dashboard.md](/klassapp-documentation/docs/dev/admin-dashboard.md)                 | Delivery dashboard KPIs, charts, monitoring                       | Admin             |
| [service-layer.md](/klassapp-documentation/docs/dev/service-layer.md)                     | WhatsAppService and OutboundWhatsAppService method reference      | Developer         |
| [emis-lin-onboarding.md](/klassapp-documentation/docs/dev/emis-lin-onboarding.md)         | EMIS/LIN integration, Path 2 CSV import, Path 3 self-registration | Admin             |
| [models.md](/klassapp-documentation/docs/dev/models.md)                                   | Database table schemas and relationships                          | Developer         |
| [testing.md](/klassapp-documentation/docs/dev/testing.md)                                 | PHPUnit test setup, factories, and running                        | Developer         |
| [digitalocean-deployment.md](/klassapp-documentation/docs/dev/digitalocean-deployment.md) | DO $200 credit — 10-school testing environment provisioning       | Ops / Admin       |
| [schoolpay-integration.md](/klassapp-documentation/docs/dev/schoolpay-integration.md)     | SchoolPay API integration spec (payment aggregator)               | Developer         |
| [ai-agent-layer.md](/klassapp-documentation/docs/dev/ai-agent-layer.md)                   | AI Agent Layer spec — marksheet ingestion, analysis, enrichment   | Developer         |

***

### Key Environment Variables

| Variable                   | Default                 | Required | Description                                        |
| -------------------------- | ----------------------- | -------- | -------------------------------------------------- |
| `EVOLUTION_API_URL`        | `http://localhost:8081` | Yes      | Base URL of the self-hosted Evolution API instance |
| `EVOLUTION_API_KEY`        | —                       | Yes      | API key for Evolution API authentication           |
| `EVOLUTION_INSTANCE_NAME`  | `klassapp`              | No       | Evolution API instance name                        |
| `WHATSAPP_HMAC_SECRET`     | —                       | Yes      | Secret key for HMAC-signing webhook payloads       |
| `WHATSAPP_BUSINESS_NUMBER` | `+256793844906`         | Yes      | Business WhatsApp number in E.164 format           |
| `WHATSAPP_BUSINESS_NAME`   | `KlassApp`              | No       | Display name for the business                      |

***

### Related Files

| File                                                         | Purpose                                                                                                                                                                                |
| ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `config/services.php`                                        | WhatsApp configuration (business\_number, business\_name, evolution\_url, evolution\_api\_key, instance\_name, send\_delay, template\_language)                                        |
| `app/Services/WhatsAppService.php`                           | HTTP transport — `sendText()`, `sendList()`, `sendTemplate()`, `sendTextSafe()`, `sendToUser()`, `isWithinServiceWindow()`, `sendMedia()`                                              |
| `app/Services/OutboundWhatsAppService.php`                   | Business logic — `queueOrSend()`, `queueNotification()`, `flushPending()`, `sendExpiredQueue()`, `flushAllOpenWindows()`, notification methods                                         |
| `app/Http/Controllers/Api/WhatsAppController.php`            | API endpoints — `handleInbound()`, `identify()`, `sendMenu()`, `buildMenuSections()`, `attendance()`, `feeBalance()`, `schoolEvents()`, `deliveryWebhook()`, `handleDeliveryFailure()` |
| `app/Http/Controllers/Admin/WhatsAppDashboardController.php` | Admin delivery dashboard with KPI aggregation                                                                                                                                          |
| `app/Http/Requests/WhatsApp/StoreWhatsAppWebhookRequest.php` | Inbound webhook payload validation                                                                                                                                                     |
| `app/Helpers/WhatsAppPhoneHelper.php`                        | Phone normalisation and Uganda (+256) validation                                                                                                                                       |
| `app/Models/WhatsAppUser.php`                                | WhatsApp user phone linking model                                                                                                                                                      |
| `app/Models/MessageDeliveryLog.php`                          | Outbound/inbound message delivery tracking                                                                                                                                             |
| `app/Models/WhatsAppPendingNotification.php`                 | Cost-optimized notification queue model                                                                                                                                                |
| `app/Console/Commands/SendFeeReminders.php`                  | Scheduled fee reminder dispatcher                                                                                                                                                      |
| `app/Console/Commands/SendWhatsAppPendingNotifications.php`  | Queue processor for pending notifications                                                                                                                                              |

***

### Related Configuration

* **`config/services.php`** — WhatsApp settings array: `business_number`, `business_name`, `evolution_url`, `evolution_api_key`, `instance_name`, `send_delay` (1200ms), `template_language` (en)
* **`routes/api.php`** — `Route::prefix('whatsapp')` group: `/inbound` (POST), `/identify-user` (POST), `/student/{id}/grades` (GET), `/student/{id}/attendance` (GET), `/fees/{id}/balance` (GET), `/school/{id}/events` (GET)
* **`routes/admin.php`** — `/whatsapp/phone` (GET + POST), `/whatsapp/dashboard` (GET)
* **`app/Console/Kernel.php`** — Schedule: fee reminders weekly (Mondays) and daily (overdue), pending queue flush every 15 minutes — all with `withoutOverlapping()`


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://klassdocs.gitbook.io/klassapp-documentation/docs/dev.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
