Skip to content

Commit

Permalink
feat: almost ready
Browse files Browse the repository at this point in the history
  • Loading branch information
louisjoecodes committed Dec 4, 2024
1 parent 3e6d48d commit 872c5b5
Show file tree
Hide file tree
Showing 19 changed files with 738 additions and 794 deletions.
37 changes: 1 addition & 36 deletions examples/conversational-ai/talk-to-santa/README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
# 🎄 Talk to Santa
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"use server";

import { actionClient } from "@/app/(main)/actions/safe-action";
import { z } from "zod";
import { ElevenLabsClient } from "elevenlabs";

export const getAgentSignedUrl = actionClient
.schema(z.object({}))
.action(async () => {
const agentId = process.env.AGENT_ID;
const apiKey = process.env.XI_API_KEY;

if (!agentId || !apiKey) {
throw new Error("Environment variables are not set");
}

const elevenlabs = new ElevenLabsClient({
apiKey: apiKey,
});

try {
const { signed_url: signedUrl } =
await elevenlabs.conversationalAi.getSignedUrl({
agent_id: agentId,
});

if (!signedUrl) {
throw new Error("Failed to get signed URL");
}

return { signedUrl };
} catch (error) {
throw new Error(`Failed to get signed URL: ${error}`);
}
});

export const getAgentConversation = actionClient
.schema(
z.object({
conversationId: z.string(),
})
)
.action(async ({ parsedInput: { conversationId } }) => {
const apiKey = process.env.XI_API_KEY;

if (!apiKey) {
throw new Error("XI_API_KEY is not set");
}

const elevenlabs = new ElevenLabsClient({
apiKey: apiKey,
});

try {
const conversation = await elevenlabs.conversationalAi.getConversation(
conversationId
);
return { conversation };
} catch (error) {
throw new Error(`Failed to get conversation: ${error}`);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
DEFAULT_SERVER_ERROR_MESSAGE,
createSafeActionClient,
} from "next-safe-action";
import { headers } from "next/headers";

export const actionClient = createSafeActionClient({
handleServerError(e) {
if (e instanceof Error) {
return e.message;
}

return DEFAULT_SERVER_ERROR_MESSAGE;
},
}).use(async ({ next }) => {
// forward the user's ip address to context (for rate limiting)
const ip = (await headers()).get("x-forwarded-for") ?? "127.0.0.1";
return next({ ctx: { ip } });
});

39 changes: 39 additions & 0 deletions examples/conversational-ai/talk-to-santa/app/(main)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Logo } from "@/components/logo/index";
import { ChristmasCountdown } from "@/components/christmas-countdown";
import { Snowfall } from "@/components/snowfall";
import { MusicPlayer } from "@/components/music-player";

export default function Layout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<div className="relative min-h-screen overflow-hidden font-[family-name:var(--font-geist-sans)]">
<div className="absolute top-0 left-0 right-0 flex justify-between p-4 z-10">
<Logo />
<ChristmasCountdown />
</div>

<main>
<div className="flex flex-col items-center justify-center min-h-screen">
{children}
</div>
</main>

<div
className="absolute inset-0 z-[-2]"
style={{
background: `radial-gradient(circle, rgb(168 0 0 / 50%) 20%, rgba(0,0,0,0.7) 100%), url('/assets/background.jpg')`,
backgroundSize: "cover",
backgroundPosition: "center",
backgroundBlendMode: "color-burn",
}}
/>
<div className="absolute inset-0 z-[-1]">
<Snowfall />
</div>
<MusicPlayer />
</div>
);
}
Loading

0 comments on commit 872c5b5

Please sign in to comment.