updates to support configurable intervals, feeds and better hashtag support
This commit is contained in:
parent
8e99a2b491
commit
2c219e1d9e
16
.env.sample
16
.env.sample
@ -1,7 +1,17 @@
|
|||||||
# Mastodon Info
|
# Mastodon Info
|
||||||
MASTODON_ACCESS_KEY=
|
MASTODON_ACCESS_KEY=
|
||||||
MASTODON_API_URL=
|
|
||||||
MASTODON_ACCOUNT_ID=
|
MASTODON_ACCOUNT_ID=
|
||||||
|
MASTODON_API_URL=https://example.com/api/v1/
|
||||||
|
|
||||||
# Prefix for the post
|
# Hashtags for the post
|
||||||
POST_PREFIX=
|
POST_HASHTAG=gaming,videogames,news
|
||||||
|
|
||||||
|
# Number of posts to create
|
||||||
|
MAX_POST_PER_SCAN=2
|
||||||
|
|
||||||
|
# Feeds to scan
|
||||||
|
#3600000 means every hours 60 * 60 * 1000
|
||||||
|
FEED_INTERVAL=3600000
|
||||||
|
|
||||||
|
#isNews = true; will post a contentSnippet. If this is too long choose isNews false to post the shorter summary
|
||||||
|
FEEDS='{"feeds": [{"url": "https://example.com/feeds/feed.atom", "isNews": true, "tag": "Post Tag"}]}'
|
61
bot.js
61
bot.js
@ -8,7 +8,11 @@ const axios = require("axios");
|
|||||||
const urlMetadata = require("url-metadata");
|
const urlMetadata = require("url-metadata");
|
||||||
let Mastodon = require("mastodon-api");
|
let Mastodon = require("mastodon-api");
|
||||||
let Parser = require("rss-parser");
|
let Parser = require("rss-parser");
|
||||||
let parser = new Parser();
|
let parser = new Parser({
|
||||||
|
headers: {
|
||||||
|
Accept: "application/rss+xml, application/xml",
|
||||||
|
},
|
||||||
|
});
|
||||||
let maxPostPerScan = process.env.MAX_POST_PER_SCAN;
|
let maxPostPerScan = process.env.MAX_POST_PER_SCAN;
|
||||||
|
|
||||||
const M = new Mastodon({
|
const M = new Mastodon({
|
||||||
@ -19,15 +23,18 @@ const M = new Mastodon({
|
|||||||
|
|
||||||
const download_image = async (url, image_path) => {
|
const download_image = async (url, image_path) => {
|
||||||
let response = await axios({
|
let response = await axios({
|
||||||
|
method: "get",
|
||||||
url,
|
url,
|
||||||
responseType: "stream",
|
responseType: "stream",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(response);
|
||||||
|
|
||||||
return new Promise((resolve, reject) =>
|
return new Promise((resolve, reject) =>
|
||||||
response.data
|
response.data
|
||||||
.pipe(fs.createWriteStream(image_path))
|
.pipe(fs.createWriteStream(image_path))
|
||||||
.on("finish", () => {
|
.on("finish", () => {
|
||||||
console.log("---- Image Written Succesfully");
|
console.log("---- Image Written Succesfully", url);
|
||||||
resolve(true);
|
resolve(true);
|
||||||
})
|
})
|
||||||
.on("error", (e) => {
|
.on("error", (e) => {
|
||||||
@ -42,7 +49,7 @@ const download_image = async (url, image_path) => {
|
|||||||
|
|
||||||
setInterval(async () => {
|
setInterval(async () => {
|
||||||
await runBot();
|
await runBot();
|
||||||
}, 60 * 60 * 1000);
|
}, process.env.FEED_INTERVAL);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
async function getLastPostDate() {
|
async function getLastPostDate() {
|
||||||
@ -58,49 +65,59 @@ async function getLastPostDate() {
|
|||||||
|
|
||||||
async function readFeeds() {
|
async function readFeeds() {
|
||||||
console.log("Processing Feeds: readFeeds()");
|
console.log("Processing Feeds: readFeeds()");
|
||||||
let feed = await parser.parseURL("http://feeds.feedburner.com/ign/games-all");
|
let feeds = JSON.parse(process.env.FEEDS || {});
|
||||||
return feed;
|
let feed = await parser.parseURL(feeds.feeds[0].url);
|
||||||
|
return { feed, isNews: feeds.feeds[0] };
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processFeed(feed, postDate) {
|
async function processFeed(feed, postDate, feedOptions) {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
let validFeeds = feed.items
|
let validFeeds = feed.items
|
||||||
.filter((item) => {
|
.filter((item) => {
|
||||||
let pubDate = new Date(item.pubDate);
|
let pubDate = new Date(item.pubDate);
|
||||||
return pubDate > postDate;
|
return pubDate < postDate;
|
||||||
})
|
})
|
||||||
.slice(0, maxPostPerScan);
|
.slice(0, maxPostPerScan);
|
||||||
|
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
validFeeds.map(async (item) => {
|
validFeeds.map(async (item) => {
|
||||||
|
let path;
|
||||||
|
|
||||||
|
if (feedOptions.isNews) {
|
||||||
let currentCount = count++;
|
let currentCount = count++;
|
||||||
|
|
||||||
let metadata = await urlMetadata(item.link);
|
let metadata = await urlMetadata(item.link);
|
||||||
|
|
||||||
// Download feed item image
|
// Download feed item image
|
||||||
let path = Path.resolve(
|
path = Path.resolve(__dirname, "images", `post-image-${currentCount}`);
|
||||||
__dirname,
|
|
||||||
"images",
|
|
||||||
`post-image-${currentCount}`
|
|
||||||
);
|
|
||||||
await download_image(metadata.image, path);
|
await download_image(metadata.image, path);
|
||||||
|
}
|
||||||
|
|
||||||
return postFeedItem(path, item);
|
return postFeedItem(path, item, feedOptions);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function postFeedItem(path, item) {
|
async function postFeedItem(path, item, feedOptions) {
|
||||||
|
if (feedOptions.isNews) {
|
||||||
let mediaup = await M.post("media", {
|
let mediaup = await M.post("media", {
|
||||||
file: fs.createReadStream(path),
|
file: fs.createReadStream(path),
|
||||||
});
|
});
|
||||||
|
|
||||||
return M.post("statuses", {
|
return M.post("statuses", {
|
||||||
status: `${item.title}\n\n${
|
status: `${feedOptions.tag}: ${item.title}\n\n${
|
||||||
item.contentSnippet ? "\n\n" + item.contentSnippet : ""
|
item.contentSnippet ? "\n\n" + item.contentSnippet : ""
|
||||||
}\n\n#NeoVibe #${process.env.POST_HASHTAG}\n\n${item.link}`,
|
}\n\n#NeoVibe ${getHashTags()}\n\n${item.link}`,
|
||||||
media_ids: [mediaup.data.id],
|
media_ids: [mediaup.data.id],
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
return M.post("statuses", {
|
||||||
|
status: `${feedOptions.tag}: ${
|
||||||
|
item.title
|
||||||
|
}\n\n#NeoVibe ${getHashTags()}\n\n${item.link}`,
|
||||||
|
media_ids: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runBot() {
|
async function runBot() {
|
||||||
@ -110,13 +127,23 @@ async function runBot() {
|
|||||||
|
|
||||||
let postDate = await getLastPostDate();
|
let postDate = await getLastPostDate();
|
||||||
|
|
||||||
let processedFeed = await processFeed(feed, postDate);
|
let processedFeed = await processFeed(feed.feed, postDate, feed.isNews);
|
||||||
|
|
||||||
console.log("Completed Running Bot: runBot()");
|
console.log("Completed Running Bot: runBot()");
|
||||||
|
|
||||||
return processedFeed;
|
return processedFeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getHashTags() {
|
||||||
|
let hashTags = process.env.POST_HASHTAG.split(",")
|
||||||
|
.map((hashtag) => {
|
||||||
|
return `#${hashtag}`;
|
||||||
|
})
|
||||||
|
.join(" ");
|
||||||
|
|
||||||
|
return hashTags;
|
||||||
|
}
|
||||||
|
|
||||||
const requestListener = function (req, res) {
|
const requestListener = function (req, res) {
|
||||||
res.writeHead(200);
|
res.writeHead(200);
|
||||||
res.end("Hello, World!");
|
res.end("Hello, World!");
|
||||||
|
Loading…
Reference in New Issue
Block a user