discord-botApp.tsx4 matches
21const [error, setError] = useState<string | null>(null);
22
23// Fetch server health status on component mount
24useEffect(() => {
25async function checkHealth() {
26try {
27setStatus('loading');
28const response = await fetch('/health');
29if (!response.ok) {
30throw new Error(`Health check failed: ${response.status}`);
116</tr>
117<tr>
118<td className="px-6 py-4 whitespace-nowrap font-mono text-sm">/api/fetch-dms</td>
119<td className="px-6 py-4 whitespace-nowrap text-sm">POST</td>
120<td className="px-6 py-4 text-sm">Manually trigger DM fetching</td>
121</tr>
122<tr>
discord-botDISCORD_BOT_SETUP.md3 matches
112- Find your deployed functions
113- Add the same environment variables from your `.env` file
1145. Set up a scheduled task for periodic DM fetching:
115- Create a new scheduled task in Val.town
116- Use the `discordDMBotCron` function
129- `/analyze Summarize our furniture discussions`
1301313. You can also manually trigger a DM fetch:
132```
133node val-town-cron.js
141- Verify that the bot has proper permissions
142143### Cannot fetch DMs
144- Ensure both you and your spouse have DMed each other at least once
145- Verify that all tokens and IDs in the `.env` file are correct
vt-discordindex.ts2 matches
21});
2223// HTTP vals expect an exported "fetch handler"
24// This is how you "run the server" in Val Town with Hono
25export default app.fetch;
MLSpointsPerMillionmain.tsx30 matches
375}
376377async function fetchClubProfileFromApi(
378transfermarktId: string | null | undefined,
379): Promise<ClubProfile | null> {
382}
383try {
384const response = await fetch(`/api/clubProfile/${transfermarktId}`);
385if (!response.ok) {
386console.error(
387`Failed to fetch profile from API for ${transfermarktId}: ${response.status}`,
388);
389return null;
401} catch (error) {
402console.error(
403`Error fetching profile from API for ${transfermarktId}:`,
404error,
405);
635setIsLoading(true);
636setErrorMessage(null);
637fetch("/api/standings")
638.then((response) => response.json())
639.then((data: Standings) => {
648} else {
649console.error(
650"Fetched standings data is not in the expected format:",
651data,
652);
653setStandings([]);
654setLastUpdated("Error fetching base standings");
655setErrorMessage(
656"Failed to load standings data. Invalid format received.",
660if (data.error) {
661console.warn(
662"Server reported an error fetching standings:",
663data.error,
664);
667})
668.catch((error) => {
669console.error("Error fetching base standings:", error);
670setLastUpdated("Error fetching base standings");
671setErrorMessage(
672`Failed to load standings data: ${(error as Error).message}`,
681setIsLoading(true);
682683const fetchAllProfiles = async () => {
684const allEntries = standings.flatMap((conf) => conf.entries);
685const uniqueTmIds = [
695setClubValues((prev) => ({ ...prev, ...initialValues }));
696697const profilePromises = uniqueTmIds.map((tmId) => fetchClubProfileFromApi(tmId));
698const results = await Promise.allSettled(profilePromises);
699707if (result.status === "rejected") {
708console.error(
709`Failed to fetch profile for ID ${tmId}:`,
710result.reason,
711);
719};
720721fetchAllProfiles();
722}, [standings]);
723876}
877878async function fetchAndCacheClubProfile_SERVER(
879transfermarktId: string,
880): Promise<ClubProfile | null> {
904const options = { method: "GET", headers: { accept: "application/json" } };
905try {
906const response = await fetch(url, options);
907let result: ClubProfile | null = null;
908let errorMsg: string | null = null;
915}
916} else {
917errorMsg = `Club profile fetch failed for ${transfermarktId}: ${response.status} ${await response.text().catch(
918() => ""
919)}`;
936} catch (error) {
937console.error(
938`Error during fetch/process profile for ${transfermarktId}:`,
939error,
940);
944}
945946async function fetchMLSStandings(): Promise<Standings> {
947const KEY = "MLSpointsPerMillion_mls_standings_v2";
948let storedData: Standings | null = null;
962|| now - storedData.timestamp > STANDINGS_CACHE_DURATION
963) {
964console.log("Fetching fresh MLS standings data...");
965const url = "https://major-league-soccer-standings.p.rapidapi.com/";
966const apiKey = Deno.env.get("RAPIDAPI_KEY")
980};
981try {
982const response = await fetch(url, options);
983if (!response.ok) {
984throw new Error(
996storedData = { timestamp: now, standings: result };
997await blob.setJSON(KEY, storedData);
998console.log("Successfully fetched and cached new standings data.");
999return storedData;
1000} catch (error) {
1001console.error("Error fetching or processing MLS standings:", error);
1002if (storedData) {
1003console.warn("Returning stale standings data due to fetch error.");
1004return {
1005...storedData,
1006error: `Failed to fetch fresh standings: ${(error as Error).message}. Displaying cached data.`,
1007};
1008} else {
1010timestamp: now,
1011standings: [],
1012error: `Failed to fetch MLS standings: ${(error as Error).message}`,
1013};
1014}
1030// API endpoint for standings data
1031if (url.pathname === "/api/standings") {
1032const standingsData = await fetchMLSStandings();
1033return new Response(JSON.stringify(standingsData), {
1034headers: headers_json,
1047});
1048try {
1049const profileData = await fetchAndCacheClubProfile_SERVER(transfermarktId);
1050if (profileData)
1051return new Response(JSON.stringify(profileData), {
1054}); else
1055return new Response(
1056JSON.stringify({ error: "Profile not found or fetch failed" }),
1057{ headers: headers_json, status: 404 },
1058);
1059} catch (error) {
1060console.error(`Server error fetching profile ${transfermarktId}:`, error);
1061return new Response(
1062JSON.stringify({
85interface TraversedCitation extends Citation {
86traversalStatus: "success" | "not_attempted" | "failed" | "url_missing";
87fetchedContentSummary?: string; // Note: Original code didn't fetch summary, only status
88error?: string;
89}
479errorInvalidFile: "Invalid file type. Please upload a PDF.",
480errorFileSize: "File is too large (Max {maxSize}).", // Updated to use replacement
481errorFetchFailed: "Failed to perform analysis: {errorMessage}", // Placeholder for dynamic message
482analysisTitle: "Analysis Results", // Keep if needed elsewhere, dashboard cards have own titles now
483loadingAnalysis: "Analyzing Document...",
515errorInvalidFile: "Tipo de archivo inválido. Por favor, suba un PDF.",
516errorFileSize: "El archivo es demasiado grande (Máx {maxSize}).", // Updated
517errorFetchFailed: "Falló la realización del análisis: {errorMessage}",
518analysisTitle: "Resultados del Análisis",
519loadingAnalysis: "Analizando Documento...",
819820try {
821// Fetch from the current location, expecting the Val to handle POST
822const response = await fetch(window.location.pathname + '?format=json', { // Ensure format=json is requested
823method: 'POST',
824headers: { 'Accept': 'application/json'}, // Crucial: Tell server we want JSON back
909console.error('Analysis Request Error:', error);
910// Use the specific error message from the caught error
911displayError('errorFetchFailed', { errorMessage: error.message });
912resultsArea.style.display = 'none';
913} finally {
952const { OpenAI } = await import("https://esm.town/v/std/openai");
953const { z } = await import("npm:zod");
954const { fetch } = await import("https://esm.town/v/std/fetch");
955// Import the PDF extraction library
956const { PDFExtract, PDFExtractOptions } = await import("npm:pdf.js-extract");
1040const traversalPromises = citations.map(async (citation): Promise<TraversedCitation> => {
1041if (citation.potentialUrl) {
1042traversedCount++; // Increment here is slightly inaccurate if fetch fails early, but simpler
1043let status: TraversedCitation["traversalStatus"] = "failed";
1044let errorMsg: string | undefined = undefined;
1045let urlToFetch = citation.potentialUrl;
1046// Basic URL validation/fixing
1047if (!urlToFetch.startsWith('http://') && !urlToFetch.startsWith('https://')) {
1048urlToFetch = 'http://' + urlToFetch; // Default to http if protocol missing
1049}
10501051try {
1052// Log the attempt for this specific URL
1053log.push({ agent, type: "step", message: `Attempting to fetch: ${urlToFetch}` });
1054const response = await fetch(urlToFetch, {
1055headers: { "User-Agent": "ValTownPolicyAnalysisBot/1.0 (+http://val.town)" }, // Be a good bot citizen
1056redirect: "follow", // Follow redirects
1065status = "success";
1066// Log success for this URL
1067log.push({ agent, type: "result", message: `Successfully accessed: ${urlToFetch}` });
1068return { ...citation, potentialUrl: urlToFetch, traversalStatus: status, error: undefined };
1069} catch (error) {
1070errorMsg = `Workspace failed for ${urlToFetch}: ${error.message.substring(0, 100)}`; // Keep error msg concise
1071// Log failure for this URL
1072log.push({ agent, type: "error", message: errorMsg });
1073status = "failed";
1074return { ...citation, potentialUrl: urlToFetch, traversalStatus: status, error: errorMsg };
1075}
1076} else {
1149log.push({ agent: ingestionAgent, type: "step", message: \`Workspaceing from URL: \${input.documentUrl}\` });
1150try {
1151// Basic check for common non-HTTP URL schemes that fetch will reject
1152if (!input.documentUrl.match(/^https?:\/\//i)) {
1153throw new Error("Invalid URL scheme. Only http and https are supported.");
1154}
1155const response = await fetch(input.documentUrl, {
1156headers: { "Accept": "text/plain, text/html, application/pdf", "User-Agent": "ValTownPolicyAnalysisBot/1.0" },
1157redirect: "follow",
1158timeout: 10000 // 10 second timeout for fetching
1159});
1160if (!response.ok) throw new Error(\`HTTP error! Status: \${response.status} \${response.statusText}\`);
1171} else if (contentType.includes("text/html") || contentType.includes("text/plain") || contentType === "") { // Allow empty content type
1172const text = await response.text();
1173if (!text || text.trim().length === 0) throw new Error("Fetched content is empty or not text.");
1174log.push({
1175agent: ingestionAgent,
11851186} catch (error) {
1187const errorMessage = \`Failed to fetch or process URL \${input.documentUrl}: \${error.message}\`;
1188log.push({ agent: ingestionAgent, type: "error", message: errorMessage });
1189documentText = null;
vtProjectSearchimport.ts3 matches
27if (userId && !processedUsers.has(userId)) {
28try {
29// Fetch user data
30const user = await vt.users.retrieve(userId);
3143processedUsers.add(userId);
44} catch (error) {
45console.error(`Error fetching user ${userId}:`, error);
46// Continue with val processing even if user fetch fails
47}
48}
myanythingmain.tsx1 match
2526try {
27const response = await fetch(window.location.href, {
28method: 'POST',
29body: formData
myeverythingmain.tsx1 match
2526try {
27const response = await fetch(window.location.href, {
28method: "POST",
29body: formData,
2526try {
27const response = await fetch(window.location.href, {
28method: "POST",
29body: formData,
FixItWandindex.http.ts1 match
18});
1920export default app.fetch;