357
358 let next = PUA_START;
359 function nextAvailableCodePoint() {
360 while (usedCodes.has(next)) {
361 next += 1;
482};
483
484function bufferToBase64(buffer: ArrayBuffer) {
485 let binary = "";
486 const bytes = new Uint8Array(buffer);
493}
494
495export default async function(
496 req: Request,
497): Promise<Response> {
4
5// formats date in SQLITE format YYYY-MM-DD
6function formatDate(date: string) {
7 let [month, day, year] = date.split("/");
8 if (month.length == 1) month = "0" + month;
12
13// insert newsletter metadata in sqlite
14async function insertRow(articleNumber: number, title: string, date: string) {
15 try {
16 await sqlite.execute({
24
25// check if newsletter id exists
26async function checkNewsletterPresent(articleNumber: number) {
27 const data = await sqlite.execute({
28 sql: `SELECT EXISTS(SELECT 1 FROM newsletter WHERE article_number=:articleNumber)`,
2import { easyAQI } from "https://esm.town/v/stevekrouse/easyAQI";
3
4export async function aqi(interval: Interval) {
5 const location = "brooklyn navy yard"; // <-- change to place, city, or zip code
6 const data = await easyAQI({ location });
10const TurndownService = isCloudflareWorker ? null : await import("npm:turndown@^7.1.3");
11
12async function markdown2html(html: string): Promise<string> {
13 if (AgentMarkdownImport) {
14 // TurndownService doesn't work on cf
22}
23
24function getYoutubeVideoID(url: URL): string | null {
25 const regExp = /(?:youtube\.com\/(?:[^/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?/\s]{11})/i;
26 const match = url.href.match(regExp);
28}
29
30function response(message: string, contentType = "text/markdown"): Response {
31 const headers = new Headers();
32 headers.set("Access-Control-Allow-Origin", "*");
41}
42
43function err(msg: string): Response {
44 const errorMessage = JSON.stringify({
45 error: {
51}
52
53function fudgeURL(url: string) {
54 try {
55 return new URL(url);
60}
61
62function processInput(req: Request) {
63 let ret = {
64 url: undefined as undefined | URL,
87}
88
89export default async function(req: Request): Promise<Response> {
90 const action = processInput(req);
91 const url = action.url;
147}
148
149function generate_ui(input_description, link, link_text) {
150 const html = `
151<!DOCTYPE html>
14});
15
16app.post("/", async function(c) {
17 let res = await sqlite.execute({
18 sql: `insert into kv(key, value) values (:key, :value)`,
2import { easyAQI } from "https://esm.town/v/stevekrouse/easyAQI";
3
4export async function aqi(interval: Interval) {
5 const location = "delhi, india"; // <-- change to place, city, or zip code
6 const data = await easyAQI({ location });
2import { easyAQI } from "https://esm.town/v/stevekrouse/easyAQI";
3
4export async function aqi(interval: Interval) {
5 const location = "brooklyn navy yard"; // <-- change to place, city, or zip code
6 const data = await easyAQI({ location });
1# Notehub
2
3A set of helper functions for interacting with the Notehub API
4
5Requires `NOTEHUB_CLIENT_ID` and `NOTEHUB_CLIENT_SECRET` [environment variables](https://www.val.town/settings/environment-variables) to be configured.
2import { fetchJSON } from "https://esm.town/v/stevekrouse/fetchJSON";
3
4export async function dailyDadJoke() {
5 let { setup, punchline } = await fetchJSON("https://official-joke-api.appspot.com/random_joke");
6 return email({
24 );
25
26export async function telegramSendAudioMessage(chatId: string, audioData: Uint8Array, botToken: string): Promise<void> {
27 const url = `https://api.telegram.org/bot${botToken}/sendAudio`;
28
A helper function to build a file's email
Simple functional CSS library for Val Town
LangChain (https://langchain.com) Ambassador, KubeSphere (https://kubesphere.io) Ambassador, CNCF OpenFunction (https://openfunction.dev) TOC Member.
import { OpenAI } from "https://esm.town/v/std/openai";
export default async function(req: Request): Promise<Response> {
if (req.method === "OPTIONS") {
return new Response(null, {
headers: {
"Access-Control-Allow-Origin": "*",