Building a Twilio-Powered App with Next.js and OpenAI GPT-3.
Published: 2024-02-13 11:17:11

In this article, you will learn how to create a Twilio-powered app with OpenAI’s GPT-3 using Twilio Programmable SMS. The app will be created using Next.js. Next.js is a powerful React framework that comes with its server-side functions and also has API routes that are used to handle HTTP requests between the server and client. Next.js is fully capable of handling both front-end and back-end functionalities and communication.

## Project Overview 
In this article, the project we will be building is a Meeting Invite app. We will use Next.js to create both the front-end and back-end due to its server-side and client-side capabilities. We will also make use of the [OpenAI](https://platform.openai.com/docs/guides/gpt) GPT-3 text-Davinci-003 engine, to generate the meeting text body and finally, we will make use of the [Twilio Programmable SMS](https://www.twilio.com/docs/sms/api) API to send SMS messages to the desired phone numbers. You can get the whole project from [GitHub](https://github.com/temidd/Twilio-powered-app-using-Nextjs-OpenAI-GPT-3) and follow along. Though we will go through all the steps to build the project. 

## Prerequisites
In other to go ahead with the article you will need the following:
Visual Studio code editor
* A [Twilio](https://www.twilio.com/try-twilio) account
* An [OpenAI](https://openai.com/) account
* [React-phone-number-input](https://www.npmjs.com/package/react-phone-number-input)
* OpenAI Api key
* Twilio

With all that stated let's begin creating the app.

## Working on the front end
The first step is to create the front end but before that here is a snapshot of the project below.

![Frontend view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/24x8z00811b72wpz8r23.png)
The front end is not the most beautiful but it will do for our project.
In other to create the Next.js app, you have to use the following command:

```
npx create-next-app meeting-invite-app
```
Next, we will also install the other libraries we need.
```
npm  install twilio openAiApi react-phone-numbers-input
```

Or if you cloned from the repo you can use the command `npm install`.

After installing the necessary dependencies, open the Next.js app in VS code. 
Then open the `index.js` file located in the pages folder and write the following code:
First, import PhoneNumber from react-phone-number-input,
import PhoneNumber from 'react-phone-number-input'

Next, input the following lines of code:

```
<div className={styles.container}>
  <Head>
    <title>Create Next App</title>
    <meta name="description" content="Generated by create next app" />
    <link rel="icon" href="/favicon.ico" />
  </Head>

  <div className={styles.formContent}>
    <div className={styles.header}>
      <h1>Meeting Inviter</h1>
    </div>

    <div>
      <form className={styles.inputForm} onSubmit={sendData} method="POST">
        <input
          className={styles.input}
          type="text"
          name="employeeName"
          placeholder="Name of employee"
          onChange={(e) => setEmployeeName(e.target.value)}
        />
        <PhoneInput
          className={styles.phoneNumber}
          placeholder="Enter Employee number"
          value={phoneNumber}
          onChange={setValue}
        />
        <input
          className={styles.input}
          type="text"
          name="messageBody"
          placeholder="Enter meeting title"
          onChange={(e) => setTitle(e.target.value)}
        />
        <textarea
          className={styles.textArea}
          placeholder="Enter meeting descreiption"
          rows="20"
          cols="50"
          onChange={(e) => setMessageBody(e.target.value)}
        />
        <button className={styles.button} type="submit">
          Send
        </button>
      </form>
      <div>{sent && <div className={styles.alert}>Message sent</div>}</div>
    </div>
  </div>
</div>;
```


The code above is used to create a simple form for our front end and in the code you will notice some functions used to get the values from our form. Those functions are the state functions and we haven’t imported our `useState` hook to handle them. To do so we have to import the `useState` hook and destructure it as follows:

```
import { useState } from "react";

const [employeeName, setEmployeeName] = useState("");
const [phoneNumber, setValue] = useState("");
const [title, setTitle] = useState("");
const [messageBody, setMessageBody] = useState("");
```

Now the front end is okay the only thing remaining is to add a CSS file. You can do that by importing the CSS module into the index file.

```
import styles from '../styles/Home.module.css'
```

After that, you can run the file with `npm run dev`.
### Getting and sending form data
Now that we have our front end we have to work on how to get our data from the form and send it to the Next.js backend which is the API route. In other to do that since the states have already been created, we need a function to get the values from the states and send them to the specific `API` route which will handle the data. If you look at the code above we, inside the form element, there is an `onSubmit` and a `method` property that will run the `sendData` function and set the HTTP request method to POST. 
Now you have to create the `sendData` function by writing the following code:

```
const sendData = async (event) => {
  event.preventDefault();
  // get data from the react state hooks
  const data1 = {
    name: employeeName,
    messageTitle: title,
    message: messageBody,
  };
  const mainObject1 = JSON.stringify(data1);
  const endPoint1 = "/api/textAI";
  //Set the parameters to be sent to the textAI api route
  const params1 = {
    method: "POST",
    body: mainObject1,
  };

  //Get the response sent back from textAI API route
  const response = await fetch(endPoint1, params1);

  const myData = await response.json();
  const { textData } = myData;

  console.log(`This data is from openAIApi: ${textData} `);
};

```

The code above is a function that gets the name,  message title, and message from the state hooks and sends them as part of the object body to the `textAI.js` API route. The function also handles the response which is from the API route.

We still have another API routes to handle in the code,  which is the data.js API route. In other to handle the request and response write the following code in the same function below the last line of code above:

```
//Get the data to be sent to the data.js api route
const data2 = {
  number: phoneNumber,
  text: textData,
};

const mainObject2 = JSON.stringify(data2);
const endPoint2 = "api/data";

//Set the parameters to be sent to the data api route
const params2 = {
  method: "POST",
  body: mainObject2,
};
//Get the response from the data api route
const response2 = await fetch(endPoint2, params2);
const myData2 = await response2.json();
console.log(
  `This is the Twilio response to the frontend: ${JSON.stringify(myData2)} `,
);
```

The code above gets the number and the generated output text gotten from the `textAI.js` API route and sends it to the `data.js` API route which also sends back a response to the front end.

The function `sendData` is called when the send button is clicked. 

## Working on the API routes
Now that the function `sendData` is created on the front end, let us set work on the API routes that will handle the data gotten from the front end and send back a response to the back end. This is where the main app functionality will occur.
We will create two API routes named:
* textAI.js
* data.js
You can name your API any name you like. But for this article let us stick to the names above.
You might wonder, what do `textAI.js` and `data.js` do? 
Well, `textAI.js` is the API route that handles the data gotten from the front end and sends it to the OpenAI to generate text and then send it back to the front end as a response.
 
While `data.js` gets the generated text and the phone number from the front end and makes an API call to Twilio and Twilio then sends the generated text to the phone number.
Now let us work on our api route. To do so, enter into the pages folder, inside the folder enter into the `api` folder then create two files named `text.js` and `data.js`.
After creating the files, go to your terminal or shell and install the Twilio and OpenAI library using the command:

```
npm install twilio openai
```
Also, you need an environment variable to store your API keys. To create it, in the root directory of your next js app create a file named `.env.local` this file will hold all your API keys.



### Making an API call to OPenAI
Now, let us make an API call to OpenAI. To do so you have to import the OpenaiAPI from the `openai` library and also configure it to initialize your API key. Inside the `textAI.js` file write the following code:

```
import { Configuration, OpenAIApi } from "openai";
export default async function postMethod(req, res) {
  const { name, message, messageTitle } = JSON.parse(req.body);
  const configuration = new Configuration({
    apiKey: process.env.openAiKey,
  });
  const openai = new OpenAIApi(configuration);
}

```

The code above enables you to make use of the OpenAI library. You will need to import `OpenAIApi` and Configuration functions from the `openai` library. The configuration method enables you to configure the `openai` library to use your API key.
While the `OpenAIApi` function enables you to initialize the configuration which holds the API key. 

Next, you need to get the data coming from the request body of the front end and send it for text generation and also send back a response by writing the following code inside the `postMethod` function:

```
//Edit the message to send to OpenAI
const prompt = `${message} to ${name} with title ${messageTitle}`;
try {
  //Send the prompt with the necessary parameters
  const response = await openai.createCompletion({
    model: "text-davinci-003",
    prompt,
    temperature: 0,
    max_tokens: 100,
    n: 1,
  });
  //Get the response from OpenAI GPT-3
  const textOutput = response.data.choices;
  const textData = textOutput[0].text;
  console.log(textOutput);
  console.log("main data: ", textData);
  //Send a response back to the front end
  res.status(200).json({ textData });
} catch (error) {
  console.error(error);
  res.status(500).json({ error: "An error occured while fetcing from openAI" });
}
```

In the code above the function `openai.createCompletion` was used to add the parameters and make a call to GPT-3 `text-DaVinci-003` engine. This engine or model is used to generate text based on input. The input is structured as in a string literal and assigned to the variable prompt.
`Prompt` is the input that is sent to GPT-3 for text generation.
Temperature is the amount of randomness set. 
`Max_tokens` represents the number of units of inputs or outputs that can be generated. `n` refers to the number of tokens.

If you run the app you will get the generated text from OpenAI GPT-3. It was destructured in the sendData function in index.js and set to the generatedText state.

Sending the message using Twilio API
This is another main part of the application. Here you have to request the Twilio API to send the generated text to the recipient's phone number. 
In other to do this, open the `data.js` file and import the Twilio library using the code:

```
import twilio from "twilio";
```

After that, you need to get your `Twilio API key` and `accountSID`. Also, make sure you put them in the `.env.local` file.

```
const authToken = process.env.AuthToken;
const accountSID = process.env.AccountSID;
const client = twilio(accountSID, authToken);
```
Next, you need to write the code to make the call to Twilio.

```
//Get the data from the front-end request body
const { number, text } = JSON.parse(req.body);
//Send the text
client.messages
  .create({
    from: "+13157125351",
    to: number,
    body: text,
  })
  //Send back a response
  .then((message) => {
    res.status(200).json({ messageSId: message.sid });
  })
  .catch((err) => {
    res.status(500).json({ err: err.message });
  });
```



You use the function `client.messages.create()` to tell the Twilio API to send a message to the recipient. Inside the function there is an object parameter as follows:
* From
* To
* Body
The `from` object property is used to set your Twilio number. You get a Twilio number once you sign up for Twilio. The number will be able to send SMS messages and also place calls.
The `to` object property is used to set the destination number to receive the message. It should contain the recipient's number.
And the `body` object is used to set the message to be sent to the recipient. 

> Note: Do not omit any of the parameters else it won’t send.

The above code will look like the one below:

```
import twilio from "twilio";
export default async function postMethod(req, res) {
  const authToken = process.env.AuthToken;
  const accountSID = process.env.AccountSID;
  const client = twilio(accountSID, authToken);
  //Get the data from the front-end request body
  const { number, text } = JSON.parse(req.body);
  //Send the text
  client.messages
    .create({
      from: "+13157125351",
      to: number,
      body: text,
    })
    //Send back a response
    .then((message) => {
      res.status(200).json({ messageSId: message.sid });
    })
    .catch((err) => {
      res.status(500).json({ err: err.message });
    });
}
```


After writing the code above, we just have to add one thing to our front end which is to show a text when the message is successfully sent. 
To do that,  we have to create a div that will show the text `message sent` You can add styles to it though, but you don't need to worry the GitHub repository with the complete styles used for this project will be added. 
To make the message pop up we need to do what is called conditional rendering. To do so, open the `index.js` file, create a state to handle the rendering;

```
const [sent, setSent] = useState(false);
```
Inside the sendData function at the bottom, add the following code:
```
const { err } = myData2;
if (!err) {
  setSent(true);
}
```

Then below the form element add the following code:

```
<div>{sent && <div className={styles.alert}>Message sent</div>}</div>;
```

After that, you can run the entire app using the command `npm run dev`. You will get a similar one to the one below;

![Initial view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vqfatxzwpxg9q9q26fdq.png)

![Form input](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tknkt6nxpbrb4xd2ye3s.png)

![console message](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eu76nep1fti7kxylygc5.png)

Conclusion
In this article, you learned to build a Twilio-powered app using Next.js and OpenAI GPT-3. The app can send text generated from GPT-3 and send it to the recipient’s phone number by using Twilio Programmable SMS. 
Remember in other to use the Twilio programmable SMS you have to create an account on [Twilio](https://www.twilio.com/try-twilio). When you create an account you get a phone number and free credits. In case the free credits are exhausted or maybe your free trial expires you have to then upgrade to a paid plan. With the paid plan you get even more capabilities. 
You can also check the [Twilio programmable SMS API](https://www.twilio.com/docs/sms/api) for more information and also check out OpenAI API documentation for more information on how to use their API.