forked from rebelchris/daily-dev-tips
-
Notifications
You must be signed in to change notification settings - Fork 0
/
collect.mjs
100 lines (86 loc) · 2.55 KB
/
collect.mjs
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 fs from 'fs';
import { loadEnv } from 'vite';
import { polyfill } from '@astrojs/webapi';
polyfill(globalThis, {
exclude: 'window document',
});
const {
PUBLIC_SENDY_ENDPOINT,
PUBLIC_SENDY_API_KEY,
PUBLIC_SENDY_LIST_ID,
PUBLIC_WEBMENTION_TOKEN,
} = loadEnv('production', process.cwd(), '');
const SUB_CACHE_FILE_PATH = '_cache/subscribers.json';
const WEBMENTION_CACHE_FILE_PATH = '_cache/webmentions.json';
const API = 'https://webmention.io/api';
const readCache = (file) => {
if (fs.existsSync(file)) {
const cacheFile = fs.readFileSync(file);
return JSON.parse(cacheFile);
}
// no cache found.
return {
lastFetched: null,
children: [],
};
};
const writeCache = (file, data) => {
fs.writeFile(file, JSON.stringify(data), (err) => {
if (err) throw err;
console.log(`>>> ${file} cached successfully`);
});
};
const fetchSubscribers = async () => {
const response = await fetch(
`${PUBLIC_SENDY_ENDPOINT}api/subscribers/active-subscriber-count.php`,
{
method: 'POST',
body: new URLSearchParams(
`api_key=${PUBLIC_SENDY_API_KEY}&list_id=${PUBLIC_SENDY_LIST_ID}`
),
}
);
const allSubscribers = await response.text();
return allSubscribers;
};
const fetchWebmentions = async (since, perPage = 10000) => {
let url = `${API}/mentions.jf2?domain=daily-dev-tips.com&token=${PUBLIC_WEBMENTION_TOKEN}&per-page=${perPage}`;
if (since) url += `&since=${since}`;
const response = await fetch(url);
if (response.ok) {
const feed = await response.json();
console.log(`>>> ${feed.children.length} new webmentions fetched`);
return feed;
}
return [];
};
const fetchAndCacheSubscribers = async () => {
const subscribers = await fetchSubscribers();
const data = {
lastFetched: Date.now(),
amount: subscribers,
};
writeCache(SUB_CACHE_FILE_PATH, data);
};
const mergeWebmentions = (a, b) => {
const merged = [...a.children, ...b.children];
const uniqueData = [
...merged
.reduce((map, obj) => map.set(obj['wm-id'], obj), new Map())
.values(),
];
return uniqueData;
};
const fetchAndCacheWebmentions = async () => {
const existingWebmentions = await readCache(WEBMENTION_CACHE_FILE_PATH);
const mentions = await fetchWebmentions(existingWebmentions.lastFetched);
if (mentions) {
const webmentions = {
lastFetched: new Date().toISOString(),
children: mergeWebmentions(existingWebmentions, mentions),
};
writeCache(WEBMENTION_CACHE_FILE_PATH, webmentions);
}
};
fetchAndCacheSubscribers();
fetchAndCacheWebmentions();