5async function fetchRandomJoke() {
6 const response = await fetch(
7 "https://official-joke-api.appspot.com/random_joke",
8 );
9 return response.json();
8
91. Click `Fork`
102. Change `location` (Line 4) to describe your location. It accepts fairly flexible English descriptions which it turns into locations via [nominatim's geocoder API](https://www.val.town/v/stevekrouse/nominatimSearch).
113. Click `Run`
12
169 }
170
171 // Existing API proxy logic
172 const { API_URL } = await import("https://esm.town/v/std/API_URL?v=5");
173 const { fetchJSON } = await import("https://esm.town/v/stevekrouse/fetchJSON");
174 const { sqlite } = await import("https://esm.town/v/stevekrouse/sqlite");
175 const Authorization = req.headers.get("Authorization") as string;
176 const meRes = await fetch(`${API_URL}/v1/me`, { headers: { Authorization } });
177 if (!meRes.ok) {
178 return new Response("Unauthorized", { status: 401 });
232 );
233
234 const socialDataURL = new URL("https://api.socialdata.tools/twitter/search");
235 socialDataURL.searchParams.set("query", query);
236 const socialDataResults = await fetchJSON(socialDataURL.toString(), {
237 bearer: Deno.env.get("SOCIAL_DATA_API_KEY"),
238 });
239
5Chart.register(...registerables);
6
7import { API_URL } from "https://esm.town/v/std/API_URL?v=5";
8import { fetchJSON } from "https://esm.town/v/stevekrouse/fetchJSON";
9import { sqlite } from "https://esm.town/v/stevekrouse/sqlite";
132 // Existing social data proxy logic remains unchanged
133 const Authorization = req.headers.get("Authorization") as string;
134 const meRes = await fetch(`${API_URL}/v1/me`, { headers: { Authorization } });
135 if (!meRes.ok) {
136 return new Response("Unauthorized", { status: 401 });
190 );
191
192 const socialDataURL = new URL("https://api.socialdata.tools/twitter/search");
193 socialDataURL.searchParams.set("query", query);
194 const socialDataResults = await fetchJSON(socialDataURL.toString(), {
195 bearer: Deno.env.get("SOCIAL_DATA_API_KEY"),
196 });
197
13## Authentication
14
15Login to your SQLite Explorer with [password authentication](https://www.val.town/v/pomdtr/password_auth) with your [Val Town API Token](https://www.val.town/settings/api) as the password.
16
17## Todos / Plans
27 <head>
28 <title>SQLite Explorer</title>
29 <link rel="preconnect" href="https://fonts.googleapis.com" />
30
31 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
32 <link
33 href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300..700&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap"
34 rel="stylesheet"
35 />
19
20const sharedStyles = `
21@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@300;400;700&display=swap');
22
23body {
4
5This val gets Twitter data via [SocialData](https://socialdata.tools) via
6@stevekrouse/socialDataProxy. Val Town Pro users can call this API
7100 times per day, so be sure not to set this cron to run more than once every 15 min.
8If you want to use it more, get your own [SocialData](https://socialdata.tools)
9API token and pay for it directly.
10
11## 1. Query
13Change the `query` variable for what you want to get notified for.
14
15You can use [Twitter's search operators](https://developer.twitter.com/en/docs/twitter-api/v1/rules-and-filtering/search-operators) to customize your query, for some collection of keywords, filtering out others, and much more!
16
17## 2. Notification
58 async function buscarDadosLoteria(numero = null) {
59 const url = numero
60 ? `https://servicebus2.caixa.gov.br/portaldeloterias/api/megasena/${numero}`
61 : "https://servicebus2.caixa.gov.br/portaldeloterias/api/megasena/";
62
63 try {
8const startingBalance = 100;
9
10interface ApiResponse {
11 status: number;
12 body: any;
131}
132
133function handleHome(baseUrl: string): ApiResponse {
134 return {
135 status: 200,
139}
140
141async function handleBalance(address: string | null): Promise<ApiResponse> {
142 if (!address) {
143 return {
153}
154
155async function handleSend(data: any): Promise<ApiResponse> {
156 const { from, to, amount } = data;
157 if (!from || !to || amount === undefined) {
193}
194
195async function handleAccounts(): Promise<ApiResponse> {
196 const accounts = await getAllAccounts();
197 return {
201}
202
203async function handleMint(data: any, authHeader: string | null): Promise<ApiResponse> {
204 const { address, amount } = data;
205 if (!address || amount === undefined) {
235}
236
237function handleFavicon(): ApiResponse {
238 return {
239 status: 204,
242}
243
244function handleNotFound(): ApiResponse {
245 return {
246 status: 404,
249}
250
251function logRequestResponse(req: Request, res: ApiResponse) {
252 console.log(`Request: ${req.method} ${req.url}`);
253 console.log(`Response: Status ${res.status}, Body:`, res.body);
260 const path = url.pathname;
261
262 let response: ApiResponse;
263
264 switch (true) {