4async function fetchRandomJoke() {
5const response = await fetch(
6"https://official-joke-api.appspot.com/random_joke",
7);
8return response.json();
uploadImagemain.tsx1 match
24}
25async function getUploadURL(): Promise<string> {
26const data = await (await fetch("https://www.val.town/api/trpc/generateImageUploadUrl", {
27"headers": {
28"content-type": "application/json",
sanguineAquaReptileREADME.md1 match
11[](https://www.val.town/v/stevekrouse/blob_admin_app/fork)
1213It uses [basic authentication](https://www.val.town/v/pomdtr/basicAuth) with your [Val Town API Token](https://www.val.town/settings/api) as the password (leave the username field blank).
1415# TODO
affableMagentaPlanarianmain.tsx4 matches
397intervalId = setInterval(async () => {
398try {
399const response = await fetch("/api/progress");
400if (!response.ok) {
401throw new Error(`HTTP error! status: ${response.status}`);
429setBrokenLinks([]);
430try {
431const response = await fetch("/api/check-links", {
432method: "POST",
433headers: {
602const url = new URL(request.url);
603604if (url.pathname === "/api/progress" && request.method === "GET") {
605const now = new Date();
606if (lastProgressUpdate && currentProgress) {
631}
632633if (url.pathname === "/api/check-links" && request.method === "POST") {
634let requestBody;
635try {
1[IIIF Presentation API](https://iiif.io/api/presentation/3.0/) for [4TU.ResearchData](https://data.4tu.nl/).
23URL scheme:
16Todo:
1718- Add more metadata from the Djehuty API response.
1920Limitations:
2122- This is a temporary workaround until the Presentation API is implemented as part of Djehuty
23- Only images are currently supported (not video/audio)
24- The val needs to do some API requests before producing the manifest and doesn't cache responses
2526Credits:
2728- Image API implementation by Roel Janssen of 4TU.ResearchData. The source code can be found [here](https://github.com/4TUResearchData/djehuty)
29- [IIIF Builder](https://github.com/IIIF-Commons/iiif-builder) by Stephen Fraser
1import * as uuid from "https://deno.land/std/uuid/mod.ts";
2import { blob } from "https://esm.town/v/std/blob";
3import { getPolicy } from "https://esm.town/v/xkonti/memoryApiPolicy";
4import { Hono } from "npm:hono@3";
56export const handleMemoryApiRequest = async (
7req: Request,
8apiName: string,
9contactEmail: string,
10lastPolicyUpdate: string,
11blobKeyPrefix: string,
12apiKeyPrefix: string,
13) => {
14// ==== HELPERS ====
5152const verifyRequest = (c): { memoriesKey: string; error: any } => {
53// Verify API key coming as a Bearer header
54const authHeader = c.req.headers.get("Authorization");
55if (!authHeader || !authHeader.startsWith("Basic ")) {
67return { memoriesKey: "", error: c.text("Forbidden", 403) };
68}
69const expectedKey = Deno.env.get(apiKeyPrefix + key) ?? null;
70if (token !== expectedKey) {
71console.error("Invalid API KEY header");
72return { memoriesKey: "", error: c.text("Forbidden", 403) };
73}
75};
7677// API
7879const app = new Hono();
405// PRIVACY POLICY
406app.get("/privacy", async (c) => {
407const policy = getPolicy(apiName, contactEmail, lastPolicyUpdate);
408c.header("Content-Type", "text/html");
409return c.html(policy);
410});
411412app.get("/openapi", async (c) => {
413const specification = `
414{
415"openapi": "3.1.0",
416"info": {
417"title": "Memories and Conversations API",
418"description": "API for managing and storing long-term memories, AI conversations, and file attachments.",
419"version": "1.2.0"
420},
421"servers": [
422{
423"url": "<APIURL>"
424}
425],
434},
435"401": {
436"description": "Unauthorized - Missing or invalid API key."
437},
438"403": {
439"description": "Forbidden - Invalid API key."
440}
441},
468},
469"401": {
470"description": "Unauthorized - Missing or invalid API key."
471},
472"403": {
473"description": "Forbidden - Invalid API key."
474}
475},
524},
525"401": {
526"description": "Unauthorized - Missing or invalid API key."
527},
528"403": {
529"description": "Forbidden - Invalid API key."
530}
531},
571},
572"401": {
573"description": "Unauthorized - Missing or invalid API key."
574},
575"403": {
576"description": "Forbidden - Invalid API key."
577}
578},
602},
603"401": {
604"description": "Unauthorized - Missing or invalid API key."
605},
606"403": {
607"description": "Forbidden - Invalid API key."
608},
609"404": {
641},
642"401": {
643"description": "Unauthorized - Missing or invalid API key."
644},
645"403": {
646"description": "Forbidden - Invalid API key."
647}
648},
674},
675"401": {
676"description": "Unauthorized - Missing or invalid API key."
677},
678"403": {
679"description": "Forbidden - Invalid API key."
680},
681"404": {
728},
729"401": {
730"description": "Unauthorized - Missing or invalid API key."
731},
732"403": {
733"description": "Forbidden - Invalid API key."
734},
735"404": {
781},
782"401": {
783"description": "Unauthorized - Missing or invalid API key."
784},
785"403": {
786"description": "Forbidden - Invalid API key."
787},
788"404": {
4async function fetchRandomJoke() {
5const response = await fetch(
6"https://official-joke-api.appspot.com/random_joke",
7);
8return response.json();
blob_adminREADME.md1 match
11[](https://www.val.town/v/stevekrouse/blob_admin_app/fork)
1213It uses [basic authentication](https://www.val.town/v/pomdtr/basicAuth) with your [Val Town API Token](https://www.val.town/settings/api) as the password (leave the username field blank).
1415# TODO
4async function fetchRandomJoke() {
5const response = await fetch(
6"https://official-joke-api.appspot.com/random_joke",
7);
8return response.json();
searchArXiVmain.tsx1 match
1export const searchArXiV = async ({ query = "", start = 0, max_results = 10 }) => {
2const { parseStringPromise } = await import("npm:xml2js")
3const url = new URL("https://export.arxiv.org/api/query")
4url.searchParams.set("search_query", query)
5url.searchParams.set("start", String(start))