diff --git a/app/api/sendSMS/route.ts b/app/api/sendSMS/route.ts new file mode 100644 index 0000000..83cf4e2 --- /dev/null +++ b/app/api/sendSMS/route.ts @@ -0,0 +1,115 @@ +import { NextRequest, NextResponse } from "next/server"; +import { SMSService } from "@/lib/sms-service"; +import { SMSRequest, SMSResponse } from "@/lib/types/sms"; + +export async function POST(request: NextRequest) { + try { + // Parse request body + const body: SMSRequest = await request.json(); + + // Validate required fields + if (!body.to || !body.message) { + return NextResponse.json( + { + success: false, + message: "Missing required fields: 'to' and 'message' are required", + } satisfies SMSResponse, + { status: 400 } + ); + } + + // Initialize SMS service + const smsService = new SMSService(); + + // Validate phone numbers + const recipients = Array.isArray(body.to) ? body.to : [body.to]; + for (const phone of recipients) { + if (!smsService.validatePhoneNumber(phone)) { + return NextResponse.json( + { + success: false, + message: `Invalid phone number format: ${phone}. Use international format (+1234567890)`, + } satisfies SMSResponse, + { status: 400 } + ); + } + } + + // Validate message + if (!smsService.validateMessage(body.message)) { + return NextResponse.json( + { + success: false, + message: "Invalid message: must be between 1 and 1600 characters", + } satisfies SMSResponse, + { status: 400 } + ); + } + + // Send SMS + const result = await smsService.sendSMS(body.to, body.message, body.from); + + // Return success response + return NextResponse.json( + { + success: true, + message: "SMS sent successfully", + data: { + messageId: result.data?.message_id, + status: result.data?.status, + recipients: result.data?.recipients, + cost: result.data?.cost, + }, + } satisfies SMSResponse, + { status: 200 } + ); + + } catch (error) { + console.error("SMS API error:", error); + + // Handle specific error cases + if (error instanceof Error && error.message.includes("MBOA_SMS_API_KEY")) { + return NextResponse.json( + { + success: false, + message: "SMS service not configured", + error: "Missing API configuration", + } satisfies SMSResponse, + { status: 500 } + ); + } + + return NextResponse.json( + { + success: false, + message: "Failed to send SMS", + error: error instanceof Error ? error.message : "Unknown error", + } satisfies SMSResponse, + { status: 500 } + ); + } +} + +// Handle GET requests - return API documentation +export async function GET() { + return NextResponse.json( + { + message: "SMS API Endpoint", + method: "POST", + endpoint: "/api/sendSMS", + requiredFields: { + to: "string | string[] - Phone number(s) in international format (+1234567890)", + message: "string - SMS content (1-1600 characters)", + }, + optionalFields: { + from: "string - Sender ID (if supported by provider)", + }, + example: { + to: "+1234567890", + message: "Hello from PlaceRank!", + from: "PlaceRank", + }, + }, + { status: 200 } + ); +} \ No newline at end of file diff --git a/app/layout.tsx b/app/layout.tsx index f7fa87e..d0d888d 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,17 +1,6 @@ import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); - export const metadata: Metadata = { title: "Create Next App", description: "Generated by create next app", @@ -24,9 +13,7 @@ export default function RootLayout({ }>) { return ( - + {children} diff --git a/app/page.tsx b/app/page.tsx index 21b686d..76b787c 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -97,6 +97,12 @@ export default function Home() { /> Go to nextjs.org → + + 📱 Test SMS API + ); diff --git a/app/profile/page.tsx b/app/profile/page.tsx index e69de29..af109a5 100644 --- a/app/profile/page.tsx +++ b/app/profile/page.tsx @@ -0,0 +1,8 @@ +export default function ProfilePage() { + return ( +
+

Profile Page

+

Profile functionality coming soon...

+
+ ); +} \ No newline at end of file diff --git a/app/sms-test/page.tsx b/app/sms-test/page.tsx new file mode 100644 index 0000000..a359d17 --- /dev/null +++ b/app/sms-test/page.tsx @@ -0,0 +1,141 @@ +"use client"; + +import { useState } from "react"; +import { SMSResponse } from "@/lib/types/sms"; + +export default function SMSTestPage() { + const [to, setTo] = useState(""); + const [message, setMessage] = useState(""); + const [from, setFrom] = useState(""); + const [result, setResult] = useState(null); + const [loading, setLoading] = useState(false); + + const sendSMS = async () => { + setLoading(true); + setResult(null); + + try { + const response = await fetch("/api/sendSMS", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + to, + message, + ...(from && { from }), + }), + }); + + const data = await response.json(); + setResult(data); + } catch (error) { + setResult({ + success: false, + message: "Failed to send SMS", + error: error instanceof Error ? error.message : "Unknown error", + }); + } finally { + setLoading(false); + } + }; + + return ( +
+
+

SMS API Test

+ +
+
+ + setTo(e.target.value)} + className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" + /> +

+ Use international format (+1234567890) +

+
+ +
+ +