-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlemmy-rss-bot.ts
130 lines (109 loc) · 3.34 KB
/
lemmy-rss-bot.ts
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
import LemmyBot from 'lemmy-bot';
import Parser from 'rss-parser';
import moment from 'moment';
import sqlite3 from 'sqlite3';
// federated instance to use
const instanceName = 'feddit.de';
// bot credentials (create bot account first)
const botCredentials = {
username: 'bot-name',
password: 'password'
};
// RSS feed URLs to get articles from
const feedUrls = [
'https://www.abc.de/feed',
'https://www.def.de/feed'
];
// Define the community name where to post
const communityName = 'communityname';
// Define the number of days to consider for filtering
const maxDaysOld = 7;
// Initialize SQLite database to store URLs to prevent double posting (processed items)
const db = new sqlite3.Database('lemmy-bot.db');
// Create table for storing processed item identifiers
db.serialize(() => {
db.run(`
CREATE TABLE IF NOT EXISTS processed_items (
identifier TEXT PRIMARY KEY
)
`);
});
// Function to check if an item has already been processed
const isItemProcessed = (identifier) => {
return new Promise((resolve, reject) => {
db.get('SELECT * FROM processed_items WHERE identifier = ?', [identifier], (err, row) => {
if (err) {
reject(err);
} else {
resolve(!!row);
}
});
});
};
// Function to mark an item as processed
const markItemAsProcessed = (identifier) => {
db.run('INSERT INTO processed_items (identifier) VALUES (?)', [identifier]);
};
// Function to put it all together
const doTheThing = async (botActions) => {
// Task to perform
console.log('Task executed');
const parser = new Parser();
try {
for (const feedUrl of feedUrls) {
const feed = await parser.parseURL(feedUrl);
const cutoffDate = moment().subtract(maxDaysOld, 'days');
for (const item of feed.items) {
const itemDate = moment(item.isoDate);
if (itemDate.isSameOrAfter(cutoffDate)) {
const identifier = item.guid || item.link;
if (await isItemProcessed(identifier)) {
console.log('Skipping already processed item:', item.title);
continue;
}
console.log('New RSS item:', item.title);
// Get the community ID based on the community name
const communityId = await botActions.getCommunityId({
instance: instanceName,
name: communityName
});
if (communityId) {
// Process and handle the new RSS item
const createPostForm = {
name: item.title,
url: item.link,
body: item.contentSnippet,
community_id: communityId
};
await botActions.createPost(createPostForm);
markItemAsProcessed(identifier);
} else {
console.log('Community not found:', communityName);
}
}
}
}
} catch (error) {
console.error('Error fetching or parsing RSS feed:', error);
}
};
const bot = new LemmyBot({
instance: instanceName,
credentials: botCredentials,
connection: {
minutesBeforeRetryConnection: 5,
secondsBetweenPolls: 10,
minutesUntilReprocess: 60
},
federation: 'local',
schedule: [
{
cronExpression: '0 * * * *', // Run once an hour
doTask: doTheThing,
timezone: 'Europe/Berlin',
runAtStart: true
}
],
dbFile: communityName + '-lemmy-bot-db.sqlite3'
});
bot.start();