DEV Community

Cover image for Innovative Ways to Use ChatGPT's API: Building a Random Quote Generator
DrPrime01
DrPrime01

Posted on

Innovative Ways to Use ChatGPT's API: Building a Random Quote Generator

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.
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*/
Enter fullscreen mode Exit fullscreen mode
  • cd into your directory and install all dependencies.
cd gpt-rqg-app
npm install
Enter fullscreen mode Exit fullscreen mode
  • Install React Bootstrap
npm install react-bootstrap bootstrap
Enter fullscreen mode Exit fullscreen mode
  • Open the code editor from the command line. Since I use VSCode, I use this command to open the directory in my code editor.
code .
Enter fullscreen mode Exit fullscreen mode
  • Return to the terminal and run the command below to kickstart your React app.
npm run dev
Enter fullscreen mode Exit fullscreen mode
  • 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.

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.
*/
Enter fullscreen mode Exit fullscreen mode
  • Clear the App.jsx file and enter the code below in it.

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.
*/
Enter fullscreen mode Exit fullscreen mode

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.
VITE_APP_API_KEY = "yourapikey"; //since the app was scaffolded with vite
Enter fullscreen mode Exit fullscreen mode
  • 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.

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.
 */
Enter fullscreen mode Exit fullscreen mode
  • Import the quoteGenerator function in the App.jsx.
  • Create a new useState hook for storing the quotes.
const [quote, setQuote] = useState("Generate beautiful quotes...");
Enter fullscreen mode Exit fullscreen mode
  • Enter the following code in the generateQuote function.

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);
*/
Enter fullscreen mode Exit fullscreen mode
  • 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.

...
<p>
  {quote ? quote : "Generate beautiful quotes..."}
</p>
...
Enter fullscreen mode Exit fullscreen mode
  • 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

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.

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

...
<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>
...
Enter fullscreen mode Exit fullscreen mode

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.

<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
*/
Enter fullscreen mode Exit fullscreen mode

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
npm i react-icons --save
npm i react-toastify
Enter fullscreen mode Exit fullscreen mode
  • Import the icons you need (clipboard, Twitter, and WhatsApp icons) and the toast.

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';
Enter fullscreen mode Exit fullscreen mode
  • Change the alert("Quote copied to clipboard"); to toast.sucess("Quote copied to clipboard");.
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);
    }
  };
Enter fullscreen mode Exit fullscreen mode
  • Finally, modify the rendered component and add the <ToastContainer /> to the top, so it appears from the top.
return (
    <>
    <ToastContainer /> //new toast component here
    <div className="col-md-6">
      ...
    </div>
    </>
  );
Enter fullscreen mode Exit fullscreen mode
  • 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 to access the code and the live link 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, or reach out to me via email.

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

Oldest comments (0)