140
141async function fetchThreadmarksFromServer(url, chapterTitles) {
142 const response = await fetch("/api/threadmarks", {
143 method: "POST",
144 headers: {
154}
155
156async function getThreadmarkUrls(baseUrl, apiKey) {
157 versionLogger(import.meta.url);
158 const startTime = Date.now();
166 console.log(`[INFO] Constructing URL for category ${category}: ${threadmarkUrl}`);
167
168 const scrapingBeeUrl = `https://app.scrapingbee.com/api/v1/?api_key=${apiKey}&url=${
169 encodeURIComponent(threadmarkUrl)
170 }&render_js=false`;
171
172 const requestStartTime = Date.now();
173 const response = await fetch(scrapingBeeUrl);
174 const requestDuration = Date.now() - requestStartTime;
175
311 console.log(`Received ${request.method} request for path: ${new URL(request.url).pathname}`);
312
313 if (request.method === "POST" && new URL(request.url).pathname === "/api/threadmarks") {
314 const apiKey = Deno.env.get("ScrapingBeeAPIkey");
315 if (!apiKey) {
316 console.error("[ERROR] API key not found in environment variables");
317 return new Response(JSON.stringify({ error: "API key not found in environment variables" }), {
318 status: 500,
319 headers: { "Content-Type": "application/json" },
324 const { url, chapterTitles } = await request.json();
325 // console.log(`[INFO] Received request to fetch threadmarks for URL: ${url}`);
326 const threadmarks = await getThreadmarkUrls(url, apiKey);
327 console.log(`[INFO] Retrieved ${threadmarks.length} threadmarks`);
328
124
125 if (!response.ok) {
126 throw new Error(`iTunes API error: ${response.status}`);
127 }
128
1Helper function to call [SocialData](https://socialdata.tools) Twitter Search API, via my proxy: @stevekrouse/socialDataProxy
2
3Migrated from folder: social_data/socialDataSearch
3
4const query = "\"val.town\" OR \"val.run\" OR \"val town\" -_ValTown_ -is:retweet -from:valenzuelacity";
5const url = new URL("https://api.socialdata.tools/twitter/search");
6
7export async function twitterAlert({ lastRunAt }: Interval) {
10 url.searchParams.append("query", query + " since_time:" + since);
11 const { tweets } = await fetchJSON(url.toString(), {
12 bearer: Deno.env.get("SOCIAL_DATA_API_KEY"),
13 });
14
5## 1. Authentication
6
7This val gets data from the https://socialdata.tools/ API.
8
9You'll need to make an account and pre-load your wallet with ~$10.
10
11Add your `SOCIAL_DATA_API_KEY` to your [Val Town Envionrment Variables](https://www.val.town/settings/environment-variables).
12
13## 2. Query
15Change the `query` variable for what you want to get notified for.
16
17You 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!
18
19## 3. Notification
1Migrated from folder: fanficSearcher/ScrapingBeeAttempt/ThreadmarkLISTFetcher2
140
141async function fetchThreadmarksFromServer(url, chapterTitles) {
142 const response = await fetch("/api/threadmarks", {
143 method: "POST",
144 headers: {
154}
155
156async function getThreadmarkUrls(baseUrl, apiKey) {
157 versionLogger(import.meta.url);
158 console.log(`[START] Threadmark URL fetch for base URL: ${baseUrl}`);
167 console.log(`[INFO] Constructing URL for category ${category}: ${threadmarkUrl}`);
168
169 const scrapingBeeUrl = `https://app.scrapingbee.com/api/v1/?api_key=${apiKey}&url=${
170 encodeURIComponent(threadmarkUrl)
171 }&render_js=true`;
172 console.log(`[INFO] Sending GET request to ScrapingBee API for category ${category}`);
173
174 const requestStartTime = Date.now();
175 const response = await fetch(scrapingBeeUrl);
176 console.log(
177 `Response received. Status: ${response.status}, Headers: ${
337 console.log(`Received ${request.method} request for path: ${new URL(request.url).pathname}`);
338
339 if (request.method === "POST" && new URL(request.url).pathname === "/api/threadmarks") {
340 const apiKey = Deno.env.get("ScrapingBeeAPIkey");
341 if (!apiKey) {
342 console.error("[ERROR] API key not found in environment variables");
343 return new Response(JSON.stringify({ error: "API key not found in environment variables" }), {
344 status: 500,
345 headers: { "Content-Type": "application/json" },
350 const { url, chapterTitles } = await request.json();
351 console.log(`[INFO] Received request to fetch threadmarks for URL: ${url}`);
352 const threadmarks = await getThreadmarkUrls(url, apiKey);
353 console.log(`[INFO] Retrieved ${threadmarks.length} threadmarks`);
354
21// View at https://wallek-currencyTransaction.val.run?target=gbp&root=eur&amount=100
22export default async function(req: Request): Promise<Response> {
23 const { rates } = await fetchJSON(`https://api.exchangerate-api.com/v4/latest/USD`);
24
25 // USD is the base currency, so we need to add it manually
1// Initialize Airtable configuration
2const airtableApiKey = Deno.env.get("AIRTABLE_API_KEY");
3const baseId = Deno.env.get("AIRTABLE_BASE_ID");
4const tableName = Deno.env.get("AIRTABLE_TABLE_NAME");
5
6async function fetchAirtableData(uid: string) {
7 if (!airtableApiKey || !baseId || !tableName) {
8 throw new Error("Missing Airtable environment variables");
9 }
10
11 const url = `https://api.airtable.com/v0/${baseId}/${tableName}?filterByFormula=UID%3D%22${encodeURIComponent(uid)}%22`;
12 const response = await fetch(url, {
13 headers: {
14 Authorization: `Bearer ${airtableApiKey}`,
15 },
16 });
12 <title>Title</title>
13 <style>{"html { font-family: sans-serif; }"}</style>
14 <style>@import url('https://fonts.googleapis.com/css2?family=Inter&display=swap');</style><div class="newsletter-form-container"><form class="newsletter-form" action="https://app.loops.so/api/newsletter-form/clbv5du7z04g2ju08qcznl56v" method="POST" style="display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%;"><input class="newsletter-form-input" name="newsletter-form-input" type="email" placeholder="you@best-email.com" required="" style="font-family: Inter, sans-serif; color: rgb(0, 0, 0); font-size: 14px; margin: 0px 0px 10px; width: 100%; max-width: 300px; min-width: 100px; background: rgb(255, 255, 255); border: 1px solid rgb(209, 213, 219); box-sizing: border-box; box-shadow: rgba(0, 0, 0, 0.05) 0px 1px 2px; border-radius: 6px; padding: 8px 12px;"><button type="submit" class="newsletter-form-button" style="background: rgb(41, 176, 68); font-size: 14px; color: rgb(255, 255, 255); font-family: Inter, sans-serif; display: flex; width: 100%; max-width: 300px; white-space: normal; height: 38px; align-items: center; justify-content: center; flex-direction: row; padding: 9px 17px; box-shadow: rgba(0, 0, 0, 0.05) 0px 1px 2px; border-radius: 6px; text-align: center; font-style: normal; font-weight: 500; line-height: 20px; border: none; cursor: pointer;">Subscribe to Replicate Intelligence</button><button type="button" class="newsletter-loading-button" style="background: rgb(41, 176, 68); font-size: 14px; color: rgb(255, 255, 255); font-family: Inter, sans-serif; display: none; width: 100%; max-width: 300px; white-space: normal; height: 38px; align-items: center; justify-content: center; flex-direction: row; padding: 9px 17px; box-shadow: rgba(0, 0, 0, 0.05) 0px 1px 2px; border-radius: 6px; text-align: center; font-style: normal; font-weight: 500; line-height: 20px; border: none; cursor: pointer;">Please wait...</button></form><div class="newsletter-success" style="display: none; align-items: center; justify-content: center; width: 100%;"><p class="newsletter-success-message" style="font-family: Inter, sans-serif; color: rgb(0, 0, 0); font-size: 14px;">You're subscribed! 🚀</p></div><div class="newsletter-error" style="display: none; align-items: center; justify-content: center; width: 100%;"><p class="newsletter-error-message" style="font-family: Inter, sans-serif; color: rgb(185, 28, 28); font-size: 14px;">Oops! Something went wrong, please try again</p></div>
15
16 <script src="https://unpkg.com/htmx.org@1.9.9"></script>