Innovative Ways to Use ChatGPT's API: Building a Random Quote Generator
Tags: beginners, ai, chatgpt, openai
Published: 2023-03-24 10:35:03

Building a random quote generator as a beginner project is fun, but have you thought of spicing things up with the latest AI trend? In this article, we will use the ChatGPT API while building a random quote generator application with React and Bootstrap.
###Requirements
- Good understanding of React
- Experience with any CSS framework, preferably Bootstrap, since it's used in the tutorial
- The willingness to learn and explore.

##What is a Random Quote Generator?
If you ask this question, I doubt you have looked up beginner projects to test your newly acquired coding skills. A random quote generator is a website that generates random quote texts. The quotes could be motivational, inspirational, religious, academic, or even demotivational. You could decide to further test your proficiency by adding a filter functionality. The filter allows users to select and generate the type of code they want. And that is what you'll learn here. 
##Setting Up React for the Application
For a faster and more optimized application, we will scaffold our React app with Vite rather than Create-React-App.
- Enter the command below to create a React application with vite.
```cmd
npm create vite@latest gpt-rqg-app --template react

/*This command is a one-liner that directly scaffold a react app as it eliminates the manual selection process.*/

/*Incase it does not create the react app at once, select React as your framework and continue with the commands below*/
```
- cd into your directory and install all dependencies.
```cmd
cd gpt-rqg-app
npm install
```
- Install React Bootstrap
```cmd
npm install react-bootstrap bootstrap
```
- Open the code editor from the command line. Since I use VSCode, I use this command to open the directory in my code editor.
```cmd
code .
```
- Return to the terminal and run the command below to kickstart your React app.
```cmd
npm run dev
```
- Back to the code editor, delete the default styles in the `index.css` file, the `app.css` and the `logo.svg` files, and create a new Components folder.
- Create a `QuoteBox.jsx` component file in the Components folder and enter the code below.
```jsx

import React from "react";
function QuoteBox({ generateQuote, onSelectChange, selectedValue }) {
  const quoteFilterOptions = [
    "Filter",
    "Inspiration",
    "Motivation",
    "Academic",
    "Religious",
    "Masculine",
    "Feminine",
  ];
  const quoteFilterOption = quoteFilterOptions.map((option, i) => {
    return option === "Filter" ? (
      <option value="" key={i} className="text-dark" disabled defaultValue>
        {option}
      </option>
    ) : (
      <option value={option} key={i} className="text-dark">
        {option}
      </option>
    );
  });
  const handleSelectChange = (e) => {
    onSelectChange(e.target.value);
  };
  return (
    <div className="col-md-6">
      <div className="h-100 p-5 text-white bg-dark rounded-3">
        <h2>Quote Of The Day</h2>
        <p>
          Swap the background-color utility and add a `.text-*` color utility to
          mix up the jumbotron look. Then, mix and match with additional
          component themes and more.
        </p>
        <div className="d-flex flex-row justify-content-between">
          <button
            className="btn btn-outline-light"
            onClick={generateQuote}
            type="button"
          >
            Generate
          </button>
          <select value={selectedValue} onChange={handleSelectChange} className="bg-transparent border rounded-3 text-white p-2">
            {quoteFilterOption}
          </select>
        </div>
      </div>
    </div>
  );
}
export default QuoteBox;

/* Code Explanation */

/*
The QuoteBox is responsible for rendering the generated quotes. It has a title text, a dummy quote placeholder, a button to generate quotes, and a dropdown filter to allow the user select the desired quote.
*/
```
- Clear the `App.jsx` file and enter the code below in it.
```jsx

import React, { useState, useEffect } from "react";
import QuoteBox from "./Components/QuoteBox";
function App() {
  const [selectedValue, setSelectedValue] = useState("");
  const generateQuote = () => {
    console.log("Quote generated.");
  };
  const handleSelectChange = (value) => {
    setSelectedValue(() => value);
  };
  useEffect(() => {
    console.log(selectedValue);
  }, [selectedValue]);
  return (
    <div className="d-flex justify-content-center align-items-center min-vh-100 px-2 sm:px-0">
      <QuoteBox
        generateQuote={generateQuote}
        onSelectChange={handleSelectChange}
        selectedValue={selectedValue}
      />
    </div>
  );
}
export default App;

/* Code Explanation */

/*
The App.jsx file is the parent component. It renders the QuoteBox component within it and implements all its functions and passes them as props. In here, the OpenAI ChatGPT API will be integrated.
*/
```
##Integrating the ChatGPT API
To increase the application of their AI, OpenAI released ChatGPT’s API for developers to integrate into their applications for a broad range of utilities like text completion, chat completion, code completion, image editing, fine-tuning, and many more. We will work with the chat completion model for our Random Quote Generator application. This model allows the users to send prompts to the AI and get the appropriate response. The OpenAI documentation helps us learn how to integrate and use ChatGPT’s API in our application. It may seem daunting to read as a beginner due to the numerous information available. Therefore, I have simplified the process and filtered out the unnecessary information in outlined steps in this section.
- Open OpenAI API’s documentation website on your browser
- Create an account if you do not have one, or log in
- Click the profile icon on the top right corner of the page and go to manage your account
- There, you get your usage stats and a free $18 credit to use the API
- Go to API keys, create a new API key and copy it.
- In your code editor, create a `.env` file and store your API key.
```env
VITE_APP_API_KEY = "yourapikey"; //since the app was scaffolded with vite
```
- Add the `.env` file to `.gitignore` to prevent others from accessing the API key.
- Create a new `script.js` file, import the key in it, and send a POST request to the ChatGPT’s API in a `quoteGenerator` function with the fetch API.
```javascript

import { API_KEY } from "../keys.js";

export function quoteGenerator(value) {
  return fetch("https://api.openai.com/v1/chat/completions", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${import.meta.env.VITE_APP_API_KEY}`,
    },
    body: JSON.stringify({
      model: "gpt-3.5-turbo",
      messages: [{ role: "user", content: `Generate a random ${value} quote` }],
    }),
  })
    .then((response) => response.json())
    .then((data) => data.choices)
    .catch((error) => console.error("Error:", error));
}

/* Code Explanation */

/* 
The quoteGenerator function sends a POST request to the OpenAI ChatGPT. 
It passes the API key generated in the header and a body specifying the prompt passed to ChatGPT. 
The function receives a value parameter which specifies the type of quote to be generated in the messages' array object key, content. 
The role specifies who's making the request. In this case, it is a user.
 */
```
- Import the `quoteGenerator` function in the `App.jsx`.
- Create a new useState hook for storing the quotes.
```jsx
const [quote, setQuote] = useState("Generate beautiful quotes...");
```
- Enter the following code in the `generateQuote` function.
```jsx

const generateQuote = () => {
    quoteGenerator(selectedValue)
      .then((choices) => {
        if (choices && choices.length > 0) {
          setQuote(choices[0].message.content);
          console.log("Quote generated.");
        } else {
          console.log("No quotes generated.");
        }
      })
      .catch((error) => console.error("Error:", error));
  
    console.log(selectedValue);
  };

/* Code Explanation */

/* 
Call the quoteGenerator function with an argument of selectedValue (selectedValue is a state storing the quote type in the filter dropdown).
Since the quoteGenerator function returns a promise, look into the returned value to check if it is empty or not.
If it is empty, log "No quote generated to the console". The QuoteBox retains a default text if no quote is generated.
Else, pick out the response and set it to quote using setQuote(choices[0].message.content);
*/
```
- Pass the new quote as a prop to the QuoteBox component and replace the dummy text within the `<p>` tag with the quote state.
- A new dummy text will be rendered if the quoteGenerator function does not return a new Quote or the user did not select any filter. Otherwise, the generated quote will be rendered.
```jsx

...
<p>
  {quote ? quote : "Generate beautiful quotes..."}
</p>
...
```
- Kickstart your application if you already cancelled it, or check the address where it is currently running on your browser and try to generate a quote. Here is my result.

![Random Quote Generator First Result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b4y7ag6m04k79vvz3og0.png)

Now, let us add more functionality to enable users to copy or share the quote on Twitter or WhatsApp.
##Adding Copy and Sharing Features
First, we will implement the **copy** feature using the clipboard API. The clipboard API allows developers to create buttons enabling users to copy texts from a website without dragging their mouse over them. 
###Copy Feature Steps
- Write this function in the QuoteBox component.
```jsx

const copyToClipboard = async () => {
    try {
      await navigator.clipboard.writeText(quote);
      alert("Quote copied to clipboard");
    } catch (err) {
      console.error("Failed to copy text: ", err);
    }
  };
```
- Modify the `<h2>` title tag to have a container. Place a clipboard link inside the container next to the title.
```jsx

...
<div className="d-flex flex-row justify-content-between align-items-center">
  <h2>Quote Of The Day</h2>
  <a onClick={copyToClipboard} className="clipboard">
    Copy Quote
  </a>
</div>
...
```

That is all for the copy feature. You may test it in the browser. Let us proceed with the share functionality.
###Share Feature Steps
- After the generate and filter buttons container, add these lines of code.
```jsx

<div className="socials mt-4">
  <a
    target="_blank"
    href={`https://twitter.com/intent/tweet?text=${quote}`}
    className="me-2"
  >
    Twitter
  </a>
  <a
    target="_blank"
    href={`https://api.whatsapp.com/send?text=${quote}`}
  >
    WhatsApp
  </a>
</div>

/* Code Explanation */

/*
The hrefs link to each respective social media sharing api with the current code dynamically appended as the text value
*/
```

The copy to clipboard and share functionalities are fully implemented, but we must replace the copy and share texts with icons and the alert function with a toast notification. They make our applications more mature.
- Install react-icons and react-toastify
```cmd
npm i react-icons --save
npm i react-toastify
```
- Import the icons you need (clipboard, Twitter, and WhatsApp icons) and the toast.
```jsx

import { FiClipboard } from "react-icons/fi";
import { RiWhatsappFill } from "react-icons/ri";
import { FaTwitter } from "react-icons/fa";
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
```
- Change the `alert("Quote copied to clipboard");` to `toast.sucess("Quote copied to clipboard");`.
```jsx
former

const copyToClipboard = async () => {
    try {
      await navigator.clipboard.writeText(quote);
      alert("Quote copied to clipboard"); //change here
    } catch (err) {
      console.error("Failed to copy text: ", err);
    }
  };

New

const copyToClipboard = async () => {
    try {
      await navigator.clipboard.writeText(quote);
      toast.success("Quote copied to clipboard"); //the change
    } catch (err) {
      console.error("Failed to copy text: ", err);
    }
  };
```
- Finally, modify the rendered component and add the `<ToastContainer />` to the top, so it appears from the top.
```jsx
return (
    <>
    <ToastContainer /> //new toast component here
    <div className="col-md-6">
      ...
    </div>
    </>
  );
```
- Save your changes and review your website again to try out these newly implemented features.

And there we go! We have successfully implemented the OpenAI ChatGPT's API in a Random Quote Generator application.
See the [GitHub repo](https://github.com/DrPrime01/gpt-rqg-app) to access the code and the [live link](https://gpt-rqg-hxpi3w3bt-drprime01.vercel.app/) to interact with the application.
##Conclusion
This tutorial successfully demonstrated the steps of incorporating the OpenAI ChatGPT API into a random quote generator application. We have developed a tool that can produce original, engaging, and thought-provoking quotes whenever needed by fusing the strength of AI with the simplicity of a quote generator.

We reviewed the crucial steps, including creating your API credentials, making API calls, managing response data, and showing users the generated quotes. Along the way, we explored crucial ideas like the share and copy to clipboard features.

By integrating ChatGPT into your projects, you can unlock new levels of creativity and functionality once thought out of reach and build unique projects.

For more tips, follow me on [Twitter](https://twitter.com/theDocWhoCodes), or reach out to me via [email](gabrielshoyombo2002@gmail.com).

Cover image attribution: https://unsplash.com/photos/7q-kE4SZzvQ?utm_source=unsplash&utm_medium=referral&utm_content=creditShareLink