Back to APIs list

ChatGPT API examples & templates

Use these vals as a playground to view and fork ChatGPT API examples and templates on Val Town. Run any example below or find templates that can be used as a pre-built solution.

inTheBackground

With the addition of the "early return" feature of web handlers, you can now process short background tasks in vals. This can be really useful for occasions where an immediate response is required, with a subsequent update a few seconds later

e.g. a Discord bot that calls ChatGPT needs to respond within a few seconds, which can be too fast for the AI to generate a response. We can instead reply immediately and then update that message later, inTheBackground

Simply wrap something in inTheBackground and it will do just that! In this example, we log something a few seconds later than the web response is sent back.

Readme
Fork
1
2
3
4
5
6
7
8
9
10
import { inTheBackground } from "https://esm.town/v/neverstew/inTheBackground";
import { sleep } from "https://esm.town/v/neverstew/sleep";
export default async function(req: Request): Promise<Response> {
inTheBackground(async () => {
await sleep(3000);
console.info(new Date());
});
return Response.json({ time: new Date() });
}

Val Town inspiration & use cases list

This list is fairly out of date. I'd love to accept pull requests with new or better vals!

Readme
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
export let valTownInspoList = [{
"title": "What can I make in Val Town?",
"description": "The data for this page was created by using Val Town as a CMS",
"val": "@rodrigotello.valTownInspoList",
image:
"https://air-prod.imgix.net/abff23bf-fc18-485f-a6b5-4a1c8b7f91ec.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
"title": "NASA photo of the day.",
"description": "Returns NASA's Astronomy Picture of the Day (APOD)",
"val": "@rodrigotello.nasaAPOD",
"image":
"https://air-prod.imgix.net/11ab8b2e-c052-4574-8341-96d5d74040cc.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
"title": "hnFollow",
"description": "Get email notifications any time an author you follow posts in Hacker News.",
"val": "@rodrigotello.hnFollow",
"image":
"https://air-prod.imgix.net/61e08fed-c77e-4a7b-9ae5-1efabb349574.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
"title": "GitHub events",
"description": "Get a GithHub users' public events",
"val": "@stevekrouse.githubEvents",
image:
"https://air-prod.imgix.net/3545d2cb-7cae-49d9-98b7-832428d2af34.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
"title": "Twitter alerts",
"description": "Track Twitter mentions and be alerted via email",
"val": "@stevekrouse.twitterAlert",
image:
"https://air-prod.imgix.net/4c81af31-0832-4c72-8afb-34ef23fa03c9.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
"title": "Air quality",
"description":
"Get email alerts when the air quality is bad. Val created with much help from @russbiggs (Director of Technology at OpenAQ)",
"val": "@stevekrouse.aqi",
image:
"https://air-prod.imgix.net/1a21321c-2bb7-4aa8-8c26-eb58cf1787a2.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
"title": "Annoy friends in Bluesky",
"description": "ChatGPT powered bot for the sole purpose of annoying friends on Bluesky.",
"val": "@ajax.annoy",
image:
"https://air-prod.imgix.net/d21d3c1f-99e9-4356-85ed-bc6d7746c867.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
"title": "Venue calendar",
"description": "Get a venue calendar through Resy",
"val": "@rlesser.Resy_getVenueCalendar",
image:
"https://air-prod.imgix.net/cab68838-bc60-48a2-8b00-50f203ac303d.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
Fork
1
2
// set at Thu Nov 30 2023 14:22:53 GMT+0000 (Coordinated Universal Time)
export let topHNThreadByHour = ["Top thread on Hackernews for 3:00 is: Vespa.ai is spinning out of Yahoo as a separate company","Top thread on Hackernews for 4:00 is: President Speaking: Spoofing Alerts in 4G LTE Networks (2019) [pdf]","Top thread on Hacke

Get a response from GPT for the player.

Readme
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { getRandomIndex as getRandomIndex2 } from "https://esm.town/v/ktodaz/getRandomIndex";
import { getRandomValue } from "https://esm.town/v/ktodaz/getRandomValue";
import { runVal } from "https://esm.town/v/std/runVal";
export const getGPTResponse = async (
playerName: string,
playerRank: number,
highestPlayer: string,
) => {
const getRandomIndex = getRandomIndex2;
const gpt = async () => {
let message = `${playerName}, you made it to #${playerRank} on the server. `;
if (playerRank == 1) {
if (Math.random() < 0.6) {
return `#1: ${(await runVal("patrickjm.gpt3", {
prompt: getRandomValue([
`Write a short poem about the best hell let loose player named ${playerName}. Hell Let Loose is a WW2 game. Do not include new line characters.`,
`Write a short rap about being the #1 player named ${playerName}. Do not label sections of the song. Do not include new line characters. between versus add a "."`,
`Write a short love letter to the #1 player named ${playerName}. Make the letter from "ChatGPT". End the letter with a surprise insult. Do not include new line characters.`,
]),
}))}`;
}
message += getRandomValue([
"Remember: If you're not first, you're last.",
"Everyone loves you.",
"You are beautiful and amazing.",
"The Hell Let Loose gods have shined upon you today.",
"Don't get too cocky now ;)",
"Time to get outside ;)",
]);
}
if (playerRank == 2) {
if (Math.random() < 0.6) {
return `#2: ${(await runVal("patrickjm.gpt3", {
prompt: getRandomValue([
`Write a short poem about the second best hell let loose player named ${playerName}. The best player is ${highestPlayer}. Hell Let Loose is a WW2 game. Do not include new line characters.`,
`Write a short rap about being the #2 player named ${playerName}. The #1 player is ${highestPlayer}. Do not label sections of the song. Do not include new line characters. between versus add a "."`,
`Write a very short love letter to the #2 player named ${playerName}. The #1 player is ${highestPlayer}. Make the letter from "${highestPlayer}". End the letter with End the letter with a surprise insult. Do not include new line characters.`,
`Write a very short break-up letter to the #2 player named ${playerName}. The #1 player is ${highestPlayer}, who you are pursuing. Make the letter from "ChatGPT". Do not include new line characters. Provide some reasons for the breakup.`,
]),
}))}`;
}
message += getRandomValue([
`${highestPlayer} beat you.`,
`${highestPlayer} is the number one, you are number 2.`,
`Remember: If you're not first, you're last. Especially since ${highestPlayer} is #1`,
"The Hell Let Loose gods have shined upon you today.",
"Don't get too cocky now ;)",
"Time to get outside ;)",
]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import { fetch } from "https://esm.town/v/std/fetch";
import process from "node:process";
export let getChatgpt = async ({ prompts, token }) => {
let text = "";
const postdata = {
model: "text-davinci-003",
prompt: `${prompts}`,
temperature: 0.7,
n: 1,
logprobs: null,
max_tokens: 1024,
};
const headers = {
"Content-Type": "application/json",
// Update your token in https://val.town/settings/secrets
Authorization: `Bearer ${token || process.env.openaiKey}`,
};
const getCompelitoins = async (data) => {
const response = await fetch("https://api.openai.com/v1/completions", {
method: "POST",
headers: {
...headers,
},
body: JSON.stringify(data),
});
const result = await response.json();
return result;
};
const data = await getCompelitoins(postdata);
// console.log(data);
if (data?.error?.type === "server_error") {
return data.error.message;
}
// return data.choices[0].text;
return data.choices;
};
1
2
3
export function myApi(name) {
return "hi " + name;
}
1
2
3
4
export let constructChatGPTMessage = (role, content) => {
let formattedMessage = { role: role, content: content };
return formattedMessage;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
export let valTownInspoList = [{
"title": "What can I make in Val Town?",
"description":
"The data for this page was created by using Val Town as a CMS",
"val": "@tmcw.valTownInspoList",
image:
"https://air-prod.imgix.net/abff23bf-fc18-485f-a6b5-4a1c8b7f91ec.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
"title": "NASA photo of the day.",
"description": "Returns NASA's Astronomy Picture of the Day (APOD)",
"val": "@rodrigotello.nasaAPOD",
"image":
"https://air-prod.imgix.net/11ab8b2e-c052-4574-8341-96d5d74040cc.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
"title": "hnFollow",
"description":
"Get email notifications any time an author you follow posts in Hacker News.",
"val": "@rodrigotello.hnFollow",
"image":
"https://air-prod.imgix.net/61e08fed-c77e-4a7b-9ae5-1efabb349574.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
"title": "GitHub events",
"description": "Get a GitHub users' public events",
"val": "@stevekrouse.githubEvents",
image:
"https://air-prod.imgix.net/3545d2cb-7cae-49d9-98b7-832428d2af34.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
"title": "Twitter alerts",
"description": "Track Twitter mentions and be alerted via email",
"val": "@stevekrouse.twitterAlert",
image:
"https://air-prod.imgix.net/4c81af31-0832-4c72-8afb-34ef23fa03c9.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
"title": "Air quality",
"description":
"Get email alerts when the air quality is bad. Val created with much help from @russbiggs (Director of Technology at OpenAQ)",
"val": "@stevekrouse.aqi",
image:
"https://air-prod.imgix.net/1a21321c-2bb7-4aa8-8c26-eb58cf1787a2.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
"title": "Annoy friends in Bluesky",
"description":
"ChatGPT powered bot for the sole purpose of annoying friends on Bluesky.",
"val": "@ajax.annoy",
image:
"https://air-prod.imgix.net/d21d3c1f-99e9-4356-85ed-bc6d7746c867.jpg?w=1200&h=2000&auto=compress&ixlib=react-9.5.4",
}, {
"title": "Venue calendar",
"description": "Get a venue calendar through Resy",
"val": "@rlesser.Resy_getVenueCalendar",
1
2
3
4
5
export async function handleChatGPTRequest(req: express.Request, res) {
console.log(req.body);
console.email("Ran");
res.end("Success");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
export let openaiOpenAPI = `
openapi: 3.0.0
info:
title: Val Town API
description: |
The Val Town API provides services to evaluate JavaScript and TypeScript expressions, run vals as APIs, either as functions or Express handlers.
Learn more at [https://docs.val.town](https://docs.val.town)
version: 1.0.0
servers:
- url: https://stevekrouse-chatgptplugin.express.val.run
description: Val Town API v1
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: API Key
schemas:
JSON:
oneOf:
- type: string
- type: number
- type: object
- type: array
items: {}
- type: boolean
description: "Can be anything: string, number, array, object, etc., including \`null\`"
parameters:
expression:
in: path
name: expression
required: true
description: |
The JavaScript or TypeScript expression to be evaluated.
This should be a single expression, like a single function
call, assignment operation, or calculation. If you need
to execute multiple expressions, wrap them in a function.
schema:
type: string
examples:
simpleAddition:
value: "1+1"
summary: Simple addition
functionCall:
value: "@stevekrouse.addOne(@stevekrouse.example1)"
summary: Calling a user's val function
handle:
name: handle
1
2
3
4
5
6
7
8
9
10
11
12
13
import { chatGpt } from "https://esm.town/v/patrickjm/chatGpt?v=3";
export const chatGptUnoCss = chatGpt({
messages: [
{
role: "user",
content:
"Why would one want to use unocss instead of other css styling solutions, like bootstrap?",
},
],
})
.then((msg) => msg.content.split("\n").filter((line) => line.length));
// Forked from @patrickjm.chatGptExample
1
2
3
4
5
6
7
8
import { runVal } from "https://esm.town/v/std/runVal";
export function promptChatGPT(prompt) {
const gptResponse = runVal("patrickjm.gpt3", {
prompt: prompt,
});
return gptResponse;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { fetch } from "https://esm.town/v/std/fetch";
import process from "node:process";
export let newChatGPT35 = async ({ req, res }) => {
const postData = {
model: "gpt-3.5-turbo",
messages: [
{ role: "system", content: "You are a powerful chatGPT assistant." },
{
role: "user",
content: "请介绍一下你自己",
},
],
};
const getCompletion = async () => {
const response = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.openaiKey}`,
},
body: JSON.stringify(postData),
});
const data = await response.json();
return data;
};
const data = await getCompletion();
res.json(JSON.stringify(data.choices[0].message.content));
};

Self Editing Website - GPT Version

Visit and ask ChatGPT to edit the site at: https://maxm-selfeditingwebsitegpt.web.val.run/

Readme
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { gpt4 } from "https://esm.town/v/maxm/gpt4";
import { set } from "https://esm.town/v/std/set?v=11";
let { selfEditingWebsiteBodyGPT } = await import("https://esm.town/v/maxm/selfEditingWebsiteBodyGPT");
export const selfEditingWebsiteGPT = async (request: Request) => {
if (request == null) {
return "not invoked correctly";
}
// Otherwise, someone has submitted a form so let's handle that
if (selfEditingWebsiteBodyGPT === undefined) {
let defaultBody = `<h1>Edit Me!</h1>`;
selfEditingWebsiteBodyGPT = defaultBody;
await set("selfEditingWebsiteBodyGPT", selfEditingWebsiteBodyGPT)
}
if (request.method == "POST") {
let formData = await request.formData();
if (formData.get("edit") !== undefined) {
const editRequest = formData.get("edit").toString()
let resp = await gpt4(`The current HTML page source is`+"````"+`
${selfEditingWebsiteBodyGPT}
`+"````"+`
Replying to this prompt only with html, change the HTML page source to meet the following request: "${editRequest}"`)
// @me.selfEditingWebsiteBodyGPT = resp.choices[0].text;
selfEditingWebsiteBodyGPT = resp;
await set("selfEditingWebsiteBodyGPT", selfEditingWebsiteBodyGPT)
}
}
let body = selfEditingWebsiteBodyGPT;
const form = `
<div style="border: 1px solid #999;">
<form action="" method="POST">
<label for="edit">Describe how you want the new page to look and ChatGPT will make the change for you.</label>
<input type=text id="edit" name="edit" required />
<br>
<input type="submit" value="Submit" />
</form>
</div>`;
return new Response(
`<!DOCTYPE html>
<html>
<head>
<title>I am a self-editing website!</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.15/codemirror.min.js" integrity="sha512-2359y3bpxFfJ9xZw1r2IHM0WlZjZLI8gjLuhTGOVtRPzro3dOFy4AyEEl9ECwVbQ/riLXMeCNy0h6HMt2WUtYw==" crossorigin="anonymous" referrerpolicy="no-referrer"></s
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.15/codemirror.min.css" integrity="sha512-uf06llspW44/LZpHzHT6qBOIVODjWtv4MxCricRxkzvopAlSWnTf6hpZTFxuuZcuNE9CBQhqE0Seu1CoRk84nQ==" crossorigin="anonymous" referrerpolicy=
</head>
<body>
${body}
${form}
1
2
3
4
5
6
7
8
9
10
11
12
13
import { chatGPT } from "https://esm.town/v/maxdrake/chatGPT";
export let chatGPTExample = async (API_KEY) => {
let repsonse_obj = await chatGPT(
"hello assistant",
[], // this can be an empty list, or if you're using this to continue a conversation, you can pass in someting of the form: https://platform.openai.com/docs/guides/chat/introduction
API_KEY
);
let response_text = repsonse_obj.message;
console.log(response_text);
let transcript = repsonse_obj.transcript;
console.log(transcript);
};