summaryrefslogtreecommitdiff
path: root/webapp/app
diff options
context:
space:
mode:
authorIlan Bigio <ilan@openai.com>2024-12-16 13:06:08 -0800
committerIlan Bigio <ilan@openai.com>2024-12-19 16:08:22 -0500
commit20009aed53d8864c9204d43a17895168a777d2cc (patch)
tree754dded819869bc34a8a2a02c66ea72dac1ccd24 /webapp/app
Initial commit
Diffstat (limited to 'webapp/app')
-rw-r--r--webapp/app/api/twilio/numbers/route.ts31
-rw-r--r--webapp/app/api/twilio/route.ts6
-rw-r--r--webapp/app/api/twilio/webhook-local/route.ts3
-rw-r--r--webapp/app/favicon.icobin0 -> 65534 bytes
-rw-r--r--webapp/app/globals.css69
-rw-r--r--webapp/app/layout.tsx23
-rw-r--r--webapp/app/page.tsx5
7 files changed, 137 insertions, 0 deletions
diff --git a/webapp/app/api/twilio/numbers/route.ts b/webapp/app/api/twilio/numbers/route.ts
new file mode 100644
index 0000000..53c13c8
--- /dev/null
+++ b/webapp/app/api/twilio/numbers/route.ts
@@ -0,0 +1,31 @@
+import twilioClient from "@/lib/twilio";
+
+export async function GET() {
+ if (!twilioClient) {
+ return Response.json(
+ { error: "Twilio client not initialized" },
+ { status: 500 }
+ );
+ }
+
+ const incomingPhoneNumbers = await twilioClient.incomingPhoneNumbers.list({
+ limit: 20,
+ });
+ return Response.json(incomingPhoneNumbers);
+}
+
+export async function POST(req: Request) {
+ if (!twilioClient) {
+ return Response.json(
+ { error: "Twilio client not initialized" },
+ { status: 500 }
+ );
+ }
+
+ const { phoneNumberSid, voiceUrl } = await req.json();
+ const incomingPhoneNumber = await twilioClient
+ .incomingPhoneNumbers(phoneNumberSid)
+ .update({ voiceUrl });
+
+ return Response.json(incomingPhoneNumber);
+}
diff --git a/webapp/app/api/twilio/route.ts b/webapp/app/api/twilio/route.ts
new file mode 100644
index 0000000..6313295
--- /dev/null
+++ b/webapp/app/api/twilio/route.ts
@@ -0,0 +1,6 @@
+export async function GET() {
+ const credentialsSet = Boolean(
+ process.env.TWILIO_ACCOUNT_SID && process.env.TWILIO_AUTH_TOKEN
+ );
+ return Response.json({ credentialsSet });
+}
diff --git a/webapp/app/api/twilio/webhook-local/route.ts b/webapp/app/api/twilio/webhook-local/route.ts
new file mode 100644
index 0000000..2dc5420
--- /dev/null
+++ b/webapp/app/api/twilio/webhook-local/route.ts
@@ -0,0 +1,3 @@
+export async function GET() {
+ return Response.json({ webhookUrl: process.env.TWILIO_WEBHOOK_URL });
+}
diff --git a/webapp/app/favicon.ico b/webapp/app/favicon.ico
new file mode 100644
index 0000000..f3e821d
--- /dev/null
+++ b/webapp/app/favicon.ico
Binary files differ
diff --git a/webapp/app/globals.css b/webapp/app/globals.css
new file mode 100644
index 0000000..99a7b0c
--- /dev/null
+++ b/webapp/app/globals.css
@@ -0,0 +1,69 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer base {
+ :root {
+ --background: 0 0% 100%;
+ --foreground: 222.2 84% 4.9%;
+ --card: 0 0% 100%;
+ --card-foreground: 222.2 84% 4.9%;
+ --popover: 0 0% 100%;
+ --popover-foreground: 222.2 84% 4.9%;
+ --primary: 222.2 47.4% 11.2%;
+ --primary-foreground: 210 40% 98%;
+ --secondary: 210 40% 96.1%;
+ --secondary-foreground: 222.2 47.4% 11.2%;
+ --muted: 210 40% 96.1%;
+ --muted-foreground: 215.4 16.3% 46.9%;
+ --accent: 210 40% 96.1%;
+ --accent-foreground: 222.2 47.4% 11.2%;
+ --destructive: 0 84.2% 60.2%;
+ --destructive-foreground: 210 40% 98%;
+ --border: 214.3 31.8% 91.4%;
+ --input: 214.3 31.8% 91.4%;
+ --ring: 222.2 84% 4.9%;
+ --radius: 0.5rem;
+ --chart-1: 12 76% 61%;
+ --chart-2: 173 58% 39%;
+ --chart-3: 197 37% 24%;
+ --chart-4: 43 74% 66%;
+ --chart-5: 27 87% 67%;
+ }
+
+ .dark {
+ --background: 222.2 84% 4.9%;
+ --foreground: 210 40% 98%;
+ --card: 222.2 84% 4.9%;
+ --card-foreground: 210 40% 98%;
+ --popover: 222.2 84% 4.9%;
+ --popover-foreground: 210 40% 98%;
+ --primary: 210 40% 98%;
+ --primary-foreground: 222.2 47.4% 11.2%;
+ --secondary: 217.2 32.6% 17.5%;
+ --secondary-foreground: 210 40% 98%;
+ --muted: 217.2 32.6% 17.5%;
+ --muted-foreground: 215 20.2% 65.1%;
+ --accent: 217.2 32.6% 17.5%;
+ --accent-foreground: 210 40% 98%;
+ --destructive: 0 62.8% 30.6%;
+ --destructive-foreground: 210 40% 98%;
+ --border: 217.2 32.6% 17.5%;
+ --input: 217.2 32.6% 17.5%;
+ --ring: 212.7 26.8% 83.9%;
+ --chart-1: 220 70% 50%;
+ --chart-2: 160 60% 45%;
+ --chart-3: 30 80% 55%;
+ --chart-4: 280 65% 60%;
+ --chart-5: 340 75% 55%;
+ }
+}
+
+@layer base {
+ * {
+ @apply border-border;
+ }
+ body {
+ @apply bg-background text-foreground;
+ }
+} \ No newline at end of file
diff --git a/webapp/app/layout.tsx b/webapp/app/layout.tsx
new file mode 100644
index 0000000..6907ee0
--- /dev/null
+++ b/webapp/app/layout.tsx
@@ -0,0 +1,23 @@
+import type { Metadata } from "next";
+import { Inter } from "next/font/google";
+import "./globals.css";
+
+const inter = Inter({ subsets: ["latin"] });
+
+export const metadata: Metadata = {
+ title: "OpenAI Realtime + Twilio",
+ description:
+ "Sample phone call assistant app for OpenAI Realtime API and Twilio",
+};
+
+export default function RootLayout({
+ children,
+}: Readonly<{
+ children: React.ReactNode;
+}>) {
+ return (
+ <html lang="en">
+ <body className={inter.className}>{children}</body>
+ </html>
+ );
+}
diff --git a/webapp/app/page.tsx b/webapp/app/page.tsx
new file mode 100644
index 0000000..07297e4
--- /dev/null
+++ b/webapp/app/page.tsx
@@ -0,0 +1,5 @@
+import CallInterface from "@/components/call-interface";
+
+export default function Page() {
+ return <CallInterface />;
+}