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."