chatwoot-develop/.context/planos/wuzapi_implementation_plan.md

2.8 KiB

WuzAPI Native Channel Implementation Plan (V2 - Strict V1 Specs)

Goal

Implement WuzAPI as a native Channel::Whatsapp provider, adhering to strict V1 requirements: text-only, strong deduplication, and encrypted token storage.

User Review Required

[!IMPORTANT] > Schema Change: Adding encrypted_wuzapi_user_token and encrypted_wuzapi_admin_token (plus IVs) to channel_whatsapp to replace insecure JSONB storage.

[!WARNING] > V1 Scope: Only text messages supported. Groups and self-messages are explicitly ignored.

Proposed Changes

Database

[NEW] Migration: Add Encrypted Tokens to Channel Whatsapp

  • Add encrypted_wuzapi_user_token (string)
  • Add encrypted_wuzapi_user_token_iv (string)
  • Add encrypted_wuzapi_admin_token (string)
  • Add encrypted_wuzapi_admin_token_iv (string)
  • Rationale: Avoids storing sensitive tokens in provider_config (JSONB).

Backend (Models)

[MODIFY] app/models/channel/whatsapp.rb

  • Add encrypts :wuzapi_user_token, :wuzapi_admin_token (Rails 7+ encryption).
  • Update validate_provider_config to check these new fields instead of JSONB.

Backend (Services)

[NEW] app/services/whatsapp/providers/wuzapi/payload_parser.rb

  • Implement class to strictly parse WuzAPI payload per contract:
    • external_id <- body.event.Info.ID
    • from_me <- body.event.Info.IsFromMe
    • wa_id <- body.event.Info.Sender (parsed)
    • text <- body.event.Message.conversation
    • timestamp <- body.event.Info.Timestamp

[MODIFY] app/services/whatsapp/incoming_message_wuzapi_service.rb

  • Integrate PayloadParser.
  • Implement Strong Dedupe:
    • Return early if Message.exists?(source_id: external_id, inbox_id: inbox.id).
  • Implement Loop Protection:
    • Return early if from_me is true.

[MODIFY] app/services/whatsapp/providers/wuzapi_service.rb (Outbound)

  • Update to use channel.wuzapi_user_token (decrypted) instead of provider_config.
  • Ensure send_message handles errors gracefully.

Security

  • Token Migration: If any data exists (unlikely in prod yet), migrate from provider_config to encrypted columns.

Verification Plan

Automated Tests

  • Request Spec (spec/requests/webhooks/whatsapp_controller_spec.rb)
    • Verify WuzAPI payload submission creates a message.
    • Verify duplicate payload does NOT create a second message (Idempotency).
    • Verify is_from_me: true is ignored.

Manual Verification

  1. Setup: Create Inbox with WuzAPI, providing Token.
  2. Persistence: Verify Token is stored in encrypted columns (checked via Rails Console).
  3. Inbound: Send "Hello" from WhatsApp. Verify it appears in Chatwoot.
  4. Dedupe: Replay the same webhook JSON. Verify no new message.
  5. Outbound: Reply "World" from Chatwoot. Verify delivery to WhatsApp.