Trending Vals

1
stevekrouse avatar
sqlite
@stevekrouse
Script
Forked from std/sqlite
2
sarahxc avatar
slackScout
@sarahxc
Cron
Slack scout sends a slack notification every time your keywords are mentioned on Twitter, Hacker News, or Reddit. Get notified whenever you, your company, or topics of interest are mentioned online. Built with Browserbase . Inspired by f5bot.com . Full code tutorial . Getting Started To run Slack Scout, you’ll need a Browserbase API key Slack Webhook URL: setup here Twitter Developer API key Browserbase Browserbase is a developer platform to run, manage, and monitor headless browsers at scale. We’ll use Browserbase to navigate to, and scrape our different news sources. We’ll also use Browserbase’s Proxies to ensure we simulate authentic user interactions across multiple browser sessions . Get started with Browserbase for free here . Twitter We’ve decided to use the Twitter API to include Twitter post results. It costs $100 / month to have a Basic Twitter Developer account. If you decide to use Browserbase, we can lend our token. Comment below for access. Once you have the SLACK_WEBHOOK_URL , BROWSERBASE_API_KEY , and TWITTER_BEARER_TOKEN , input all of these as Val Town Environment Variables . Project created by Sarah Chieng and Alex Phan 💌
3
stevekrouse avatar
btcPriceAlert
@stevekrouse
Cron
Forked from panphora/btcPrice
4
pomdtr avatar
password_auth
@pomdtr
Script
Password Auth Middleware Protect your vals behind a password. Use session cookies to persist authentication. Demo See @pomdtr/password_auth_test Usage import { passwordAuth } from "https://esm.town/v/pomdtr/password_auth?v=84"; export default passwordAuth(() => { return new Response("OK"); }, { verifyPassword: (password) => password == Deno.env.get("VAL_PASSWORD") }); If you want to use an api token to authenticate: import { passwordAuth } from "https://esm.town/v/pomdtr/password_auth?v=84"; import { verifyToken } from "https://esm.town/v/pomdtr/verifyToken"; export default passwordAuth(() => { return new Response("OK"); }, { verifyPassword: verifyToken }); TODO [x] allow to authenticate using a val town token [ ] add a way to send an email to ask a password from the val owner [ ] automatically extend the session [ ] automatically remove expired sessions FAQ How to sign out ? Navigate to <your-site>/signout .
5
pomdtr avatar
extractValInfo
@pomdtr
Script
Extract vals infos (author, name, version) from a val url (either from esm.town or val.town ). Example usage: const {author, name} = extractValInfo(import.meta.url) Also returns a unique slug for the val: <author>/<name>
6
nbbaier avatar
sqliteExplorerApp
@nbbaier
HTTP (deprecated)
SQLite Explorer View and interact with your Val Town SQLite data. It's based off Steve's excellent SQLite Admin val, adding the ability to run SQLite queries directly in the interface. This new version has a revised UI and that's heavily inspired by LibSQL Studio by invisal . This is now more an SPA, with tables, queries and results showing up on the same page. Install Install the latest stable version (v86) by forking this val: Authentication Login to your SQLite Explorer with password authentication with your Val Town API Token as the password. Todos / Plans [ ] improve error handling [ ] improve table formatting [ ] sticky table headers [x] add codemirror [ ] add loading indication to the run button (initial version shipped) [ ] add ability to favorite queries [ ] add saving of last query run for a table (started) [ ] add visible output for non-query statements [ ] add schema viewing [ ] add refresh to table list sidebar after CREATE/DROP/ALTER statements [ ] add automatic execution of initial select query on double click [x] add views to the sidebar [ ] add triggers to sidebar [ ] add upload from SQL, CSV and JSON [ ] add ability to connect to a non-val town Turso database [x] fix wonky sidebar separator height problem (thanks to @stevekrouse) [x] make result tables scrollable [x] add export to CSV, and JSON (CSV and JSON helper functions written in this val . Thanks to @pomdtr for merging the initial version!) [x] add listener for cmd+enter to submit query
7
stevekrouse avatar
blob_admin
@stevekrouse
HTTP (deprecated)
Forked from stevekrouse/sqlite_admin
8
andreterron avatar
codeOnValTown
@andreterron
Script
Code on Val Town Adds a "Code on Val Town" ribbon to your page. This lets your website visitors navigate to the code behind it. This uses github-fork-ribbon-css under the hood. Usage Here are 2 different ways to add the "Code on Val Town" ribbon: 1. Wrap your fetch handler (recommended) import { modifyFetchHandler } from "https://esm.town/v/andreterron/codeOnValTown?v=50"; import { html } from "https://esm.town/v/stevekrouse/html?v=5"; export default modifyFetchHandler(async (req: Request): Promise<Response> => { return html(`<h2>Hello world!</h2>`); }); Example: @andreterron/openable_handler 2. Wrap your HTML string import { modifyHtmlString } from "https://esm.town/v/andreterron/codeOnValTown?v=50"; import { html } from "https://esm.town/v/stevekrouse/html?v=5"; export default async (req: Request): Promise<Response> => { return html(modifyHtmlString(`<h2>Hello world!</h2>`)); }; Example: @andreterron/openable_html Other ways We made sure this was very modular, so you can also add the ribbon using these methods: Get the element string directly: @andreterron/codeOnVT_ribbonElement Modify an HTTP Response: @andreterron/codeOnVT_modifyResponse Use .pipeThrough to append to a stream: @andreterron/InjectCodeOnValTownStream Customization Linking to the val These functions infer the val using the call stack or the request URL. If the inference isn't working, or if you want to ensure it links to a specific val, pass the val argument: modifyFetchHandler(handler, {val: { handle: "andre", name: "foo" }}) modifyHtmlString("<html>...", {val: { handle: "andre", name: "foo" }}) Styling You can set the style parameter to a css string to customize the ribbon. Check out github-fork-ribbon-css to learn more about how to style the element. modifyFetchHandler(handler, {style: ".github-fork-ribbon:before { background-color: #333; }"}) modifyHtmlString("<html>...", {style: ".github-fork-ribbon:before { background-color: #333; }"}) Here's how you can hide the ribbon on small screens: modifyFetchHandler(handler, {style: `@media (max-width: 768px) { .github-fork-ribbon { display: none !important; } }`}) To-dos [ ] Let users customize the ribbon. Some ideas are the text, color or placement.
9
sarahxc avatar
redditSearch
@sarahxc
HTTP
Use Browserbase and Puppeteer to monitor and scrape reddit search results.
10
muhammad_owais_warsi avatar
Spline
@muhammad_owais_warsi
HTTP
Spline
11
janpaul123 avatar
VALLE
@janpaul123
HTTP (deprecated)
Forked from janpaul123/valTownChatGPT2
12
stevekrouse avatar
getWeather
@stevekrouse
Script
Forked from sdan/getWeather
13
roramigator avatar
hackerNewsDigest
@roramigator
Cron
Hacker News Digest Fork this val to get an email like this in your inbox!
14
stevekrouse avatar
aqi
@stevekrouse
Cron
AQI Alerts Get email alerts when AQI is unhealthy near you. Set up Click Fork Change location (Line 4) to describe your location. It accepts fairly flexible English descriptions which it turns into locations via nominatim's geocoder API . Click Run Background This val uses nominatim's geocoder to get your lat, lon, and air quality data from OpenAQ. It uses EPA's NowCast AQI Index calculation and severity levels. Learn more: https://www.val.town/v/stevekrouse.easyAQI
15
stevekrouse avatar
valTownInspirationEmail
@stevekrouse
Cron
Forked from rodrigotello/valTownInspirationEmail
16
stevekrouse avatar
dailyDadJoke
@stevekrouse
Cron
Daily Dad Joke How do you make a programmer laugh every morning? A dad joke cron job! Setup Fork this val Click Create fork 🤣🤣🤣🤣 API This val uses the icanhazdadjoke API . You can find more docs here , such as how to filter by type .
17
stevekrouse avatar
status
@stevekrouse
HTTP
Uptime Status Page This is the status page for the data generated by this uptime cron: @stevekrouse/uptime
18
stevekrouse avatar
reloadOnSave
@stevekrouse
Script
Forked from stevekrouse/ReloadScript
19
jxnblk avatar
ReactStream
@jxnblk
Script
Forked from jxnblk/resrvStreaming
20
stevekrouse avatar
lastlogin
@stevekrouse
Script
Forked from pomdtr/lastlogin
21
stevekrouse avatar
uptime
@stevekrouse
Cron
Forked from healeycodes/isMyWebsiteDown
22
janpaul123 avatar
VALLErun
@janpaul123
HTTP (deprecated)
Forked from janpaul123/VALLE
23
saolsen avatar
p5
@saolsen
Script
P5 sketch Easily turn a p5.js sketch into a val. See https://www.val.town/v/saolsen/p5_sketch for an example. Usage Make a p5 sketch, you can import the p5 types to make it easier. import type * as p5 from "npm:@types/p5"; Export any "global" p5 functions. These are functions like setup and draw that p5 will call. Set the val type to http and default export the result of sketch , passing in import.meta.url . A full example looks like this. import type * as p5 from "npm:@types/p5"; export function setup() { createCanvas(400, 400); } export function draw() { if (mouseIsPressed) { fill(0); } else { fill(255); } ellipse(mouseX, mouseY, 80, 80); } import { sketch } from "https://esm.town/v/saolsen/p5"; export default sketch(import.meta.url); How it works The sketch function returns an http handler that sets up a basic page with p5.js added. It then imports your module from the browser and wires up all the exports so p5.js can see them. All the code in your val will run in the browser (except for the default sketch export) so you can't call any Deno functions, environment variables, or other server side apis.
24
stevekrouse avatar
lucia_middleware_safe
@stevekrouse
Script
Cross-platform safe Lucia-middleware This is a pretty ugly sittuation. It's really a hack around the way @stevekrouse/lucia_middlware was written, but to make it safe to import on the frontend, because it only imports the backend stuff dynamically per request.
25
stevekrouse avatar
easyAQI
@stevekrouse
Script
easyAQI Get the Air Quality Index (AQI) for a location via open data sources. It's "easy" because it strings together multiple lower-level APIs to give you a simple interface for AQI. Accepts a location in basically any string format (ie "downtown manhattan") Uses Nominatim to turn that into longitude and latitude Finds the closest sensor to you on OpenAQ Pulls the readings from OpenAQ Calculates the AQI via EPA's NowCAST algorithm Uses EPA's ranking to classify the severity of the score (ie "Unhealthy for Sensitive Groups") It uses blob storage to cache the openai location id for your location string to skip a couple steps for the next time. Example usage @stevekrouse.easyAQI({ location: "brooklyn navy yard" }) // Returns { "aqi": 23.6, "severity": "Good" } Forkable example: val.town/v/stevekrouse.easyAQIExample Also useful for getting alerts when the AQI is unhealthy near you: https://www.val.town/v/stevekrouse.aqi
26
janpaul123 avatar
blob
@janpaul123
Script
Forked from std/blob
27
vlad avatar
serverlessMatrixEchoBot
@vlad
Express
A example Serverless Bot for Matrix chat. See https://vlad.roam.garden/How-to-create-a-serverless-Matrix-Chat-bot for a more detailed write-up on how to set one up! To test this bot: invite serverless-echo@matrix.org to your unencrypted room Send a message starting with !echo and the bot will repeat content after. Use https://matrix-serverless.netlify.app/ to configure Matrix to call the endpoint on newly received messages
28
begoon avatar
thisval
@begoon
Script
This val default exports a function returning ValInfo. The val information comes from the Deno stack trace induced by throw new Error() . type ValInfo = { stack: string[]; // mostly for debugging endpoint: string; // val endpoint URL, empty if it is not an HTTP val user: string; // val.town user name name: string; // val name }; Here is an example program: import thisval from "https://esm.town/v/begoon/thisval"; const val = thisval(); export default async function(req: Request): Promise<Response> { return Response.json(val); } when invoked, it returns: { "stack": [ "Error", " at info (https://esm.town/v/begoon/thisval?v=12:10:11)", " at https://esm.town/v/begoon/thisvaltest?v=2:3:13" ], "endpoint": "begoon-thisvaltest.web.val.run", "user": "begoon", "name": "thisvaltest" }
29
g avatar
serveUtils
@g
Script
Serve Utils This val exports various utility functions, mainly the serve(commentFunction, contentType?) . It enables easy serving of different files, while allowing the use of all string characters: // this is possible const arr = ["Hello", 'world', `!`]; Townie Prompt This can be used as a replacement system prompt for Townie. Townie will: Write client-side applications with vanilla JavaScript Serve them as different assets, ie. index.html , style.css and main.js Use modern module syntax, including importing modules directly from esm.sh on the client side Not reuse the same script for the server and client logic CONTEXT Answer requests with TypeScript programs that are written for Deno's runtime environment in Val Town. 1. Your answer should be code that is complete and directly runnable. 2. There should be no comments like "more content here". 3. Your response should start with ```ts and end with ```, ie full code fences. No yapping about what you are doing and why. If necessary, include minimal instructions for the user to add secrets or other setup requirements. For changes to a single place within the code that only impact a few lines of code, respond with valid unified diff only, based on the code provided in the <current_code> tags in the system prompt. 1. Write valid unified diffs with change hunk headers. The file headers can be omitted. 2. Always based diffs off the latest version of the code provided in the <current_code> tags. 3. Ensure diffs use the ```diff language code fence. 4. If the diff is longer than 15 lines, too complex, or if you are not confident that it will work, respond with the full working code instead of creating a diff. 5. The decision to respond with a diff is one time. When you are asked to fix a simple bug, use a diff. The next request might ask for a more significant change, so respond with the complete fully working code containing the changes. Responses should omit any information about installing or running Deno or dependencies. Your val must export default an HTTP handler, which inputs and outputs web-standard Request and Response objects, respectively. This is almost the same interface as Cloudflare workers. The val should create a "export default async function server" which is the main function that gets executed on every HTTP request. When using libraries such as hono, you should `export default app.fetch`. When writing complete code, start with a multiline comment explaining how your approach will work, what libraries or API calls you will use. When changes are requested, do not overwrite the original comment, instead add the requested changes to the end if they are significant enough. QUIRKS Avoid external images or base64 images, use emojis, unicode symtols, or icon fonts/libraries instead, unless that's not practical for the user's request (e.g. if they ask for a particular animated gif). If you want an AI generated image, use https://maxm-imggenurl.web.val.run/the-description-of-your-image to dynamically generate one. Do not use the Deno KV module for storage. Do not use the alert() or input() methods. You do not have access to the file system. Do not attempt to access, read, write or serve anything from the file system. ENVIRONMENT VARIABLES Don't use any environment variables unless strictly necessary. For example use APIs that don't require a key. If you need environment variables use Deno.env.get('keyname') IMPORTS Prefix server-side imports with npm: This syntax only works if the script is only ran on the server side. Otherwise, imports should be prefixed with https://esm.sh/ for npm and deno dependencies to ensure compatibility in the browser. PERSISTENCE Only use backend storage if explicitly required. Otherwise make a simple static client-side site. If needed and if the user asks for something that requires persistence, use Val Town SQLite or Blob storage. Use the val's `import.meta.url` for the blob storage key or sqlite table name, unless specified by the user. ```ts // Blob Storage import { blob } from "https://esm.town/v/std/blob"; await blob.setJSON("myKey", { hello: "world" }); let blobDemo = await blob.getJSON("myKey"); let appKeys: { key: string; size: number; lastModified: string }[] = await blob.list("app_"); await blob.delete("myKey"); // SQLITE Storage import { sqlite } from "https://esm.town/v/stevekrouse/sqlite"; let KEY = new URL(import.meta.url).pathname.split("/").at(-1); (await sqlite.execute(`select * from ${KEY}_users where id = ?`, [1])).rows[0].id // If you are changing a SQLite table's schema, you should also change the table's name so it creates a fresh table, ie by adding _2 or _3 after it everywhere. Ensure that tables are created before they are used. ``` OPENAI If required, use the OpenAPI library as below. Notice that the api key must be omitted, as it is included during runtime: ```ts 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-4o-mini", max_tokens: 30, }); ``` TEMPLATE ```tsx /** * This template creates a hono app that serves a client-side application. * Use this template for any val you create for the user. * Ensure that server-side and client-side code is clearly separated to prevent errors. * * All imports that are not from `https://esm.town` should use `https://esm.sh` to ensure compatibility. * * DO NOT USE window.alert() */ import { serve } from 'https://esm.town/v/g/serveUtils'; import { Hono } from 'npm:hono'; function html() { /* <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="/styles.css"> <script type="module" src="/main.js" defer></script> </head> <body> <h1 id="h1El">Tap to get the current date.</h1> </body> </html> */ } function css() { /* body { height: 100vh; margin: 0; display: grid; place-items: center; background: #232323; color: white; font-family: sans-serif; } */ } function js() { /* import df from 'https://esm.sh/dateformat'; const h1El = document.getElementById('h1El'); document.body.addEventListener('click', (ev) => { ev.preventDefault(); h1El.textContent = df('HH:MM, dd/mm/yy'); }); */ } const app = new Hono(); app.get('/', serve(html, 'text/html')); app.get('/styles.css', serve(css, 'text/css')); app.get('/main.js', serve(js, 'text/javascript')); export default app.fetch; ```
30
muhammad_owais_warsi avatar
QR_Generator
@muhammad_owais_warsi
HTTP
QR Code Generator