Public vals
16
std
openai
Script
OpenAI - Docs β Use OpenAI's chat completion API with std/openai . This integration enables access to OpenAI's language models without needing to acquire API keys. For free Val Town users, all calls are sent to gpt-4o-mini . Basic Usage import { OpenAI } from "https://esm.town/v/std/openai";
const openai = new OpenAI();
const completion = await openai.chat.completions.create({
messages: [
{ role: "user", content: "Say hello in a creative way" },
],
model: "gpt-4",
max_tokens: 30,
});
console.log(completion.choices[0].message.content); Images To send an image to ChatGPT, the easiest way is by converting it to a
data URL, which is easiest to do with @stevekrouse/fileToDataURL . import { fileToDataURL } from "https://esm.town/v/stevekrouse/fileToDataURL";
const dataURL = await fileToDataURL(file);
const response = await chat([
{
role: "system",
content: `You are an nutritionist.
Estimate the calories.
We only need a VERY ROUGH estimate.
Respond ONLY in a JSON array with values conforming to: {ingredient: string, calories: number}
`,
},
{
role: "user",
content: [{
type: "image_url",
image_url: {
url: dataURL,
},
}],
},
], {
model: "gpt-4o",
max_tokens: 200,
}); Limits While our wrapper simplifies the integration of OpenAI, there are a few limitations to keep in mind: Usage Quota : We limit each user to 10 requests per minute. Features : Chat completions is the only endpoint available. If these limits are too low, let us know! You can also get around the limitation by using your own keys: Create your own API key on OpenAI's website Create an environment variable named OPENAI_API_KEY Use the OpenAI client from npm:openai : import { OpenAI } from "npm:openai";
const openai = new OpenAI(); π Edit docs
5
std
parse_email
Script
Parse email A small wrapper around email-addresses , an RFC 5322 email address parser. Usage import { parseAddressList } from "https://esm.town/v/std/parse_email";
console.log(parseAddressList('Steve <steve@val.town>, tom@val.town')); Should output: [
{
parts: {
name: {
name: "display-name",
tokens: "'Steve ",
semantic: "'Steve",
children: [ [Object] ]
},
address: {
name: "addr-spec",
tokens: "steve@val.town",
semantic: "steve@val.town",
children: [ [Object] ]
},
local: {
name: "local-part",
tokens: "steve",
semantic: "steve",
children: [ [Object] ]
},
domain: {
name: "domain",
tokens: "val.town",
semantic: "val.town",
children: [ [Object] ]
},
comments: [
{ name: "cfws", tokens: " ", semantic: " ", children: [Array] }
]
},
type: "mailbox",
name: "'Steve",
address: "steve@val.town",
local: "steve",
domain: "val.town",
comments: "",
groupName: null
},
{
parts: {
name: null,
address: {
name: "addr-spec",
tokens: " tom@val.town'",
semantic: "tom@val.town'",
children: [ [Object] ]
},
local: {
name: "local-part",
tokens: " tom",
semantic: "tom",
children: [ [Object] ]
},
domain: {
name: "domain",
tokens: "val.town'",
semantic: "val.town'",
children: [ [Object] ]
},
comments: [
{ name: "cfws", tokens: " ", semantic: "", children: [Array] }
]
},
type: "mailbox",
name: null,
address: "tom@val.town'",
local: "tom",
domain: "val.town'",
comments: "",
groupName: null
}
]
0
std
sqlite
Script
SQLite - Docs β SQLite is a lightweight, standard database. Every Val Town account comes with its own private SQLite database that is accessible from any of your vals via std/sqlite . Val Town SQLite is powered by Turso . Usage Migrations ORMs We recommend these admin data viewers for managing your database β viewing or editing data or your database table schema: Outerbase Studio (recommended) - formely known as LibSQL Studio β see instructions here SQLite Explorer (built in Val Town) Limits You can store 10mb on the free plan and up to 1gb on the paid plan. Contact us if you need more space. π Edit docs
0
std
blob
Script
Blob Storage - Docs β Val Town comes with blob storage built-in. It allows for storing any data, like text, JSON, or images. You can access it via std/blob . Blob storage is scoped globally to your account. If you set a blob in one val, you can retrieve it by the same key in another val. It's backed by Cloudflare R2. Blob Admin Panels Blob Storage in Settings β built-into Val Town - list, download, delete blobs Blob Admin β search, view, edit, upload blobs β built in a val β easy to customize in Val Town! Usage Get JSON import { blob } from "https://esm.town/v/std/blob";
let blobDemo = await blob.getJSON("myKey");
console.log(blobDemo); // returns `undefined` if not found Set JSON import { blob } from "https://esm.town/v/std/blob";
await blob.setJSON("myKey", { hello: "world" }); List keys import { blob } from "https://esm.town/v/std/blob";
let allKeys = await blob.list();
console.log(allKeys);
const appKeys = await blob.list("app_");
console.log(appKeys); // all keys that begin with `app_` Delete by key import { blob } from "https://esm.town/v/std/blob";
await blob.delete("myKey"); Examples Counter RSS Notifications (saving the last run time) Picture: Save & Read Error Handling blob.get can throw ValTownBlobNotFoundError Any method can throw ValTownBlobError for unexpected errors. Utilities Our Blob SDK also includes some utility functions to make working with blobs easier. Copy import { blob } from "https://esm.town/v/std/blob";
await blob.copy("myKey", "myKeyCopy"); Move import { blob } from "https://esm.town/v/std/blob";
await blob.move("myKey", "myKeyNew"); Lower-level API We provide access to the lower-level getter and setters,
which are useful if you are storing non-JSON or binary data,
need to stream in your response or request data, or do anything else lower-level. async get(key: string) : Retrieves a blob for a given key. async set(key: string, value: string | BodyInit) : Sets the blob value for a given key. See BodyInit . Limitations Blob-stored data counts towards your total Val Town storage β 10mb on the free plan and 1gb on pro. Check our pricing page to learn more. Keys for blobs can be up to 512 characters long. π Edit docs
9
std
API_URL
Script
Val Town API URL When Val Town code is run on Val Town servers we use a local URL so we can save time by skipping a roundtrip to the public internet. However, if you want to run your vals that use our API, ie std library vals, locally, you'll want to use our public API's URL, https://api.val.town . We recommend importing and using std/API_URL whenever you use our API so that you are always using the most efficient route. Example Usage import { API_URL } from "https://esm.town/v/std/API_URL";
const response = await fetch(`${API_URL}/v1/me`, {
headers: {
Authorization: `Bearer ${Deno.env.get("valtown")}`,
Accept: "application/json",
},
});
const data = await response.json();
console.log(data)
0
std
fetch
Script
Proxied fetch - Docs β The Javascript Fetch API is directly available within a Val. However sometimes fetch calls are blocked by the receiving server for using particular IP addresses. Additionally, network blips or unreliable web services may lead to failures if not handled properly. The Val Town standard library contains an alternative version, std/fetch , that wraps the JavaScript Fetch API to provide additional functionality. The fetch function from std/fetch reroutes requests using a proxy vendor so that requests obtain different IP addresses. It also automatically retries failed requests several times. Note that using std/fetch will be significantly slower than directly calling the Javascript Fetch API due to extra network hops. Usage After importing std/fetch , the fetch method is used with the same signature as the Javascript Fetch API. import { fetch } from "https://esm.town/v/std/fetch";
let result = await fetch("https://api64.ipify.org?format=json");
let json = await result.json();
console.log(json.ip); If you run the above code multiple times, you'll see that it returns different IP addresses, because std/fetch uses proxies so that each request is made from a different IP address. π Edit docs
2
std
turso
Script
Deprecated in favor of std/sqlite (also powered by Turso) std/turso was the initial version of our integration with Turso. It was so popular, we rebuilt it to be faster and easier to use: std/sqlite . Turso is a serverless SQLite platform designed for the edge. It runs libSQL , their open contribution fork of SQLite. Every Val Town user automatically gets their own Turso SQLite database! It's great for >100kb data (ie bigger than a val) or when you need SQL: relations, ACID transactions, etc. Storage used in Turso will count against your Val Town total storage (10mb for free users; 1gb for Pro users). Contact us if you'd need more β it should be no problem! Getting started This val uses our public key auth scheme . Generate your keypair On your publicKey click the lock iconπ to change the permissions to Unlisted . Fork this helper function replacing stevekrouse with your own username Try out some queries! Usage This val returns a Turso SDK's Client , which supports execute , batch , and transaction . await @me.turso().execute(`create table blobs(
key text unique,
value text
)`) More example usage Architecture This @std.turso function is the client or SDK to @std.tursoAPI, which acts as a "proxy" to Turso. It handles authentication, creates databases, and forwards on your SQL queries. You can get lower latency (~200ms vs ~800ms), more storage, databases, CLI & API access by having your own Turso account.
7
std
email
Script
Email - Docs β Send emails with std/email . You can only send emails to yourself if you're on Val Town Free. If you're on Val Town Pro , you can email anyone. Want to receive emails instead? Create an email handler val Basic usage import { email } from "https://esm.town/v/std/email";
await email({ subject: "New Ink & Switch Post!", text: "https://www.inkandswitch.com/embark/" }); subject The email subject line. It defaults to Message from @your_username on Val Town . to , cc , and bcc By default, the to field is set to the owner of the Val Town account that calls it. If you have Val Town Pro, you can send emails to anyone via the to , cc , and bcc fields. If you don't have Val Town Pro, you can only send emails to yourself, so leave those fields blank. from The from is limited to a few options: It defaults to notifications@val.town if you don't specify it. If you do specify it, it must be of the form: your_username.valname@valtown.email . replyTo replyTo accepts a string email or an object with strings for email and name (optional). This can be useful if you are sending emails to others with Val Town Pro. import { email } from "https://esm.town/v/std/email";
await email({
to: "someone_else@example.com",
from: "your_username.valname@valtown.email",
replyTo: "your_email@example.com",
text: "these pretzels are making me thirsty",
}); Attachments You can attach files to your emails by using the attachments field.
Attachments need to be Base64 encoded,
which is what the btoa
method is doing in this example: import { email } from "https://esm.town/v/std/email";
export const stdEmailAttachmentExample = email({
attachments: [
{
content: btoa("hello attachments!"),
filename: "test.txt",
type: "text",
disposition: "attachment",
},
],
}); Here's an example sending a PDF . Headers You can set custom headers in emails that you send: import { email } from "https://esm.town/v/std/email?v=13"
console.log(
await email({
text: "Hi",
headers: {
"X-Custom-Header": "xxx",
},
}),
) This is also documented in our REST API , and supported in the SDK . π Edit docs
7