I arrived in Germany about a week ago, and my current goal is to secure a development position in Frankfurt, I have been trying to learn German. Since I'm not the type of person who studies with books, I plan to study German by texting with German-speaking friends until I reach a certain level. In the mean time, I have been using Google Translator and ChatGPT to translate and learn from the translated sentences. The keywords that I often use with ChatGPT are following.
- Correct this ""
- "" in German and break it down
I use first one to correct my English sentences and the second one to translate my sentence into German and get some explanation. However, I found it bothersome that I have to type the same thing every time. So, I thought it would be good to create my own German translator to make the process easier. Additionally, if I add a TTS(Text-to-Speech) feature to the app, it would definitely save me a lot of time because I use TTS all the time to listen to the pronunciation of German words.
For the first attempt, I decided to create a simple example using OpenAI API. I also chose NextJS and Vercel, thinking it would save me a lot of time too since they both use one language(javascript) and there's no need for a separate server with NextJS. Plus, deploying with Vercel is just a one-click process.
You can obtain your own API KEY from OpenAI, then enter the key in the input box and click on Register
. If you have entered the correct key, the translate button will be enabled after refreshing the page.
Enter any text you want to translate into German, then click the Translate
button. The result will be displayed as shown above.
[pages/api/key/register.ts]
import type { NextApiRequest, NextApiResponse } from "next";
import { setCookie } from "cookies-next";
type Param = {
key: string;
};
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== "POST") {
return res.status(405).end();
}
const param: Param = req.body;
setCookie("key", param.key, { req, res });
res.status(200).end();
}
I used the library cookies-next
to handle cookies. Register
API saves an API key in cookies that it obtained from the request, and it will allow you to use the same key even after closing the tab.
[pages/api/key/unregister.ts]
import type { NextApiRequest, NextApiResponse } from "next";
import { deleteCookie } from "cookies-next";
export default function handler(req: NextApiRequest, res: NextApiResponse) {
deleteCookie("key", { req, res });
res.status(200).end();
}
Unregister
API deletes an API KEY from cookies.
[pages/api/translate/german.ts]
import type { NextApiRequest, NextApiResponse } from "next";
import { getCookie } from "cookies-next";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const key = getCookie("key", { req, res });
const content = `"${req.body.message}" in German and break it down`;
const apiRes = await fetch("https://api.openai.com/v1/chat/completions", {
method: "post",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${key}`,
},
body: JSON.stringify({
model: "gpt-3.5-turbo",
messages: [{ role: "user", content }],
}),
// body: JSON.stringify({
// model: "gpt-3.5-turbo",
// messages: [
// { role: "system", content: "You are a great German teacher." },
// {
// role: "assistant",
// content:
// "Yes, I am. I will translate your German sentence and explain the detail about the translated sentence. ",
// },
// { role: "user", content },
// ],
// }),
});
if (apiRes.status !== 200) {
return res.status(500).send(`open ai API status code: ${apiRes.status}`);
}
const json = await apiRes.json();
res.status(200).json({
message: !json.choices?.length ? "" : json.choices[0].message.content,
});
}
German
API receives text from a client, sends a request to the OpenAI API, and then sends the response of the API back to the client.
You can create your own conversation and use it to generate chat completions, like the following.
...
body: JSON.stringify({
model: "gpt-3.5-turbo",
messages: [
{ role: "system", content: "You are a great German teacher." },
{
role: "assistant",
content:
"Yes, I am. I will translate your German sentence and explain the detail about the translated sentence. ",
},
{ role: "user", content },
],
}),
...
But in my case, using one message was enough and looked better, so I passed only one message to the Chat API.
const content = `"${req.body.message}" in German and break it down`;
...
body: JSON.stringify({
model: "gpt-3.5-turbo",
messages: [{ role: "user", content }],
}),
[page/index.tsx]
import Head from "next/head";
import { useEffect, useRef, useState } from "react";
import { getCookies } from "cookies-next";
import { TmpCookiesObj } from "cookies-next/lib/types";
import { GetServerSideProps } from "next";
interface PageProps {
cookies: TmpCookiesObj;
}
export const getServerSideProps: GetServerSideProps<PageProps> = async (
context
) => {
const cookies = getCookies({
req: context.req,
res: context.res,
});
return {
props: {
cookies,
},
};
};
export default function Home({ cookies }: PageProps) {
const [translating, setTranslating] = useState(false);
const keyInputRef = useRef<HTMLInputElement>(null);
const messageInputRef = useRef<HTMLTextAreaElement>(null);
const resultTextRef = useRef<HTMLDivElement>(null);
const key = cookies["key"];
const keyRegistered = key !== undefined;
const handleRegisterClick = async () => {
if (keyRegistered) {
await fetch("api/key/unregister");
location.reload();
} else {
const key = keyInputRef.current?.value.trim() || "";
if (!key?.length) {
alert("Enter your key");
return;
}
await fetch("api/key/register", {
method: "post",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
key,
}),
});
}
location.reload();
};
const translate = async () => {
setTranslating(true);
try {
const res = await fetch("api/translate/german", {
method: "post",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
message: messageInputRef.current?.value || "",
}),
});
const json = await res.json();
if (resultTextRef.current) {
resultTextRef.current.innerText = json.message || "";
}
} finally {
setTranslating(false);
}
};
useEffect(() => {
if (!keyInputRef.current) return;
keyInputRef.current.value = key || "";
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<>
<Head>
<title>Translator</title>
<meta name="description" content="Generated by create next app" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className="box-border w-full px-4 mt-8 md:mx-auto md:w-3/6">
<section className="border p-4 mb-4">
<div className="flex items-center">
<label className="w-44">OpenAI Secret Key</label>
<input
ref={keyInputRef}
type="text"
placeholder="Enter your key"
className="border h-8 p-2 disabled:opacity-50"
disabled={keyRegistered}
/>
</div>
<button
type="button"
className="border bg-sky-500 text-white p-2 rounded hover:opacity-70"
onClick={handleRegisterClick}
>
{keyRegistered ? "Unregister" : "Register"}
</button>
</section>
<section className="border p-4">
<div className="flex flex-col gap-y-2">
<label className="w-44">English</label>
<textarea
placeholder="Input"
className="border h-32 p-4"
ref={messageInputRef}
></textarea>
</div>
<button
type="button"
className="border bg-sky-500 text-white p-2 rounded hover:opacity-70 mt-4 disabled:opacity-25"
disabled={!keyRegistered || translating}
onClick={translate}
>
Translate
</button>
<div
className="border w-100 h-60 mt-4 p-4 overflow-y-auto"
ref={resultTextRef}
>
Result
</div>
</section>
</main>
</>
);
}
There are many models, features and API options available. You can check in OpenAI API Docs. To create the example quickly, I just gave a quick view and wrote code. I recommend you to read the documentation thoroughly before getting started.
In the future, I plan to create a better version of this app that includes a TTS feature and creates several chat completions at once I want. I will use it as my German teacher. I will share about it later.
It's amazing how technology has made our lives easier. I'm grateful to be living in this generation.
Thank you for reading my article, and I hope you found it helpful.
Happy Coding!
Top comments (0)