Readme

Slack scout sends a slack notification every time your keywords are mentioned on Twitter, Hacker News, or Reddit. Get notified whenever you, your company, or topics of interest are mentioned online.

Built with Browserbase. Inspired by f5bot.com.

Full code tutorial.

Getting Started

To run Slack Scout, you’ll need a

  • Browserbase API key
  • Slack Webhook URL: setup here
  • Twitter Developer API key

Browserbase

Browserbase is a developer platform to run, manage, and monitor headless browsers at scale. We’ll use Browserbase to navigate to, and scrape our different news sources. We’ll also use Browserbase’s Proxies to ensure we simulate authentic user interactions across multiple browser sessions.

Get started with Browserbase for free here.

Twitter

We’ve decided to use the Twitter API to include Twitter post results. It costs $100 / month to have a Basic Twitter Developer account. If you decide to use Browserbase, we can lend our token. Comment below for access.

Once you have the SLACK_WEBHOOK_URL, BROWSERBASE_API_KEY, and TWITTER_BEARER_TOKEN, input all of these as Val Town Environment Variables.


Project created by Sarah Chieng and Alex Phan 💌

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.
Comments
3
colestark avatar

Exactly what I've been looking for! Would it work for Google Chat via Zapier as well?

colestark avatar

Would love to have the Twitter API token so I can try this out with Browserbase :)

fahadakhan2 avatar

Hi Sarah I'd appreciate if I could get access to the Twitter API token so I can try this out! Thanks.

September 4, 2024