Skip to main content
Version: Latest

1. Overview

1.1 What WhatsApp Integration Is​

Shumoul.Saas.WhatsAppIntegration is a standalone, narrowly-scoped library that owns everything required to speak to Meta's WhatsApp Cloud API: the HTTP client, webhook signature validation, webhook payload parsing, and the provider-facing DTOs and configuration shapes. It ships as three NuGet packages — Contracts, Abstractions, Core — consumed by Shumoul.Saas.Api via ordinary PackageReference, never ProjectReference (see the platform's Dependency Law in docs/ARCHITECTURE/STANDARDS/).

It is a provider integration library, not a Framework. ADR-001 in the library's own repository formally records this as a deliberate "third module shape" — distinct from both Blueprint shapes the platform's certified Frameworks use (the 6-package data/delivery shape and the 5-package execution/runtime shape). It has no Adapters package and no Persistence package, because it holds no state and needs no host-agnostic adapter layer — every consumer of it is Shumoul.Saas.Api.

1.2 What It Owns​

  • The Meta Cloud API HTTP client (WhatsAppCloudApiClient) — sending text and template messages, retrieving media metadata, downloading media bytes.
  • Webhook signature validation (WhatsAppSignatureValidator) — HMAC-SHA256 over X-Hub-Signature-256.
  • Webhook payload parsing (WhatsAppWebhookParser) — turning Meta's raw JSON into typed WhatsAppWebhookMessageDto/WhatsAppWebhookStatusDto objects.
  • Provider-facing DTOs and configuration (WhatsAppCloudApiOptions and friends).
  • The three public interfaces consumers code against: IWhatsAppService, IWhatsAppWebhookParser, IWhatsAppSignatureValidator.

1.3 What the ERP Owns​

Everything business-shaped stays in Shumoul.Saas.Api:

  • The Inbox/Conversation system — conversations, messages, notes, tags, saved replies, timeline, read state, favorites, agent presence, and the real-time SignalR layer built on top of it.
  • OTP and tenant-activation WhatsApp business messages.
  • The ERP's Communication module — a channel-agnostic send API (Email/WhatsApp/SMS/Push/In-App) with its own tenant-scoped WhatsApp sender.
  • Every controller, permission, route, and the entire Angular/Flutter-facing API surface.
  • Phone number normalization — a Saudi-market business rule that stays in the ERP by design (see §4 Configuration and ADR-001).

1.4 Why It Is Not a Full Framework​

Two alternatives were explicitly considered and rejected during the platform's Phase 0.5 boundary review:

  1. Restructure into a 5-package execution/runtime Framework (matching the Background Jobs Framework's shape) — rejected because no legitimate Adapters package content exists. Both plausible adapter candidates (the ERP's controllers, and the Notification Framework's channel-provider bridge) are Host-tier concerns under the platform's Adapter Standard, not library-tier.
  2. Generalize into a MessagingFramework covering multiple providers — rejected as premature generalization: no second provider exists or is planned, and Meta's WhatsApp Cloud API is specific enough that a generic abstraction would either leak Meta concepts or under-serve them.

The repository name deliberately uses the Integration suffix rather than Framework — a documented, precedent-setting convention for narrow, stateless provider-integration libraries with no persistence or adapter layer of their own.

1.5 Relationship With the Notification Framework​

WhatsApp is one of six channels the platform's Notification Framework can dispatch through, alongside Email, SMS, Push, In-App, and SignalR — and, as of the Phase 2.3 runtime audit, is routed through INotificationChannelProviderResolver exactly like the other five (an earlier belief that it bypassed the resolver via a class called WhatsAppNotificationSender was based on dead code that was never actually wired in — see §18 Architecture Validation). What remains WhatsApp-specific is template resolution: Meta's template model (template name, template language, positional body parameters) doesn't fit the generic channel-provider contract, so the dispatch service reads those fields from AppNotificationTemplate before resolving the provider. The Notification Framework's MetaWhatsAppProvider (ERP-owned) is one of four ERP-side consumers of this library's IWhatsAppService — see §2 Architecture for the complete consumer map.

1.6 Relationship With ERP Communication / Inbox​

Two more ERP subsystems consume this library independently of the Notification Framework:

  • The Communication module (CommunicationController) exposes a generic, channel-agnostic Send/WhatsApp and Send/Document API for tenant-triggered business messages (e.g. sending an invoice by WhatsApp). It uses the tenant's own Meta credentials via TenantWhatsAppSender, which — since the Phase 1 Runtime Consolidation — constructs the same WhatsAppCloudApiClient every other path uses (see §2.4).
  • The Inbox/Conversation system (WhatsAppInboxController and siblings) is the two-way, agent-facing customer-service surface: receiving inbound messages via webhook, replying, assigning, tagging, and tracking SLA metrics. It is the largest single consumer of IWhatsAppService, and the only one that also needs SignalR for real-time agent presence, typing indicators, and inbox updates.

None of these three ERP subsystems know about each other's existence through the library — each holds its own reference to IWhatsAppService via dependency injection, and the library itself has no concept of "tenant," "conversation," "OTP," or "invoice."