Public
Cron
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { hackerNewsSearch } from "https://esm.town/v/alexdphan/hackerNewsSearch";
import { twitterSearch } from "https://esm.town/v/alexdphan/twitterSearch";
import { redditSearch } from "https://esm.town/v/sarahxc/redditSearch";
const { sqlite } = await import("https://esm.town/v/std/sqlite");
const TABLE_NAME = "slack_scout_browserbase";
const KEYWORDS = ["headless browsers", "browserbase"];
interface Website {
source: string;
url: string;
title?: string;
date_published: string;
}
export default async function(interval: Interval): Promise<void> {
try {
await createTable();
for (const topic of KEYWORDS) {
const results = await Promise.allSettled([
fetchHackerNewsResults(topic),
fetchTwitterResults(topic),
fetchRedditResults(topic),
]);
const validResults = results
.filter((result): result is PromiseFulfilledResult<Website[]> => result.status === "fulfilled")
.flatMap(result => result.value);
await processResults(validResults);
}
console.log("Cron job completed successfully.");
} catch (error) {
console.error("An error occurred during the cron job:", error);
}
}
// Create an SQLite table
async function createTable(): Promise<void> {
await sqlite.execute(`
CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (
source TEXT NOT NULL,
url TEXT PRIMARY KEY,
title TEXT NOT NULL,
date_published TEXT NOT NULL
)
`);
}
// Fetch Hacker news, Twitter, and Reddit results
async function fetchHackerNewsResults(topic: string): Promise<Website[]> {
return hackerNewsSearch({
query: topic,
pages: 2,
apiKey: Deno.env.get("BROWSERBASE_API_KEY") ?? "",
});
}
async function fetchTwitterResults(topic: string): Promise<Website[]> {
return twitterSearch({
query: topic,
maxResults: 10,
daysBack: 1,
apiKey: Deno.env.get("TWITTER_BEARER_TOKEN") ?? "",
});
}
async function fetchRedditResults(topic: string): Promise<Website[]> {
return redditSearch({ query: topic });
}
function formatSlackMessage(website: Website): string {
const displayTitle = website.title || website.url;
return `*<${website.url}|${displayTitle}>*
Source: ${website.source}
Posted: ${website.date_published}`;
}
async function sendSlackMessage(message: string): Promise<Response> {
const slackWebhookUrl = Deno.env.get("SLACK_WEBHOOK_URL");
if (!slackWebhookUrl) {
throw new Error("SLACK_WEBHOOK_URL environment variable is not set");
}
const response = await fetch(slackWebhookUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
blocks: [
{
type: "section",
text: { type: "mrkdwn", text: message },
},
],
}),
});
if (!response.ok) {
throw new Error(`Slack API error: ${response.status} ${response.statusText}`);
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
September 4, 2024
Exactly what I've been looking for! Would it work for Google Chat via Zapier as well?
Would love to have the Twitter API token so I can try this out with Browserbase :)
Hi Sarah I'd appreciate if I could get access to the Twitter API token so I can try this out! Thanks.