Skip to main content
Version: Latest

3. Packages

Repository: Shumoul.Saas.WhatsAppIntegration · Current version: 1.0.1 (all three packages move together as a group, per the platform's versioning policy) · Target framework: net9.0

3.1 Shumoul.WhatsAppIntegration.Contracts

Data-only package: DTOs and configuration shapes, no logic beyond simple property defaults.

TypePurpose
WhatsAppCloudApiOptionsMeta Cloud API + webhook configuration, bound from the WhatsAppCloudApi config section
WhatsAppTextMessageRequestDto / WhatsAppTextMessageResponseDtoOutbound free-text send request/result
WhatsAppTemplateMessageRequestDto / WhatsAppTemplateMessageResponseDtoOutbound template send request/result
WhatsAppTemplateComponentDto / WhatsAppTemplateComponentParameterDtoOne component/parameter of a template message
WhatsAppWebhookMessageDtoOne parsed inbound message from a webhook
WhatsAppWebhookStatusDtoOne parsed delivery/read status update from a webhook
WhatsAppWebhookParseResultAggregate parser result (InboundMessages + StatusUpdates)
WhatsAppMediaMetaDtoInternal-use-only raw media metadata from the Graph API media endpoint — never returned directly to API clients

Allowed: plain data classes, primitive-typed properties, safe defaults. Forbidden: any HTTP logic, any reference to Abstractions or Core, any ERP/tenant concept.

3.2 Shumoul.WhatsAppIntegration.Abstractions

The three public interfaces every consumer codes against:

public interface IWhatsAppService
{
Task<WhatsAppTextMessageResponseDto> SendTextAsync(WhatsAppTextMessageRequestDto request, CancellationToken ct = default);
Task<WhatsAppTemplateMessageResponseDto> SendTemplateAsync(WhatsAppTemplateMessageRequestDto request, CancellationToken ct = default);
Task<WhatsAppMediaMetaDto> GetMediaMetaAsync(string mediaId, CancellationToken ct = default);
Task<(bool Success, byte[] Data, string MimeType, string ErrorMessage)> DownloadMediaBytesAsync(string mediaId, CancellationToken ct = default);
}

public interface IWhatsAppWebhookParser
{
Task<WhatsAppWebhookParseResult> ParseAsync(string rawPayload, CancellationToken ct = default);
}

public interface IWhatsAppSignatureValidator
{
WhatsAppSignatureValidationResult Validate(byte[] body, string signatureHeader);
}

WhatsAppSignatureValidationResult is a readonly struct (IsValid, Reason) — allocation-free by design for a check that runs on every inbound webhook.

Note: IWhatsAppService has no SendMediaAsync method — media support is receive/download-only (GetMediaMetaAsync, DownloadMediaBytesAsync). Outbound media is sent as a URL reference inside a template component (ImageUrl/DocumentUrl/VideoUrl on WhatsAppTemplateComponentParameterDto), not as an uploaded binary — see §9 Templates.

Allowed: interface definitions, the one readonly struct result type. Forbidden: any implementation logic — that belongs exclusively in Core.

3.3 Shumoul.WhatsAppIntegration.Core

The only package with implementation logic and the only package that talks to the network.

TypePurpose
WhatsAppCloudApiClientIWhatsAppService implementation — all outbound Meta Graph API HTTP calls
WhatsAppSignatureValidatorIWhatsAppSignatureValidator implementation — HMAC-SHA256 constant-time compare via CryptographicOperations.FixedTimeEquals
WhatsAppWebhookParserIWhatsAppWebhookParser implementation — parses Meta's entry[].changes[] webhook shape
WhatsAppIntegrationServiceCollectionExtensionsAddWhatsAppIntegration(IServiceCollection, IConfiguration) — registers all three services + a named HttpClient("WhatsAppCloudApi")

Allowed: HTTP client logic, JSON parsing, cryptographic signature checks, IHttpClientFactory usage. Forbidden: any persistence, any tenant-awareness, any dependency on the ERP's assemblies (enforced simply by this being a separate repository with its own solution — there is no ERP project reference to violate).

3.4 Tests

Tests/ — xUnit, 29 test cases across 4 files:

FileCasesCovers
WhatsAppWebhookParserTests.cs9Text/media/status message parsing, ProfileName regression coverage
WhatsAppSignatureValidatorTests.cs7Valid/invalid/missing/malformed signature headers
WhatsAppCloudApiClientRequestConstructionTests.cs8Text/template send HTTP request shape
WhatsAppCloudApiClientMediaTests.cs5Media metadata lookup and binary download

See §12 Testing for full coverage detail.

3.5 Allowed and Forbidden Responsibilities — Summary

AllowedForbidden
Any package in this repoMeta Cloud API concepts, DTOs, HTTP, cryptographyTenant IDs, database access, ERP business rules, phone-number business logic
This repo as a wholeGrowing new Meta-specific capabilities (e.g. new message types Meta adds)Growing an Adapters or Persistence package, becoming a MessagingFramework, absorbing Inbox/Conversation/Communication code from the ERP