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}`);