Skip to content

Next JS (OpenAI SDK)

If you’re using OpenAI JS/TS SDK with completions API, use this example to send chat data from Next.js to Growl.

In this example, we use the OpenAI SDK with completions API and streaming, and forward the data to Growl within an after call.

import recordGrowlEvent from './growl'
import OpenAI from "openai";
export async function POST(req: Request) {
// visitor_id is required - must be obtained from window.GrowlAds.getVisitorId() on client-side
const { messages, visitor_id }: { messages: any[]; visitor_id: string } = await req.json();
const client = new OpenAI();
// Ask the API to stream Server-Sent Events (SSE)
const stream = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: messages,
stream: true,
});
const encoder = new TextEncoder();
const summary = {
textParts: [] as string[], // collect *all* text chunks here
fullText: "",
};
const headersObject = Object.fromEntries(req.headers.entries());
after(async() => {
summary.fullText = summary.textParts.join("");
await recordGrowlEvent({
publisher_id: "<publisher_id>",
user_id: "<user-id>",
user_email: "<user-email>",
visitor_id: visitor_id, // from client: await GrowlAds.getVisitorId()
chat_id: "<chat-id>",
headers: headersObject,
user_message: { text : messages[messages.length -1] },
ai_message: { text: summary.fullText }
})
})
const readable = new ReadableStream({
async start(controller) {
try {
for await (const event of stream) {
// The stream sends typed events; emit text deltas to the client
if (event.choices[0].delta.content) {
controller.enqueue(
encoder.encode(event.choices[0].delta.content || "")
);
summary.textParts.push(event.choices[0].delta.content || ""); // store the entire text
}
if (event.choices[0].finish_reason === "stop") {
controller.close();
}
}
} catch (err) {
controller.error(err);
}
},
});
return new Response(readable, {
headers: { "Content-Type": "text/plain; charset=utf-8" },
});
}

In this example, we use the after function provided by the Next.js SDK and forward the data to Growl.

import recordGrowlEvent from './growl'
import OpenAI from "openai";
export async function POST(req: Request) {
// visitor_id is required - must be obtained from window.GrowlAds.getVisitorId() on client-side
const { messages, visitor_id }: { messages: any[]; visitor_id: string } = await req.json();
const client = new OpenAI();
try {
const completion = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: messages,
});
const fullText = completion.choices[0]?.message?.content ?? "";
const summary = {
textParts: [fullText],
fullText,
};
after(async () => {
const headersObject = Object.fromEntries(req.headers.entries());
await recordGrowlEvent({
publisher_id: "<publisher_id>",
user_id: "<user-id>",
user_email: "<user-email>",
visitor_id: visitor_id, // from client: await GrowlAds.getVisitorId()
chat_id: "<chat-id>",
headers: headersObject,
user_message: { text: messages[messages.length - 1] },
ai_message: { text: summary.fullText }
}
})
});
return new Response(fullText, {
headers: { "Content-Type": "text/plain; charset=utf-8" },
});
} catch (err) {
return new Response("Internal Server Error", { status: 500 });
}
}