diff --git a/src/app/(app)/whatsapp-cloud-pilot/page.tsx b/src/app/(app)/whatsapp-cloud-pilot/page.tsx new file mode 100644 index 0000000..9ad87bb --- /dev/null +++ b/src/app/(app)/whatsapp-cloud-pilot/page.tsx @@ -0,0 +1,155 @@ +"use client"; + +import { Loader2, Send, ListChecks } from "lucide-react"; +import { useState } from "react"; +import { toast } from "sonner"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { Textarea } from "@/components/ui/textarea"; + +interface CloudMessageTemplate { + id: string; + name: string; + status: string; + category: string; + language: string; +} + +/** + * PUL-16 pilot: a minimal, real exercise of the Meta WhatsApp Cloud API, + * against the temporary test business number from the App Dashboard's own + * API Setup page — not the merchant-facing send path (that's PUL-18) and + * not reachable from the main sidebar nav. Exists so App Review's + * screencast requirement has a genuine, working flow to record: a real + * send via whatsapp_business_messaging, and a real template list via + * whatsapp_business_management. + */ +export default function WhatsAppCloudPilotPage() { + const [mode, setMode] = useState<"template" | "text">("template"); + const [to, setTo] = useState(""); + const [message, setMessage] = useState("Hello from the PulseCommerce Cloud API pilot."); + const [sending, setSending] = useState(false); + + const [templates, setTemplates] = useState(null); + const [loadingTemplates, setLoadingTemplates] = useState(false); + + const sendTest = async () => { + setSending(true); + try { + const res = await fetch("/api/whatsapp-cloud/test-send", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ to, message, mode }), + }); + const body = await res.json(); + if (!res.ok) { + toast.error(body.error ?? "The send failed."); + return; + } + toast.success(`Sent (${body.mode}) — message id ${body.messageId}`); + } finally { + setSending(false); + } + }; + + const loadTemplates = async () => { + setLoadingTemplates(true); + try { + const res = await fetch("/api/whatsapp-cloud/templates", { cache: "no-store" }); + const body = await res.json(); + if (!res.ok) { + toast.error(body.error ?? "Could not list templates."); + return; + } + setTemplates(body.templates); + } finally { + setLoadingTemplates(false); + } + }; + + return ( +
+ + + + Send a test message + + + Uses whatsapp_business_messaging against Meta's test business number. The + recipient must be one of the up to 5 numbers verified as a test recipient in the App + Dashboard. + + + + setMode(v as "template" | "text")}> + + Template (reliable) + Free-form text + + + {mode === "text" && ( +

+ Only delivers if the recipient has messaged this business number first, opening a + 24h window — otherwise Meta accepts the call and returns a message id, but the + message is never actually delivered. +

+ )} + + setTo(e.target.value)} + /> + {mode === "text" && ( +