Next.js में Agents Platform के साथ डेटा संग्रह और विश्लेषण

Agents Platform और Next.js का इस्तेमाल करके पोस्ट-कॉल वेबहुक में डेटा इकट्ठा करें और उसका विश्लेषण करें।

ट्यूटोरियल · इसमें माना गया है कि आपने ElevenAgents क्विकस्टार्ट पूरा कर लिया है और आपका Next.js प्रोजेक्ट सेट अप है।

परिचय

इस ट्यूटोरियल में, आप सीखेंगे कि ऐसा वॉइस एजेंट कैसे बनाएं जो बातचीत के ज़रिए यूज़र से जानकारी इकट्ठा करता है, फिर डेटा का विश्लेषण करके उसे संरचित रूप में निकालता है और पोस्ट-कॉल वेबहुक के ज़रिए आपके एप्लिकेशन को भेजता है।

ज़रूरी चीज़ें

  • API key वाला एक ElevenLabs अकाउंट। API key
  • आपकी मशीन पर Node.js v18 या उससे नया वर्ज़न इंस्टॉल होना चाहिए।

सेटअप

नया Next.js प्रोजेक्ट बनाएं

हम आपके एप्लिकेशन की शुरुआत के लिए हमारा v0.dev Agents Platform टेम्पलेट इस्तेमाल करने की सलाह देते हैं। यह ElevenLabs एजेंट के पहले से इंटीग्रेट किए हुए, प्रोडक्शन के लिए तैयार Next.js एप्लिकेशन का टेम्पलेट है।

Agents Platform सेट अप करें

इंस्टॉलेशन और कॉन्फ़िगरेशन के लिए हमारी Next.js गाइड देखें। फिर एडवांस्ड सुविधाएं बनाने के लिए यहां वापस आएं।

एजेंट कॉन्फ़िगरेशन

1

ElevenLabs में साइन इन करें

elevenlabs.io पर जाएं और अपने अकाउंट में साइन इन करें।

2

नया एजेंट बनाएं

Agents Platform > Agents पर जाएं और ब्लैंक टेम्पलेट से नया एजेंट बनाएं।

3

पहला संदेश सेट करें

पहला संदेश सेट करें और प्लेटफ़ॉर्म के लिए डायनामिक वेरिएबल निर्दिष्ट करें।

Hi {{user_name}}, I'm Jess from the ElevenLabs team. I'm here to help you design your very own ElevenLabs agent! To kick things off, let me know what kind of agent you're looking to create. For example, do you want a support agent, to help your users answer questions, or a sales agent to sell your products, or just a friend to chat with?
4

सिस्टम प्रॉम्प्ट सेट करें

सिस्टम प्रॉम्प्ट सेट करें। आप यहां डायनामिक वेरिएबल भी शामिल कर सकते हैं।

You are Jess, a helpful agent helping {{user_name}} to design their very own ElevenLabs agent. The design process involves the following steps:
"initial": In the first step, collect the information about the kind of agent the user is looking to create. Summarize the user's needs back to them and ask if they are ready to continue to the next step. Only once they confirm proceed to the next step.
"training": Tell the user to create the agent's knowledge base by uploading documents, or submitting URLs to public websites with information that should be available to the agent. Wait patiently without talking to the user. Only when the user confirms that they've provided everything then proceed to the next step.
"voice": Tell the user to describe the voice they want their agent to have. For example: "A professional, strong spoken female voice with a slight British accent." Repeat the description of their voice back to them and ask if they are ready to continue to the next step. Only once they confirm proceed to the next step.
"email": Tell the user that we've collected all necessary information to create their ElevenLabs agent and ask them to provide their email address to get notified when the agent is ready.
Always call the `set_ui_state` tool when moving between steps!
5

क्लाइंट टूल सेट अप करें

चरणों के बीच जाने के लिए यह क्लाइंट टूल सेट अप करें:

  • नाम: set_ui_state
    • विवरण: अलग-अलग UI स्टेट के बीच जाने के लिए इस क्लाइंट-साइड टूल का इस्तेमाल करें।
    • रिस्पॉन्स का इंतज़ार करें: true
    • रिस्पॉन्स टाइमआउट (सेकंड): 1
    • पैरामीटर:
      • डेटा टाइप: string
      • आइडेंटिफ़ायर: step
      • ज़रूरी: true
      • वैल्यू टाइप: LLM Prompt
      • विवरण: UI में जाने का चरण। सिर्फ़ उन्हीं चरणों का इस्तेमाल करें जो सिस्टम प्रॉम्प्ट में तय किए गए हैं!
6

अपने एजेंट की वॉइस सेट करें

Voice टैब पर जाएं और अपने एजेंट की वॉइस सेट करें। Agents Platform के लिए सुझाई गई वॉइस की सूची आपको Conversational Voice Design दस्तावेज़ में मिल सकती है।

7

मूल्यांकन मानदंड सेट करें

Analysis टैब पर जाएं और नया मूल्यांकन मानदंड जोड़ें।

  • नाम: all_data_provided
    • प्रॉम्प्ट: मूल्यांकन करें कि क्या यूज़र ने उस एजेंट का विवरण दिया है जिसे वे बनाना चाहते हैं, साथ ही उस वॉइस का विवरण भी दिया है जो एजेंट में होनी चाहिए।
8

डेटा संग्रह कॉन्फ़िगर करें

आप बातचीत से डेटा निकालने के लिए पोस्ट-कॉल विश्लेषण का इस्तेमाल कर सकते हैं। Analysis टैब में, Data Collection के तहत ये आइटम जोड़ें:

  • आइडेंटिफ़ायर: voice_description
    • data-type: String
    • विवरण: यूज़र एजेंट के लिए जैसी वॉइस चाहते हैं उसके विवरण के आधार पर, वॉइस का संक्षिप्त विवरण बनाएं, जिसमें उपलब्ध होने पर उम्र, एक्सेंट, टोन और व्यक्तित्व शामिल हों।
  • आइडेंटिफ़ायर: agent_description
    • data-type: String
    • विवरण: यूज़र जिस एजेंट को डिज़ाइन करना चाहते हैं, उसके विवरण के आधार पर ऐसा प्रॉम्प्ट बनाएं जिसका इस्तेमाल किसी मॉडल को एजेंट के रूप में काम करने के लिए ट्रेन करने में किया जा सके।
9

पोस्ट-कॉल वेबहुक कॉन्फ़िगर करें

कॉल खत्म होने और विश्लेषण व डेटा एक्सट्रैक्शन के चरण पूरे होने पर आपको सूचित करने के लिए पोस्ट-कॉल वेबहुक का इस्तेमाल होता है।

इस उदाहरण में पोस्ट-कॉल वेबहुक ये कुछ काम करता है:

  1. voice_description के आधार पर कस्टम वॉइस डिज़ाइन बनाता है।
  2. यूज़र के दिए गए agent_description के आधार पर उनके लिए ElevenLabs एजेंट बनाता है।
  3. Redis में स्टोर की गई बातचीत की स्टेट से नॉलेज बेस दस्तावेज़ हासिल करता है और नॉलेज बेस को एजेंट से अटैच करता है।
  4. यूज़र को ईमेल भेजता है, ताकि उन्हें पता चल सके कि उनका कस्टम ElevenLabs एजेंट चैट करने के लिए तैयार है।

लोकल रूप से चलाते समय, अपने लोकल सर्वर को इंटरनेट पर एक्सपोज़ करने के लिए आपको ngrok जैसे टूल की ज़रूरत होगी।

ngrok http 3000

Agents Platform सेटिंग्स पर जाएं और Post-Call Webhook के तहत नया वेबहुक बनाकर अपना ngrok URL पेस्ट करें: https://<your-url>.ngrok-free.app/api/convai-webhook।

वेबहुक सेव करने के बाद आपको वेबहुक सीक्रेट मिलेगा। इसे सुरक्षित रूप से स्टोर करें, क्योंकि बाद में आपको इसे अपनी .env फ़ाइल में सेट करना होगा।

एडवांस्ड सुविधाएं इंटीग्रेट करें

बातचीत की स्टेट स्टोर करने के लिए Redis डेटाबेस सेट अप करें

इस उदाहरण में हम बातचीत की स्टेट स्टोर करने के लिए Redis का इस्तेमाल कर रहे हैं। इससे कॉल खत्म होने के बाद हम बातचीत की स्टेट से नॉलेज बेस दस्तावेज़ हासिल कर सकते हैं।

अगर आप Vercel पर डिप्लॉय कर रहे हैं, तो Upstash for Redis इंटीग्रेशन कॉन्फ़िगर कर सकते हैं। वैकल्पिक रूप से, आप मुफ़्त Upstash अकाउंट के लिए साइन अप करके नया डेटाबेस बना सकते हैं।

पोस्ट-कॉल ईमेल भेजने के लिए Resend सेट अप करें

इस उदाहरण में हम यूज़र को पोस्ट-कॉल ईमेल भेजने के लिए Resend का इस्तेमाल कर रहे हैं। इसके लिए आपको मुफ़्त Resend अकाउंट बनाना होगा और नई API key सेट अप करनी होगी।

एनवायरनमेंट वेरिएबल सेट करें

अपने प्रोजेक्ट के रूट में .env फ़ाइल बनाएं और ये वेरिएबल जोड़ें:

ELEVENLABS_CONVAI_WEBHOOK_SECRET=
ELEVENLABS_API_KEY=
ELEVENLABS_AGENT_ID=
# Resend
RESEND_API_KEY=
RESEND_FROM_EMAIL=
# Upstash Redis
KV_URL=
KV_REST_API_READ_ONLY_TOKEN=
REDIS_URL=
KV_REST_API_TOKEN=
KV_REST_API_URL=

सुरक्षा और ऑथेंटिकेशन कॉन्फ़िगर करें

अपने ElevenLabs एजेंट को सुरक्षित रखने के लिए, आपको एजेंट कॉन्फ़िगरेशन के Security टैब में ऑथेंटिकेशन चालू करना होगा।

ऑथेंटिकेशन चालू होने के बाद, एजेंट के साथ बातचीत शुरू करने के लिए आपको सुरक्षित सर्वर-साइड एनवायरनमेंट में एक साइन किया हुआ URL बनाना होगा। Next.js में, आप नया API रूट सेट अप करके ऐसा कर सकते हैं।

./app/api/signed-url/route.ts
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import { NextResponse } from "next/server";
export async function GET() {
const agentId = process.env.ELEVENLABS_AGENT_ID;
if (!agentId) {
throw Error("ELEVENLABS_AGENT_ID is not set");
}
try {
const elevenlabs = new ElevenLabsClient();
const response = await elevenlabs.conversationalAi.conversations.getSignedUrl({
agentId,
});
return NextResponse.json({ signedUrl: response.signedUrl });
} catch (error) {
console.error("Error:", error);
return NextResponse.json({ error: "Failed to get signed URL" }, { status: 500 });
}
}

बातचीत सेशन शुरू करें

बातचीत शुरू करने के लिए, पहले साइन किया हुआ URL पाने के लिए अपना API रूट कॉल करें, फिर बातचीत सेशन सेट अप करने के लिए useConversation हुक इस्तेमाल करें।

./page.tsx
import { useConversation } from "@elevenlabs/react";
async function getSignedUrl(): Promise<string> {
const response = await fetch("/api/signed-url");
if (!response.ok) {
throw Error("Failed to get signed url");
}
const data = await response.json();
return data.signedUrl;
}
export default function Home() {
// ...
const [currentStep, setCurrentStep] = useState<
"initial" | "training" | "voice" | "email" | "ready"
>("initial");
const [conversationId, setConversationId] = useState("");
const [userName, setUserName] = useState("");
const conversation = useConversation({
onConnect: () => console.log("Connected"),
onDisconnect: () => console.log("Disconnected"),
onMessage: (message: string) => console.log("Message:", message),
onError: (error: Error) => console.error("Error:", error),
});
const startConversation = useCallback(async () => {
try {
// Request microphone permission
await navigator.mediaDevices.getUserMedia({ audio: true });
// Start the conversation with your agent
const signedUrl = await getSignedUrl();
const convId = await conversation.startSession({
signedUrl,
dynamicVariables: {
user_name: userName,
},
clientTools: {
set_ui_state: ({ step }: { step: string }): string => {
// Allow agent to navigate the UI.
setCurrentStep(step as "initial" | "training" | "voice" | "email" | "ready");
return `Navigated to ${step}`;
},
},
});
setConversationId(convId);
console.log("Conversation ID:", convId);
} catch (error) {
console.error("Failed to start conversation:", error);
}
}, [conversation, userName]);
const stopConversation = useCallback(async () => {
await conversation.endSession();
}, [conversation]);
// ...
}

क्लाइंट टूल और डायनामिक वेरिएबल

पहले एजेंट कॉन्फ़िगरेशन में, आपने एजेंट को अलग-अलग UI स्टेट के बीच जाने देने के लिए set_ui_state क्लाइंट टूल रजिस्टर किया था। इसे एक साथ काम करने के लिए, आपको क्लाइंट टूल का इंप्लीमेंटेशन conversation.startSession ऑप्शन में पास करना होगा।

यहीं पर आप बातचीत में डायनामिक वेरिएबल भी पास कर सकते हैं।

./page.tsx
const convId = await conversation.startSession({
signedUrl,
dynamicVariables: {
user_name: userName,
},
clientTools: {
set_ui_state: ({ step }: { step: string }): string => {
// Allow agent to navigate the UI.
setCurrentStep(step as "initial" | "training" | "voice" | "email" | "ready");
return `Navigated to ${step}`;
},
},
});

नॉलेज बेस में दस्तावेज़ अपलोड करना

Training चरण में, एजेंट यूज़र से दस्तावेज़ अपलोड करने या ऐसी सार्वजनिक वेबसाइटों के URL सबमिट करने के लिए कहेगा जिनकी जानकारी उनके एजेंट के लिए उपलब्ध होनी चाहिए। यहां आप बैकग्राउंड में दस्तावेज़ अपलोड करने के लिए Next.js 15 के नए after फ़ंक्शन का इस्तेमाल कर सकते हैं।

फ़ॉर्म सबमिट होने पर नॉलेज बेस बनाने के लिए नया upload सर्वर एक्शन बनाएं। सभी नॉलेज बेस दस्तावेज़ बनने के बाद, बातचीत ID और नॉलेज बेस ID को Redis डेटाबेस में स्टोर करें।

./app/actions/upload.ts
"use server";
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import { Redis } from "@upstash/redis";
import { redirect } from "next/navigation";
import { after } from "next/server";
// Initialize Redis
const redis = Redis.fromEnv();
const elevenlabs = new ElevenLabsClient({
apiKey: process.env.ELEVENLABS_API_KEY,
});
export async function uploadFormData(formData: FormData) {
const knowledgeBase: Array<{
id: string;
type: "file" | "url";
name: string;
}> = [];
const files = formData.getAll("file-upload") as File[];
const email = formData.get("email-input");
const urls = formData.getAll("url-input");
const conversationId = formData.get("conversation-id");
after(async () => {
// Upload files as background job
// Create knowledge base entries
// Loop through files and create knowledge base entries
for (const file of files) {
if (file.size > 0) {
const response = await elevenlabs.conversationalAi.knowledgeBase.documents.createFromFile({
file,
});
if (response.id) {
knowledgeBase.push({
id: response.id,
type: "file",
name: file.name,
});
}
}
}
// Append all urls
for (const url of urls) {
const response = await elevenlabs.conversationalAi.knowledgeBase.documents.createFromUrl({
url: url as string,
});
if (response.id) {
knowledgeBase.push({
id: response.id,
type: "url",
name: `url for ${conversationId}`,
});
}
}
// Store knowledge base IDs and conversation ID in database.
const redisRes = await redis.set(
conversationId as string,
JSON.stringify({ email, knowledgeBase })
);
console.log({ redisRes });
});
redirect("/success");
}

कॉल के बाद वाले वेबहुक को संभालना

कॉल खत्म होने और विश्लेषण व डेटा एक्सट्रैक्शन के चरण पूरे होने पर कॉल के बाद वाला वेबहुक ट्रिगर होता है।

यहां कुछ चरण होते हैं:

  1. वेबहुक सीक्रेट सत्यापित करें और वेबहुक पेलोड बनाएं।
  2. voice_description के आधार पर एक कस्टम वॉइस डिज़ाइन बनाएं।
  3. यूज़र के दिए गए agent_description के आधार पर उनके लिए एक ElevenLabs एजेंट बनाएं।
  4. Redis में स्टोर किए गए कन्वर्सेशन स्टेट से नॉलेज बेस दस्तावेज़ प्राप्त करें और नॉलेज बेस को एजेंट से अटैच करें।
  5. यूज़र को यह बताने के लिए ईमेल भेजें कि उनका कस्टम ElevenLabs एजेंट चैट के लिए तैयार है।
./app/api/convai-webhook/route.ts
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import { Redis } from "@upstash/redis";
import crypto from "crypto";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { Resend } from "resend";
import { EmailTemplate } from "@/components/email/post-call-webhook-email";
// Initialize Redis
const redis = Redis.fromEnv();
// Initialize Resend
const resend = new Resend(process.env.RESEND_API_KEY);
const elevenlabs = new ElevenLabsClient({
apiKey: process.env.ELEVENLABS_API_KEY,
});
export async function GET() {
return NextResponse.json({ status: "webhook listening" }, { status: 200 });
}
export async function POST(req: NextRequest) {
const secret = process.env.ELEVENLABS_CONVAI_WEBHOOK_SECRET; // Add this to your env variables
const { event, error } = await constructWebhookEvent(req, secret);
if (error) {
return NextResponse.json({ error: error }, { status: 401 });
}
if (event.type === "post_call_transcription") {
const { conversation_id, analysis, agent_id } = event.data;
if (
agent_id === process.env.ELEVENLABS_AGENT_ID &&
analysis.evaluation_criteria_results.all_data_provided?.result === "success" &&
analysis.data_collection_results.voice_description?.value
) {
try {
// Design the voice
const voicePreview = await elevenlabs.textToVoice.createPreviews({
voiceDescription: analysis.data_collection_results.voice_description.value,
text: "The night air carried whispers of betrayal, thick as London fog. I adjusted my cufflinks - after all, even spies must maintain appearances, especially when the game is afoot.",
});
const voice = await elevenlabs.textToVoice.createVoiceFromPreview({
voiceName: `voice-${conversation_id}`,
voiceDescription: `Voice for ${conversation_id}`,
generatedVoiceId: voicePreview.previews[0].generatedVoiceId,
});
// Get the knowledge base from redis
const redisRes = await getRedisDataWithRetry(conversation_id);
if (!redisRes) throw new Error("Conversation data not found!");
// Handle agent creation
const agent = await elevenlabs.conversationalAi.agents.create({
name: `Agent for ${conversation_id}`,
conversationConfig: {
tts: { voiceId: voice.voiceId },
agent: {
prompt: {
prompt:
analysis.data_collection_results.agent_description?.value ??
"You are a helpful assistant.",
knowledgeBase: redisRes.knowledgeBase,
},
firstMessage: "Hello, how can I help you today?",
},
},
});
console.log("Agent created", { agent: agent.agentId });
// Send email to user
console.log("Sending email to", redisRes.email);
await resend.emails.send({
from: process.env.RESEND_FROM_EMAIL!,
to: redisRes.email,
subject: "Your ElevenLabs agent is ready to chat!",
react: EmailTemplate({ agentId: agent.agentId }),
});
} catch (error) {
console.error(error);
return NextResponse.json({ error }, { status: 500 });
}
}
}
return NextResponse.json({ received: true }, { status: 200 });
}
const constructWebhookEvent = async (req: NextRequest, secret?: string) => {
const body = await req.text();
const signatureHeader = req.headers.get("ElevenLabs-Signature");
return await elevenlabs.webhooks.constructEvent(body, signatureHeader, secret);
};
async function getRedisDataWithRetry(
conversationId: string,
maxRetries = 5
): Promise<{
email: string;
knowledgeBase: Array<{
id: string;
type: "file" | "url";
name: string;
}>;
} | null> {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const data = await redis.get(conversationId);
return data as any;
} catch (error) {
if (attempt === maxRetries) throw error;
console.log(`Redis get attempt ${attempt} failed, retrying...`);
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}
return null;
}

अब हर चरण को विस्तार से देखते हैं।

वेबहुक सीक्रेट सत्यापित करें और वेबहुक पेलोड बनाएं

वेबहुक रिक्वेस्ट मिलने पर, हम पहले वेबहुक सीक्रेट सत्यापित करते हैं और वेबहुक पेलोड बनाते हैं।

./app/api/convai-webhook/route.ts
// ...
export async function POST(req: NextRequest) {
const secret = process.env.ELEVENLABS_CONVAI_WEBHOOK_SECRET;
const { event, error } = await constructWebhookEvent(req, secret);
// ...
}
// ...
const constructWebhookEvent = async (req: NextRequest, secret?: string) => {
const body = await req.text();
const signatureHeader = req.headers.get("ElevenLabs-Signature");
return await elevenlabs.webhooks.constructEvent(body, signatureHeader, secret);
};
async function getRedisDataWithRetry(
conversationId: string,
maxRetries = 5
): Promise<{
email: string;
knowledgeBase: Array<{
id: string;
type: "file" | "url";
name: string;
}>;
} | null> {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const data = await redis.get(conversationId);
return data as any;
} catch (error) {
if (attempt === maxRetries) throw error;
console.log(`Redis get attempt ${attempt} failed, retrying...`);
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}
return null;
}

voice_description के आधार पर कस्टम वॉइस डिज़ाइन बनाएं

वेबहुक पेलोड से मिले voice_description का इस्तेमाल करके, हम कस्टम वॉइस डिज़ाइन बनाते हैं।

./app/api/convai-webhook/route.ts
// ...
// Design the voice
const voicePreview = await elevenlabs.textToVoice.createPreviews({
voiceDescription: analysis.data_collection_results.voice_description.value,
text: "The night air carried whispers of betrayal, thick as London fog. I adjusted my cufflinks - after all, even spies must maintain appearances, especially when the game is afoot.",
});
const voice = await elevenlabs.textToVoice.createVoiceFromPreview({
voiceName: `voice-${conversation_id}`,
voiceDescription: `Voice for ${conversation_id}`,
generatedVoiceId: voicePreview.previews[0].generatedVoiceId,
});
// ...

Redis में स्टोर किए गए कन्वर्सेशन स्टेट से नॉलेज बेस दस्तावेज़ प्राप्त करें

दस्तावेज़ अपलोड होने में वेबहुक डेटा विश्लेषण से ज़्यादा समय लग सकता है, इसलिए दस्तावेज़ अपलोड होने तक हमें Redis में कन्वर्सेशन स्टेट को पोल करना होगा।

./app/api/convai-webhook/route.ts
// ...
// Get the knowledge base from redis
const redisRes = await getRedisDataWithRetry(conversation_id);
if (!redisRes) throw new Error("Conversation data not found!");
// ...
async function getRedisDataWithRetry(
conversationId: string,
maxRetries = 5
): Promise<{
email: string;
knowledgeBase: Array<{
id: string;
type: "file" | "url";
name: string;
}>;
} | null> {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const data = await redis.get(conversationId);
return data as any;
} catch (error) {
if (attempt === maxRetries) throw error;
console.log(`Redis get attempt ${attempt} failed, retrying...`);
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}
return null;
}

यूज़र के दिए गए agent_description के आधार पर उनके लिए ElevenLabs एजेंट बनाएं

यूज़र के दिए गए agent_description के आधार पर उनके लिए ElevenLabs एजेंट बनाएं और नए बनाए गए वॉइस डिज़ाइन व नॉलेज बेस को एजेंट से अटैच करें।

./app/api/convai-webhook/route.ts
// ...
// Handle agent creation
const agent = await elevenlabs.conversationalAi.agents.create({
name: `Agent for ${conversationId}`,
conversationConfig: {
tts: { voiceId: voice.voiceId },
agent: {
prompt: {
prompt:
analysis.data_collection_results.agent_description?.value ??
"You are a helpful assistant.",
knowledgeBase: redisRes.knowledgeBase,
},
firstMessage: "Hello, how can I help you today?",
},
},
});
console.log("Agent created", { agent: agent.agentId });
// ...

यूज़र को बताने के लिए ईमेल भेजें कि उनका कस्टम ElevenLabs एजेंट चैट के लिए तैयार है

एजेंट बनने के बाद, आप यूज़र को यह बताने के लिए ईमेल भेज सकते हैं कि उनका कस्टम ElevenLabs एजेंट चैट के लिए तैयार है।

./app/api/convai-webhook/route.ts
import { Resend } from "resend";
import { EmailTemplate } from "@/components/email/post-call-webhook-email";
// ...
// Send email to user
console.log("Sending email to", redisRes.email);
await resend.emails.send({
from: process.env.RESEND_FROM_EMAIL!,
to: redisRes.email,
subject: "Your ElevenLabs agent is ready to chat!",
react: EmailTemplate({ agentId: agent.agentId }),
});
// ...

ईमेल टेम्पलेट को वाइब डिज़ाइन करने के लिए आप Resend टीम के आसान टूल new.email का इस्तेमाल कर सकते हैं। टेम्पलेट से संतुष्ट होने पर, एक नया कंपोनेंट बनाएं और एजेंट ID को प्रॉप के रूप में जोड़ें।

./components/email/post-call-webhook-email.tsx
import {
Body,
Button,
Container,
Head,
Html,
Section,
Text,
Tailwind,
} from "@react-email/components";
import * as React from "react";
const EmailTemplate = (props: any) => {
const { agentId } = props;
return (
<Html>
<Head />
<Tailwind>
<Body className="bg-[#151516] font-sans">
<Container className="mx-auto my-[40px] max-w-[600px] rounded-[8px] bg-[#0a1929] p-[20px]">
{/* Top Section */}
<Section className="mb-[32px] mt-[32px] text-center">
<Text className="m-0 text-[28px] font-bold text-[#9c27b0]">
Your ElevenLabs agent is ready to chat!
</Text>
</Section>
{/* Content Area with Icon */}
<Section className="mb-[32px] text-center">
{/* Circle Icon with Checkmark */}
<div className="mx-auto mb-[24px] flex h-[80px] w-[80px] items-center justify-center rounded-full bg-gradient-to-r from-[#9c27b0] to-[#3f51b5]">
<div className="text-[40px] text-white">✓</div>
</div>
{/* Descriptive Text */}
<Text className="mb-[24px] text-[18px] text-white">
Your ElevenLabs agent is ready to chat!
</Text>
</Section>
{/* Call to Action Button */}
<Section className="mb-[32px] text-center">
<Button
href={`https://elevenlabs.io/app/talk-to?agent_id=${agentId}`}
className="box-border rounded-[8px] bg-[#9c27b0] px-[40px] py-[20px] text-[24px] font-bold text-white no-underline"
>
Chat now!
</Button>
</Section>
{/* Footer */}
<Section className="mt-[40px] border-t border-[#2d3748] pt-[20px] text-center">
<Text className="m-0 text-[14px] text-white">
Powered by{" "}
<a
href="https://elevenlabs.io/conversational-ai"
target="_blank"
rel="noopener noreferrer"
className="underline transition-colors hover:text-gray-400"
>
ElevenLabs Agents
</a>
</Text>
</Section>
</Container>
</Body>
</Tailwind>
</Html>
);
};
export { EmailTemplate };

ऐप चलाएं

ऐप को लोकल रूप से शुरू से अंत तक चलाने के लिए, पहले आपको Next.js डेवलपमेंट सर्वर चलाना होगा। फिर एक अलग टर्मिनल में वेबहुक हैंडलर को इंटरनेट पर एक्सपोज़ करने के लिए ngrok टनल चलाएं।

  • टर्मिनल 1:
    • Next.js डेवलपमेंट सर्वर शुरू करने के लिए pnpm dev चलाएं।
pnpm dev
  • टर्मिनल 2:
    • वेबहुक हैंडलर को इंटरनेट पर एक्सपोज़ करने के लिए ngrok http 3000 चलाएं।
ngrok http 3000

अब http://localhost:3000 खोलें और अपनी वॉइस के साथ अपना कस्टम ElevenLabs एजेंट डिज़ाइन करना शुरू करें!

अगले चरण