Send Contracts via WhatsApp with DoAide Contract Generator
Problem
Indian SMB owners, freelancers, and startups often need to share newly generated contracts—NDAs, employment contracts, service agreements—quickly with clients or partners. Sending a PDF by email or uploading it to a cloud folder adds friction and delays the signing process. This is where contract generator pays off in practice.
How the Feature Works
DoAide Contracts adds a single‑click WhatsApp share button after a contract is generated. The flow is:
- Generate: The user selects a template (e.g., employment contract template) and fills in the form.
- Store: FastAPI saves the contract as a PDF blob in PostgreSQL and returns a contract ID.
- Share: The React UI renders a Share via WhatsApp button. When clicked, it calls a FastAPI endpoint that streams the PDF to the WhatsApp Business API.
- Confirm: A toast informs the user that the contract was sent.
The user never leaves the site; the contract is delivered instantly to the chosen WhatsApp contact. Getting contract generator right early saves rework later.
Frontend Implementation
The share button lives in components/ShareWhatsAppButton.jsx:
import { useState } from "react"; export default function ShareWhatsAppButton({ contractId, recipient }) { const [sending, setSending] = useState(false); const send = async () => { setSending(true); try { const res = await fetch(`/api/contract/${contractId}/send-whatsapp`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ phone: recipient }), }); if (!res.ok) throw new Error("Send failed"); alert("Contract sent to WhatsApp"); } catch (e) { alert("Could not send contract"); } finally { setSending(false); } }; return ( <button onClick={send} disabled={sending} className="btn-whatsapp"> {sending ? "Sending…" : "Share via WhatsApp"} </button> ); } The component uses a simple POST request; the button is styled with the teal theme introduced in the latest branding update.
Backend Implementation
FastAPI exposes the endpoint in api/contract.py:
from fastapi import APIRouter, HTTPException from sqlalchemy.orm import Session from .models import Contract from .whatsapp import send_pdf_via_whatsapp router = APIRouter() @router.post("/contract/{contract_id}/send-whatsapp") async def send_whatsapp(contract_id: int, payload: dict, db: Session): contract = db.query(Contract).filter(Contract.id == contract_id).first() if not contract: raise HTTPException(status_code=404, detail="Contract not found") phone = payload.get("phone") if not phone: raise HTTPException(status_code=400, detail="Phone number required") # contract.pdf is a byte array stored in PostgreSQL success = await send_pdf_via_whatsapp(phone, contract.pdf, contract.title) if not success: raise HTTPException(status_code=500, detail="WhatsApp send failed") return {"status": "sent"} The helper send_pdf_via_whatsapp wraps the Twilio WhatsApp API:
import aiohttp async def send_pdf_via_whatsapp(to: str, pdf_bytes: bytes, title: str) -> bool: url = "https://api.twilio.com/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Messages.json" data = { "From": "whatsapp:+14155238886", "To": f"whatsapp:{to}", "Body": f"Here is your {title}.", } files = {"MediaUrl": ("contract.pdf", pdf_bytes, "application/pdf")} auth = aiohttp.BasicAuth("ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "your_auth_token") async with aiohttp.ClientSession(auth=auth) as session: async with session.post(url, data=data, files=files) as resp: return resp.status == 201 The PDF is streamed directly; no temporary file is written to disk. Good contract generator keeps the rest of the workflow predictable.
UX Considerations
- The Share via WhatsApp button appears only after the contract is ready, keeping the interface clean.
- The button uses a 48 px touch target, satisfying the mobile improvements commit.
- On success, the toast uses the Inter font, aligning with the unified DoAide branding.
Benefits for Indian SMBs
- Instant delivery: No email attachments, no manual uploads.
- Higher conversion: Clients receive the contract in their primary messaging app.
- Compliance: The contract remains a single PDF file, preserving formatting for legal review.
Conclusion
By integrating WhatsApp sharing into the contract generation workflow, DoAide Contracts removes a common bottleneck for Indian SMB owners. The implementation demonstrates how a lightweight FastAPI endpoint and a React button can leverage an external API to deliver a seamless user experience.
Further Reading
- The project’s blog now contains a post on WhatsApp contract sharing.
- The new SEO‑friendly blog posts include structured data for better discoverability.
Code Repository
All changes are available in the latest commit on GitHub: https://github.com/r2st/DoAide-Contracts/commit/9778d074b8bea1329eaed78e12438e9b496de2ed