9To use it on your own Val Town SQLite database, [fork it](https://www.val.town/v/stevekrouse/sqlite_admin/fork) to your account.
10
11It 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).
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
4function fetchRandomJoke() {
5 const response = fetch(
6 "https://official-joke-api.appspot.com/random_joke",
7 );
8 return response;
4async function fetchRandomJoke() {
5 const response = await fetch(
6 "https://official-joke-api.appspot.com/random_joke",
7 );
8 return response.json();
102 <ol>
103 <li>Ensure your Killamix Mini is connected to your computer via USB.</li>
104 <li>Use a Web MIDI API compatible browser (Chrome, Edge, or Opera).</li>
105 <li>Click the "Connect MIDI" button in the app.</li>
106 <li>In the MIDI device selection popup, choose your Killamix Mini.</li>
13 // Los Angeles coordinates with Fahrenheit units
14 const response = await fetch(
15 "https://api.open-meteo.com/v1/forecast?latitude=34.0522&longitude=-118.2437¤t=temperature_2m,relative_humidity_2m,wind_speed_10m,weather_code&temperature_unit=fahrenheit&wind_speed_unit=mph&timezone=America%2FLos_Angeles"
16 );
17
13 try {
14 const response = await fetch(
15 `https://api.open-meteo.com/v1/forecast?latitude=${location.latitude}&longitude=${location.longitude}¤t_weather=true&hourly=temperature_2m,weathercode&daily=weathercode,temperature_2m_max,temperature_2m_min&timezone=auto`
16 );
17 const data = await response.json();
29 try {
30 const response = await fetch(
31 `https://geocoding-api.open-meteo.com/v1/search?name=${cityName}&count=1&language=en&format=json`
32 );
33 const locationData = await response.json();
332
333const css = `
334 @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600&display=swap');
335
336 :root {
664async function server(request: Request): Promise<Response> {
665 if (request.method === "POST" && new URL(request.url).pathname === "/generate-training") {
666 const YOUTUBE_API_KEY = Deno.env.get("YOUTUBE_API_KEY2");
667 const useApiKey = YOUTUBE_API_KEY !== undefined && YOUTUBE_API_KEY !== "";
668 if (!YOUTUBE_API_KEY) {
669 console.warn("YouTube API key (YOUTUBE_API_KEY2) is not set. Falling back to search URL method.");
670 }
671
722 for (const placeholder of videoPlaceholders) {
723 const searchQuery = placeholder.replace('[VIDEO: ', '').replace(']', '');
724 const videoId = await getYouTubeVideoId(searchQuery, sport, YOUTUBE_API_KEY);
725 if (videoId) {
726 const embedHtml = `
805}
806
807async function getYouTubeVideoId(query, sport, apiKey, useApiKey = true) {
808 if (useApiKey) {
809 try {
810 const searchUrl = `https://www.googleapis.com/youtube/v3/search?part=snippet&q=${encodeURIComponent(sport + ' ' + query)}&key=${apiKey}&type=video&maxResults=1`;
811 const response = await fetch(searchUrl);
812 const data = await response.json();
813 if (data.error) {
814 console.warn("YouTube API error:", data.error.message);
815 return getFallbackYouTubeLink(query, sport);
816 }
819 }
820 } catch (error) {
821 console.error("Error fetching from YouTube API:", error);
822 }
823 }
7
8const css = `
9 @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600&display=swap');
10
11 :root {
224 const openai = new OpenAI({
225 // Add any necessary configuration if required
226 // For example: apiKey might be needed depending on the library version
227 });
228