eventsCalendarserver.ts6 matches
1314import { Hono } from "npm:hono@4";
15import { SSEStreamingApi, stream, streamSSE } from "npm:hono@4/streaming";
16import { html, raw } from "npm:hono@4/html";
17import process from "node:process";
27return streamSSE(c, async (stream) => {
28// validate token
29const apiToken = c.req.query("token");
30if (apiToken !== process.env.API_TOKEN) {
31await fail(stream, "Unauthorized");
32return stream.close();
209});
210211function update(stream: SSEStreamingApi, payload: any) {
212return stream.writeSSE({
213event: "update",
220221function complete(
222stream: SSEStreamingApi,
223state: "success" | "error",
224) {
233234function fail(
235stream: SSEStreamingApi,
236message?: string,
237) {
eventsCalendarlogs.tsx1 match
20export const dashboard = async (req) => {
21const token = new URL(req.url).searchParams.get("token");
22if (token !== process.env.API_TOKEN) {
23return new Response("Token required to view logs", { status: 403 });
24}
TopTenVideosREADME.md2 matches
80```
81https://yoursite.com/custom-header.html
82https://api.yoursite.com/generate-header
83https://cdn.example.com/headers/analysis.html
84```
146- **Safe External Links**: `noopener noreferrer` attributes
147- **Input Validation**: URL validation for all inputs
148- **XSS Protection**: Proper HTML escaping
149- **Error Boundaries**: Graceful error handling
150
TopTenVideosindex.html2 matches
674});
675
676// Here you could make an API call to your backend
677console.log('Selected niche data:', {
678niche,
767`;
768
769// Sample video data (you can replace this with real API data)
770const sampleVideos = [
771{
TopTenVideosindex.html30 matches
90<!-- Setup Instructions -->
91<div id="setup-info" class="max-w-4xl mx-auto mt-12 bg-blue-50 border border-blue-200 rounded-lg p-6">
92<h3 class="text-lg font-semibold text-blue-800 mb-3">๐ง YouTube API Setup Guide</h3>
93
94<!-- API Key Tester -->
95<div class="mb-6 bg-white p-4 rounded-lg border">
96<h4 class="font-semibold text-gray-800 mb-3">๐งช Test Your API Key</h4>
97<div class="flex gap-3">
98<input
99type="text"
100id="test-api-key"
101placeholder="Paste your YouTube API key here to test it..."
102class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm font-mono"
103>
113
114<div class="mb-6">
115<h4 class="font-semibold text-blue-800 mb-2">Step 1: Create API Key</h4>
116<ol class="list-decimal list-inside text-blue-700 space-y-1 mb-4 ml-4">
117<li>Go to <a href="https://console.developers.google.com/" target="_blank" class="underline font-medium">Google Cloud Console</a></li>
118<li>Create a new project or select an existing one</li>
119<li>Go to "APIs & Services" โ "Library"</li>
120<li>Search for and enable <strong>"YouTube Data API v3"</strong></li>
121<li>Go to "APIs & Services" โ "Credentials"</li>
122<li>Click "Create Credentials" โ "API Key"</li>
123<li>Copy your API key</li>
124</ol>
125</div>
126127<div class="mb-6">
128<h4 class="font-semibold text-blue-800 mb-2">Step 2: Configure API Key</h4>
129<ol class="list-decimal list-inside text-blue-700 space-y-1 mb-4 ml-4">
130<li>In Val Town, go to your environment variables</li>
131<li>Add a new variable named: <code class="bg-blue-100 px-2 py-1 rounded font-mono">YOUTUBE_API_KEY</code></li>
132<li>Paste your API key as the value</li>
133<li>Save the environment variable</li>
134</ol>
139<div class="space-y-3 text-sm">
140<div class="bg-white p-3 rounded border-l-4 border-yellow-400">
141<strong class="text-gray-800">API Key Invalid Error:</strong>
142<ul class="mt-1 text-gray-700 list-disc list-inside ml-4">
143<li>Double-check your API key is copied correctly (no extra spaces)</li>
144<li>Ensure YouTube Data API v3 is enabled in Google Cloud Console</li>
145<li>Wait a few minutes after creating the key for it to activate</li>
146<li>Try removing all API restrictions temporarily</li>
147</ul>
148</div>
150<strong class="text-gray-800">Quota Exceeded Error:</strong>
151<ul class="mt-1 text-gray-700 list-disc list-inside ml-4">
152<li>YouTube API has daily quotas (10,000 units/day for free tier)</li>
153<li>Each search uses ~100 units, so you can do ~100 searches per day</li>
154<li>Reset happens at midnight Pacific Time</li>
159160<p class="text-sm text-blue-600">
161๐ก <strong>Good news:</strong> The YouTube Data API is completely free for personal use with generous daily quotas!
162</p>
163</div>
185
186async handleTestKey() {
187const testKeyInput = document.getElementById('test-api-key');
188const testKeyBtn = document.getElementById('test-key-btn');
189const resultDiv = document.getElementById('key-test-result');
190const apiKey = testKeyInput.value.trim();
191
192if (!apiKey) {
193this.showKeyTestResult('Please enter an API key to test', 'error');
194return;
195}
198testKeyBtn.textContent = 'Testing...';
199resultDiv.className = 'mt-3 p-3 bg-gray-100 rounded text-sm';
200resultDiv.innerHTML = '๐ Testing API key...';
201resultDiv.classList.remove('hidden');
202
203try {
204const response = await fetch('/api/test-key', {
205method: 'POST',
206headers: { 'Content-Type': 'application/json' },
207body: JSON.stringify({ apiKey })
208});
209const data = await response.json();
210
211if (data.success) {
212this.showKeyTestResult(`โ API key is valid! Found ${data.sampleData.videoCount} video(s).`, 'success');
213} else {
214this.showKeyTestResult(`โ API key failed: ${data.error}`, 'error');
215}
216} catch (error) {
250
251try {
252const response = await fetch(`/api/videos?niche=${encodeURIComponent(niche)}`);
253const data = await response.json();
254
TopTenVideosapp.js10 matches
19
20async handleTestKey() {
21const testKeyInput = document.getElementById('test-api-key');
22const testKeyBtn = document.getElementById('test-key-btn');
23const resultDiv = document.getElementById('key-test-result');
24const apiKey = testKeyInput.value.trim();
25
26if (!apiKey) {
27this.showKeyTestResult('Please enter an API key to test', 'error');
28return;
29}
32testKeyBtn.textContent = 'Testing...';
33resultDiv.className = 'mt-3 p-3 bg-gray-100 rounded text-sm';
34resultDiv.innerHTML = '๐ Testing API key...';
35resultDiv.classList.remove('hidden');
36
37try {
38const response = await fetch('/api/test-key', {
39method: 'POST',
40headers: { 'Content-Type': 'application/json' },
41body: JSON.stringify({ apiKey })
42});
43const data = await response.json();
44
45if (data.success) {
46this.showKeyTestResult(`โ API key is valid! Found ${data.sampleData.videoCount} video(s).`, 'success');
47} else {
48this.showKeyTestResult(`โ API key failed: ${data.error}`, 'error');
49}
50} catch (error) {
84
85try {
86const response = await fetch(`/api/videos?niche=${encodeURIComponent(niche)}`);
87const data = await response.json();
88
TopTenVideosindex.ts34 matches
73});
7475// API key tester endpoint
76app.post("/api/test-key", async (c) => {
77const body = await c.req.json();
78const testKey = body.apiKey;
79
80if (!testKey) {
81return c.json({ error: "API key is required" }, 400);
82}
83
84try {
85const testUrl = `https://www.googleapis.com/youtube/v3/search?part=snippet&q=test&maxResults=1&key=${testKey}`;
86const testResponse = await fetch(testUrl);
87const responseData = await testResponse.json();
90return c.json({
91success: true,
92message: "API key is valid and working!",
93sampleData: {
94videoCount: responseData.items?.length || 0,
111}
112});
113app.get("/api/debug", async (c) => {
114const apiKey = Deno.env.get("YOUTUBE_API_KEY");
115
116if (!apiKey) {
117return c.json({
118hasApiKey: false,
119message: "No API key found in environment variables"
120});
121}
122
123// Test the API key with a simple request
124try {
125const testUrl = `https://www.googleapis.com/youtube/v3/search?part=snippet&q=test&maxResults=1&key=${apiKey}`;
126const testResponse = await fetch(testUrl);
127const responseText = await testResponse.text();
128
129return c.json({
130hasApiKey: true,
131keyLength: apiKey.length,
132keyPrefix: apiKey.substring(0, 8) + "...",
133testStatus: testResponse.status,
134testOk: testResponse.ok,
135testResponse: testResponse.ok ? "API key works!" : responseText.substring(0, 500)
136});
137} catch (error) {
138return c.json({
139hasApiKey: true,
140keyLength: apiKey.length,
141keyPrefix: apiKey.substring(0, 8) + "...",
142testError: error.message
143});
145});
146147// API endpoint to search YouTube videos
148app.get("/api/videos", async (c) => {
149const niche = c.req.query("niche");
150const apiKey = Deno.env.get("YOUTUBE_API_KEY");
151
152if (!niche) {
154}
155
156if (!apiKey) {
157return c.json({ error: "YouTube API key not configured" }, 500);
158}
159
160try {
161// Search for videos
162const searchUrl = `https://www.googleapis.com/youtube/v3/search?part=snippet&q=${encodeURIComponent(niche)}&type=video&order=relevance&maxResults=10&key=${apiKey}`;
163
164const searchResponse = await fetch(searchUrl);
165if (!searchResponse.ok) {
166const errorText = await searchResponse.text();
167console.error(`YouTube API error details:`, errorText);
168
169// Parse error for better user feedback
170try {
171const errorData = JSON.parse(errorText);
172if (errorData.error?.message?.includes("API key not valid")) {
173return c.json({
174error: "Invalid YouTube API Key",
175details: "Your API key is not valid. Please check that:\n1. The API key is correct\n2. YouTube Data API v3 is enabled for your project\n3. The API key has the proper permissions"
176}, 400);
177}
178if (errorData.error?.message?.includes("quota")) {
179return c.json({
180error: "YouTube API Quota Exceeded",
181details: "You've reached your daily quota limit. Try again tomorrow or upgrade your quota."
182}, 429);
183}
184return c.json({
185error: "YouTube API Error",
186details: errorData.error?.message || `HTTP ${searchResponse.status}`
187}, searchResponse.status);
188} catch {
189return c.json({
190error: "YouTube API Error",
191details: `HTTP ${searchResponse.status}: ${errorText}`
192}, searchResponse.status);
200
201// Get video statistics and duration
202const detailsUrl = `https://www.googleapis.com/youtube/v3/videos?part=statistics,contentDetails&id=${videoIds}&key=${apiKey}`;
203
204const detailsResponse = await fetch(detailsUrl);
untitled-2035main.ts3 matches
51const [nflResponse, fantasyResponse] = await Promise.all([
52fetch(
53"http://site.api.espn.com/apis/site/v3/sports/football/nfl/scoreboard",
54),
55fetch(
56`https://lm-api-reads.fantasy.espn.com/apis/v3/games/ffl/seasons/${YEAR}/segments/0/leagues/${LEAGUE_ID}?view=mMatchup&view=mMatchupScore&view=mTeam&view=mRoster&view=mLiveScoring&scoringPeriodId=${currentWeek}`,
57{
58headers: {
311// Use kona_player_info view to get ALL players including free agents
312const allPlayersUrl =
313`https://lm-api-reads.fantasy.espn.com/apis/v3/games/ffl/seasons/${YEAR}/segments/0/leagues/${LEAGUE_ID}?view=kona_player_info&scoringPeriodId=${week}`;
314315const allPlayersResponse = await fetch(allPlayersUrl, {
1415const response = await fetch(
16"https://http-proxy.val.run/?finalUrl=https%3A%2F%2Fegs-platform-service.store.epicgames.com%2Fapi%2Fv2%2Fpublic%2Fdiscover%2Fhome%3Fcount%3D10%26country%3DPT%26locale%3Den%26platform%3Dandroid%26start%3D0%26store%3DEGS",
17);
18const json = await response.json();
1415const response = await fetch(
16"https://http-proxy.val.run/?finalUrl=https%3A%2F%2Fegs-platform-service.store.epicgames.com%2Fapi%2Fv2%2Fpublic%2Fdiscover%2Fhome%3Fcount%3D10%26country%3DPT%26locale%3Den%26platform%3Dios%26start%3D0%26store%3DEGS",
17);
18const json = await response.json();