Construct a ChatGPT web demonstration page using Laf
Tags: chatgpt, serverless, faas, typescript
Published: 2023-03-27 12:36:25

OpenAI has released the official ChatGPT API, powered by their newest model gpt-3.5-turbo, which is their most advanced model yet, with faster response times and cheaper pricing.

As developers, we want to integrate ChatGPT and related models into our own products and applications through the API. However, due to access restrictions, we need to use various API proxy services to access the ChatGPT API indirectly.

Even if we solve the API access problem, we still need to prepare a development environment, such as a Node.js environment for a Node.js client.

Is there a simple and fast way to call the ChatGPT API?

**We can use Laf.**

Laf is a fully open-source cloud development platform that provides out-of-the-box capabilities such as cloud functions, cloud databases, and object storage, allowing you to write code like writing a blog post.

> GitHub: **https://github.com/labring/laf**

If you want to quickly learn how to use Laf, you can refer to this article: [Learn Laf in Three Minutes](https://zuofeng59556.github.io/my-blog/pages/quickStart/laf/).

Now, let's start the timer and use Laf to implement our own ChatGPT in three minutes!

> Prerequisite: You need to have a ChatGPT account and generate an API Key (you can search on Google for this).

## Cloud Function Tutorial

First, log in to [laf.dev](https://laf.dev/) and create a new application.

![](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-27-18-39-hzELHb.png)

Click the "Develop" button to enter the development page.

![](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-27-18-42-UwEWtp.png)

In the NPM Dependence panel, click the `+` in the upper right corner:

![](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-27-18-46-fUtTj2.png)

Then enter "chatgpt" and press enter to search, select the first search result, and click "save and restart":

![](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-27-18-47-h1zrwt.png)

After the restart, "chatgpt" will appear in the custom dependency items.

![](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-27-18-48-ToRLw5.png)

Now, create a new cloud function named **send** and write the following code:

```typescript
import cloud from '@lafjs/cloud'
export async function main(ctx: FunctionContext) {
  const { ChatGPTAPI } = await import('chatgpt')
  const api = new ChatGPTAPI({ apiKey: cloud.env.CHAT_GPT_API_KEY })

  let res = await api.sendMessage('"鸡你太美" refers to which male artist in mainland China? Here\'s a hint: he likes to sing, dance, play basketball, and rap.')
  console.log(res.text)

  return res.text
}
```

API Key is passed through the environment variable `CHAT_GPT_API_KEY`, so we also need to create an environment variable. Click the settings icon in the lower left corner:

![img](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-11-18-38-ydsD8h.png)

Select "Environment Variable" --> "Add Environment Variables" in turn, enter the name and value of the environment variable, and click "OK", then click "Update", and the application will be restarted.

![](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-27-18-57-SsikP3.png)

Now click "Run" in the upper right corner to debug and run.

![](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-27-19-00-7linkX.png)

Perfect! Now let's try adding the **context tracking** feature. It's actually quite simple, just pass in the ID of the previous message during the conversation. Here's the code:

```typescript
import cloud from '@lafjs/cloud'
export async function main(ctx: FunctionContext) {
  const { ChatGPTAPI } = await import('chatgpt')
  const api = new ChatGPTAPI({ apiKey: cloud.env.CHAT_GPT_API_KEY })

  let res = await api.sendMessage('"鸡你太美" refers to which male artist in mainland China? Here\'s a hint: he likes to sing, dance, play basketball, and rap.')
  console.log(res.text)

  // Pass in parentMessageId to track context
  res = await api.sendMessage('No, his surname is Cai. Please answer again.', {
    parentMessageId: res.id
  })
  console.log(res.text)

  return res.text
}
```

Let's run it and see:

![](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-27-19-03-1vAZA8.png)

Amazing! They got the answer right on the second try!

Okay, let's start the timer now, as the tutorial is finished and we are ready to implement our ChatGPT.

## Cloud Function

Now we can start building our own ChatGPT. First, replace the function from the previous section with the following code:

```typescript
import cloud from '@lafjs/cloud'

export async function main(ctx: FunctionContext) {
  const { ChatGPTAPI } = await import('chatgpt')
  const data = ctx.body

  // Put the api object into cloud.shared so that we can track context
  let api = cloud.shared.get('api')
  if (!api) {
    api = new ChatGPTAPI({ apiKey: cloud.env.CHAT_GPT_API_KEY })
    cloud.shared.set('api', api)
  }

  let res
  // If parentMessageId is passed in from the front-end, it means we need to track context
  if (!data.parentMessageId) {
    res = await api.sendMessage(data.message)
  } else {
    res = await api.sendMessage(data.message, { parentMessageId: data.parentMessageId })
  }
  return res
}
```

Now it should be easy to understand this function, right?

## Front-end

We need a front-end page for our Web version of ChatGPT. First, we need to install the Laf SDK:

```bash
$ npm install laf-client-sdk
```

Next, we need to create a `cloud` object:

```typescript
import { Cloud } from "laf-client-sdk"; 

// Create a cloud object, replace <appid> with your own App ID
const cloud = new Cloud({
  baseUrl: "https://<appid>.laf.dev",
  getAccessToken: () => "", // No need for authorization here, leave it blank for now
});
```

Now let's take a look at the core code of the front-end, which is very simple, just pass the question and context ID to the cloud function:

```typescript
async function send() {

  // The question we are asking
  const message = question.value;

  let res;
  // Same logic as the cloud function, pass in context ID if there is one
  if (!parentMessageId.value) {
    res = await cloud.invoke("send", { message });
  } else {
    res = await cloud.invoke("send", { message, parentMessageId: parentMessageId.value });
  }

  // The answer to our question is in res.text

  // This is the context ID
  parentMessageId.value = res.id;
}
```

With a **little** bit of additional detail, we can make it look like this:

![](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-27-19-06-SYTCr2.png)

After adding these details, the basic development work is done. Now it's time to deploy the project and share it with your friends, and maybe have a drink or two.

Speaking of deployment, we should now go buy a server, install Nginx, configure Nginx, set up domain name resolution, bind the domain name...

**NO NO NO, I don't allow you to waste your young and beautiful life. Life is short, you need Laf. 😃**

## Deploy

Open your Laf and navigate to the storage interface. Click on the "+" sign above and create a storage bucket with read-only permissions (you can choose any name).

![](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-27-19-20-xs8Usu.png)

After creating the bucket, run the build command in your front-end project (I used `npm run build`).

Once the build is complete, locate the `dist` folder and upload everything inside it to the storage bucket you just created, just as I did. Remember to upload everything as is, files are files, and folders are folders.

![](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-27-19-21-UmfB9S.png)

Once the upload is complete, you will notice an option in the top right corner to "Enable website hosting". Click on it!

![](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-27-19-23-1VWBAp.png)

After clicking, a link will appear. Click on it to see what it is.

![](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-27-19-24-X1U4ts.png)

Oh my goodness! Isn't this the project I just developed?!

![](https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting5@main/uPic/2023-03-27-19-25-MlxmPl.png)

Congratulations! Your project is now online. Share it with your friends!

------

- Project source code: [https://github.com/zuoFeng59556/chatGPT](https://github.com/zuoFeng59556/chatGPT)
- Example website: [https://lafai.io/](https://lafai.io/)