-
Notifications
You must be signed in to change notification settings - Fork 8
/
index.js
140 lines (131 loc) · 3.52 KB
/
index.js
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
const functions = require("@google-cloud/functions-framework");
const { BskyAgent, AppBskyFeedPost } = require("@atproto/api");
const cheerio = require("cheerio");
const sharp = require("sharp");
const Parser = require("rss-parser");
const parser = new Parser();
const settings = [
{
account: "bbcnews-uk-rss.bsky.social",
password: "xxxx-xxxx-xxxx-xxxx",
url: "https://feeds.bbci.co.uk/news/uk/rss.xml#",
},
{
account: "bbcnews-world-rss.bsky.social",
password: "xxxx-xxxx-xxxx-xxxx",
url: "https://feeds.bbci.co.uk/news/world/rss.xml#",
},
{
account: "apnews-world-rss.bsky.social",
password: "xxxx-xxxx-xxxx-xxxx",
url: "https://rsshub.app/apnews/topics/world-news",
},
];
async function get_feeds(url) {
const feed = await parser.parseURL(url);
let output = [];
for (const item of feed.items) {
output.push({
title: item.title,
link: item.link,
});
}
return output;
}
async function post(agent, item) {
let post = {
$type: "app.bsky.feed.post",
text: item.title,
createdAt: new Date().toISOString(),
};
const dom = await fetch(item.link)
.then((response) => response.text())
.then((html) => cheerio.load(html));
let description = null;
const description_ = dom('head > meta[property="og:description"]');
if (description_) {
description = description_.attr("content");
}
let image_url = null;
const image_url_ = dom('head > meta[property="og:image"]');
if (image_url_) {
image_url = image_url_.attr("content");
}
const buffer = await fetch(image_url)
.then((response) => response.arrayBuffer())
.then((buffer) => sharp(buffer))
.then((s) =>
s.resize(
s
.resize(800, null, {
fit: "inside",
withoutEnlargement: true,
})
.jpeg({
quality: 80,
progressive: true,
})
.toBuffer()
)
);
const image = await agent.uploadBlob(buffer, { encoding: "image/jpeg" });
post["embed"] = {
external: {
uri: item.link,
title: item.title,
description: description,
thumb: image.data.blob,
},
$type: "app.bsky.embed.external",
};
const res = AppBskyFeedPost.validateRecord(post);
if (res.success) {
console.log(post);
// await agent.post(post);
} else {
console.log(res.error);
}
}
async function main(setting) {
const agent = new BskyAgent({ service: "https://bsky.social" });
await agent.login({
identifier: setting.account,
password: setting.password,
});
let processed = new Set();
let cursor = "";
for (let i = 0; i < 3; ++i) {
const response = await agent.getAuthorFeed({
actor: setting.account,
limit: 100,
cursor: cursor,
});
cursor = response.cursor;
for (const feed of response.data.feed) {
processed.add(feed.post.record.embed.external.uri);
processed.add(feed.post.record.text);
}
}
for (const feed of await get_feeds(setting.url)) {
if (!processed.has(feed.title) && !processed.has(feed.link)) {
await post(agent, feed);
} else {
console.log("skipped " + feed.title);
}
}
}
// async function entrypoint() {
// for (const setting of settings) {
// console.log("process " + setting.url);
// await main(setting);
// }
// console.log("--- finish ---");
// }
// entrypoint();
functions.cloudEvent("entrypoint", async (_) => {
for (const setting of settings) {
console.log("process " + setting.url);
await main(setting);
}
console.log("--- finish ---");
});