Search
BlobArray
@joey
Blob Array Create an array as a Database, instantly! Just create a new val for your array: import { BlobArray } from "https://esm.town/v/joey/BlobArray";
type User = { email: string };
// specify the type inside the TS generic <> to define the type of your array
export let myUserArray = BlobArray<User>("my-user-array"); Now import it and start using it in your vals! import { myUserArray } from "https://esm.town/v/joey/myUserArray";
// overwrite the entire array
await myUserArray.set([{ email: "user1@gmail.com" }, { email: "user2@yahoo.com" }]);
// get all the entries in your array
const allUsers = await myUserArray.get();
// call any array method you want, just use "await"
await myUserArray.push({ email: "johndoe@gmail.com" });
const gmailUsers = await myUserArray.filter(u => u.email.includes("@gmail.com"));
Script
type User = { email: string };
// specify the type inside the TS generic <> to define the type of your array
export let myUserArray = BlobArray<User>("my-user-array");
valTownBadge
@jxnblk
Add a Val Town badge to your own HTTP vals Option 1: Middleware Import the middleware from https://www.val.town/v/jxnblk/valTownBadgeMiddleware Wrap your HTML request handler with middleware, and pass import.meta.url to link to your val import wrapper from "https://esm.town/v/jxnblk/valTownBadgeMiddleware";
async function handler(req: Request): Promise<Response> {
const html = `
<h1>Hello, world</h1>
`;
return new Response(html, {
headers: {
"Content-Type": "text/html; charset=utf-8",
},
});
}
export default wrapper(handler, import.meta.url); Option 2: HTML string generator Get the HTML string for the badge using https://www.val.town/v/jxnblk/valTownBadge Add the HTML to your response's HTML string wherever you like import valTownBadge from "https://esm.town/v/jxnblk/valTownBadge";
export default async function(req: Request): Promise<Response> {
const badge = valTownBadge(import.meta.url);
const html = `
<h1>Hello, world</h1>
${badge}
`;
return new Response(html, {
headers: {
"Content-Type": "text/html; charset=utf-8",
},
});
} Manual options You can also edit the snippet below to manually add the badge in HTML <a href="https://www.val.town/v/jxnblk/valTownBadgeExample" target="_blank" style="text-decoration:none;color:inherit">
<img src="https://jxnblk-valtownbadgesvg.web.val.run/" width="160" height="160">
</a> Or markdown: [![View source on Val Town](https://jxnblk-valtownbadgesvg.web.val.run/)](https://www.val.town/v/jxnblk/valTownBadgeExample) Vals used to create this https://www.val.town/v/jxnblk/valTownBadgeSVG SVG badge image service https://www.val.town/v/jxnblk/valTownLogotypeReact Val Town logo React component https://www.val.town/v/jxnblk/codeIconReact Code icon React component https://www.val.town/v/jxnblk/valTownBadge HTML generator that uses import.meta.url to create a link to your val https://www.val.town/v/jxnblk/valTownBadgeMiddleware Middleware to inject badge HTML in the lower right corner of your page
Script
- <https://www.val.town/v/jxnblk/valTownBadgeSVG> SVG badge image service
- <https://www.val.town/v/jxnblk/valTownLogotypeReact> Val Town logo React component
- <https://www.val.town/v/jxnblk/codeIconReact> Code icon React component
- <https://www.val.town/v/jxnblk/valTownBadge> HTML generator that uses `import.meta.url` to create a link to your val
umbrellaReminder
@madhatter349
☔️ Umbrella reminder if there's rain today Setup Fork this val 👉 https://val.town/v/stevekrouse.umbrellaReminder/fork Customize the location (line 8). You can supply any free-form description of a location. ⚠️ Only works for US-based locations (where weather.gov covers). How it works Geocodes an free-form description of a location to latitude and longitude – @stevekrouse.nominatimSearch Converts a latitude and longitude to weather.gov grid – @stevekrouse.weatherGovGrid Gets the hourly forecast for that grid Filters the forecast for periods that are today and >30% chance of rain If there are any, it formats them appropriately, and sends me an email
Cron
export const umbrellaReminder = async (arg) => {
if (arg.method) return Response.json("");
let location = "Upper West Side, New York"; // <---- customize this line
let [{ lat, lon }] = await nominatimSearch({
q: location,
plausible
@saolsen
Plausible analytics Call track with the domain you set up in plausible and the request. I've been using saolsen.val-name .
Note that there is no auth for the plausible events API, so if somebody forks the val it'll still work but
track all their val page loads in your dashboard which is kinda weird but also kinda cool, idk. See https://www.val.town/v/saolsen/plausible_example for how to use.
Script
headers: {
"User-Agent": req.headers.get("user-agent")!,
"X-Forwarded-For": req.headers.get("true-client-ip")!,
"Content-Type": "application/json",
body: JSON.stringify({
byob
@vawogbemi
BYOB - Build Your Own Bot You can chat with llms over email, the email thread functions as memory. The biggest thing is that you can instantly create a chat
like interface with llms. Pair that with back end data and functions and you got something really powerful. Take it further Custom domains Use cloudflare email workers or a similiar service to create a custom email domain and route any incoming emails to this val. Use any email api set up with that domain to send emails ie. Sendgrid, Resend, Postmark. Toolings Llms can uses tools , meaning you can make this an agent and a whole lot more useful.
Email
export default async function(e: Email) {
const client = new OpenAI();
const Messages = z.object({
content: z.string(),
const completion = await client.beta.chat.completions.parse({
messages: [
You are a helpful email assistant. Reply to emails to your best abilities, but keep responses short and concise around 280 characters.`;
const completion2 = await client.chat.completions.create({
messages: [{ role: "system", content: systemPrompt }].concat(results),
emailValHandlerNo
@martinbowling
Email AI Assistant Chat with your favorite AI via email (with enhanced attachment and content support) What It Does This advanced email AI assistant allows you to: Send emails to an AI for comprehensive analysis and responses Automatically transform your queries into structured research objectives Parse and analyze various types of content: PDF attachments Image attachments (using GPT-4 Vision) Website content from links in your email Get detailed, context-aware responses directly to your inbox Setup Guide Copy this Val and save it as an Email Val (choose Val type in the top-right corner of the editor) Set up the required environment variables: OPENAI_API_KEY: Your OpenAI API key MD_API_KEY: Your API key for the markdown extraction service You can set these using Val Town's environment variables: https://docs.val.town/reference/environment-variables/ Copy the email address of the Val (click 3 dots in top-right > Copy > Copy email address) Compose your email: Write your query or request in the email body Attach any relevant PDFs or images Include links to websites you want analyzed Send it to the Val email address Wait for the AI's response, which will arrive in your inbox shortly How to Use Effectively Be clear and specific in your queries Provide context when necessary Utilize attachments and links to give the AI more information to work with The AI will transform your query into a structured research objective, so even simple questions may yield comprehensive answers Supported File Types and Limitations PDFs: Text content will be extracted and analyzed Images: Will be analyzed using GPT-4 Vision API Websites: Content will be extracted and converted to markdown for analysis Other file types are not currently supported and will be ignored Note: There may be size limitations for attachments and processing times may vary based on the complexity of the content. The AI uses advanced prompt transformation to enhance your queries, providing more detailed and structured responses. This process helps in generating comprehensive and relevant answers to your questions.
Email
</return_format>
<warnings>
List critical considerations for accuracy, verification requirements, and potential limitations of the data or analysis.
</warnings>
3. Ensure that your transformed request is more detailed and comprehensive than the original query, providing a clear structure for research and analysis.
getAccessToken
@raymondcamden
An interactive, runnable TypeScript val by raymondcamden
Script
const params = new URLSearchParams();
params.append("client_secret", secret);
params.append("grant_type", "client_credentials");
params.append("scope", "openid,AdobeID,read_organizations");
let resp = await fetch(`https://ims-na1.adobelogin.com/ims/token/v2?client_id=${id}`, {
method: "POST",
get_clip_download_url
@sijames
An interactive, runnable TypeScript val by sijames
HTTP
headers: {
"Content-Type": "application/json",
// This is NOT your app's client ID. This is the official twitch UI client ID.
// This is required to authenticate against this request.
"Client-Id": "kimne78kx3ncx6brgo4mv6wki5h1ko",
body: JSON.stringify({
operationName: "VideoAccessToken_Clip",
emailSummaryHandler
@paulkinlan
Email Summary Service This val is an email handler replies to emails it recieves with an LLM-generated summary. To use, forward an email to paulkinlan.emailSummaryHandler@valtown.email Blog post: https://paul.kinlan.me/projects/email-summary-service/
Email
role: "system",
content:
"You are a helpful email summarization assistant. Provide a concise, professional summary of the email content in HTML format optimized for email clients. Use only basic HTML tags like <p>, <strong>, <em>, <ul>, <li>, and <br>. Avoid using <div>, <span>, or any advanced HTML5 elements. Do not include any CSS or JavaScript. Keep the structure simple and focused on content.",
role: "user",
content: e.text || e.html || "No content",
sweetAzureFinch
@cingozilyas
An interactive, runnable TypeScript val by cingozilyas
Script
const Airtable = require("airtable");
export default async function saveToAirtable(videoName, videoDescription, videoCover, videoFile, clientLogo) {
// Set up your Airtable API key and base ID
{ url: videoCover }, // assuming videoCover is a URL to the uploaded file
"ssa-video-clientLogo": [
{ url: clientLogo }, // assuming clientLogo is a URL to the uploaded file
"ssa-video-videoFile": [
syncCommentToLemmy
@pdebie
This allows copying specific comments from Reddit to a Lemmy thread. Might be super specific to my use case, but we use this for example to copy over some content from the r/SpaceX Starship thread to the one on the Lemmy community (with their blessing).
Script
return hash;
const { LemmyHttp } = await import("npm:lemmy-js-client@0.18.1");
let client = new LemmyHttp(`https://${instance}`, {
fetchFunction: fetch,
// (client as any)["#fetchFunction"] = fetch;
let comments = (await fetchRss(redditUrl)).filter((i) =>
lemmyId: undefined,
const ret = await client.createComment({
post_id: postId,
if (existingStatus.contentHash !== contentHash) {
await client.editComment({
comment_id: existingStatus.lemmyId,
unsplashSourceReimplementation
@pinjasaur
Re-implements Unsplash Source which was a service hosted at source.unsplash.com that served random photos from Unsplash. To use this, you'll want to fork it, provide your own Unsplash API key, and configure the allowed domains. Read more: https://paul.af/reimplementing-unsplash-source
HTTP
// Add parameters conditionally
const searchParams = new URLSearchParams({
client_id: UNSPLASH_ACCESS_KEY,
// Add orientation only if specified
if (orientationParam) {
headers: {
"Accept-Version": "v1",
"Authorization": `Client-ID ${UNSPLASH_ACCESS_KEY}`,
if (!response.ok) {
// Include the response body for more detailed error information
resume
@ajax
// set by ajax.resumeHtml at 2023-06-07T20:30:59.005Z
Script
"name": "Joey Flores, Co-founder and CEO of Earbits, Inc."
"reference": "I've had the great pleasure of working with Thomas for the past three years at Earbits, and on a few side projects. Two years ago our CTO left on a moment's notice, Thomas saved our company by quickly stepping up to fill this role. He has been with our company through thick and thin and made serious personal sacrifices in order to help the company during tough times. He is a phenomenal hacker and a true team player. Highly recommended!",
"name": "Yotam Rosenbaum, SVP of Operations, Earbits, Inc."
"skills": [{
"keywords": ["HTML / JSX", "SCSS / CSS / BEM / Styled Components", "Javascript / Typescript", "React / Next", "Redux / Apollo"],
"level": "Senior",
"startDate": "2020-05-05",
"highlights": ["Tokenized is a Bitcoin wallet for issuing, managing and trading digital tokens. I built out the front end which was packaged as an electron app. It was a difficult frontend to build because we store the users keys locally and used them to sign transactions and contracts.", "React", "Redux", "SCSS", "Product"],
"startDateYear": "2020",
"endDate": "2020-01-01",
"highlights": ["Blockbid is an Australian crypto currency exchange. I started off on the frontend but eventually became lead tech and worked on every moving piece of the exchange. I really enjoyed working with liquidity providers and connecting their platforms to help us achieve liquid markets.", "React, Apollo, Styled Components", "Node.js / Rails", "Docker / Heroku / GCP", "Used Figma for design and UX work", "Optimizing markets with tens of millions of rows using SQL."],
"startDateYear": "2018",
"boolHighlights": true
"highlights": ["Built a very large and complex React / Redux application. It works on all platforms and has IOS/Android builds due to it being a PWA. (wrapped it in React Native though only implementing a WebView)", "Worked with Postgres, Redis and Dynamodb for storage.", "Hosted on a mixture of Heroku Apps and EC2 servers.", "Caching by Fastly and Cloudflare", "Hybrid app supported on all platforms"],
"website": "https://listium.com",
emailSummaryHandler
@stevekrouse
Email Summary Service This val is an email handler replies to emails it recieves with an LLM-generated summary. To use, forward an email to paulkinlan.emailSummaryHandler@valtown.email Blog post: https://paul.kinlan.me/projects/email-summary-service/
Email
role: "system",
content:
"You are a helpful email summarization assistant. Provide a concise, professional summary of the email content in HTML format optimized for email clients. Use only basic HTML tags like <p>, <strong>, <em>, <ul>, <li>, and <br>. Avoid using <div>, <span>, or any advanced HTML5 elements. Do not include any CSS or JavaScript. Keep the structure simple and focused on content.",
role: "user",
content: e.text || e.html || "No content",
sendEmailNewsletter
@petermillspaugh
Val Town email subscriptions: send email newsletter Cousin Val to @petermillspaugh/emailSubscription — see docs there. This Val has a few layers of protection to avoid double sending. Those mechanisms feel pretty hacky, so any suggestions are welcome! Feel free to comment on the Val or submit a PR.
Cron
/** @jsxImportSource https://esm.sh/preact */
import { generateNewsletterJsx } from "https://esm.town/v/petermillspaugh/generateNewsletterJsx";
import { newsletters } from "https://esm.town/v/petermillspaugh/newsletters";
import { email as sendEmail } from "https://esm.town/v/std/email?v=11";
import { sqlite } from "https://esm.town/v/std/sqlite?v=4";
import { render } from "npm:preact-render-to-string";
type SubscriberRow = [
subscriberId: number,