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
Top comments (0)