Runs every 1 hrs
Fork
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
import { email } from "https://esm.town/v/std/email?v=9";
import { discordWebhook } from "https://esm.town/v/stevekrouse/discordWebhook";
import { searchParams } from "https://esm.town/v/stevekrouse/searchParams";
import { twitterJSON } from "https://esm.town/v/stevekrouse/twitterJSON";
const query = "buttondown";
export async function twitterSearch({
query,
start_time,
bearerToken,
...rest
}: {
query?: string;
start_time?: Date;
bearerToken: string;
}): Promise<TweetResult[]> {
const { data } = await twitterJSON({
url: `https://api.twitter.com/2/tweets/search/recent?query=${await searchParams(
{
query,
start_time: start_time?.toISOString(),
expansions: "author_id",
...rest,
},
)}`,
bearerToken: bearerToken,
});
console.log(data);
return Promise.all(
(data || []).map(async (tweet) => {
const { data: author } = await twitterUser({
id: tweet.author_id,
bearerToken,
});
return {
...tweet,
author_name: author?.name,
author_username: author?.username,
};
}),
);
}
interface TweetResult {
author_id: string;
text: string;
id: string;
edit_history_tweet_ids: string[];
author_name?: string;
author_username?: string;
}
export default async function twitterAlert({ lastRunAt }: Interval) {
const results = await twitterSearch({
query,
bearerToken: Deno.env.get("TWITTER_API_KEY"),
});
console.log("Here!", results);
if (!results.length) return;
// format results
let content = results
.map(({ author_name, author_username, text, id }) => `https://twitter.com/${author_username}/status/${id}`)
.join("\n");
// notify
await email({
html: content,
subject: `New post in Twitter`,
});
}
👆 This is a val. Vals are TypeScript snippets of code, written in the browser and run on our servers. Create scheduled functions, email yourself, and persist small pieces of data — all from the browser.