DDG, cats, refactor and more

This commit is contained in:
John Facey
2021-12-27 18:46:34 -06:00
parent d133911fe6
commit 7324a06512
6 changed files with 1303 additions and 108 deletions

View File

@@ -11,7 +11,7 @@ Link Flayer is a Discord Bot designed to provide your Discord server with RSS Ne
- Setup has been moved from config file to environment variables to assume bot runs from one instance - Setup has been moved from config file to environment variables to assume bot runs from one instance
## Configure your feeds.json: ## Configure your feeds.json:
Each node with a "title", "link", category attribute to be used from an Airtable. Each node with a "title", "link", "category" attribute to be used from an Airtable columns.
Setting up Airtable for multiple Discord severs still in progress. Setting up Airtable for multiple Discord severs still in progress.
It should be assumed every server will need its own Airtable Base and the coresponding apiKey, base and table name. It should be assumed every server will need its own Airtable Base and the coresponding apiKey, base and table name.

View File

@@ -3,9 +3,11 @@ var libFlayer = require("../libFlayer.js");
module.exports = { module.exports = {
name: 'categories', name: 'categories',
description: 'Categories', description: 'Categories',
async execute(message) { execute(message) {
var cats = libFlayer.getCategories();
message.reply( message.reply(
`Categories: [General, Entertainment, Sports, Tech]` `Categories: [${cats.join(', ')}]`
); );
} }
}; };

View File

@@ -11,8 +11,11 @@ const express = require("express");
const server = express(); const server = express();
var libFlayer = require("./libFlayer.js"); var libFlayer = require("./libFlayer.js");
let linkFlayerMap = [];
server.all("/",(req, res) => { server.all("/",(req, res) => {
var htmlOutput = "Bot is Ready - Sources loading <br />"; var htmlOutput = "LinkFlayer Bot is Ready - Sources loading <br />";
var sources = libFlayer.getSources(); var sources = libFlayer.getSources();
sources.forEach(source => { sources.forEach(source => {
@@ -21,8 +24,15 @@ server.all("/",(req, res) => {
<div> Title: ${source.title} </div> <div> Title: ${source.title} </div>
<div> Link: ${source.link} </div> <div> Link: ${source.link} </div>
<div> category: ${source.category} </div>
</div>` </div>
<div>
<hr />
</div>
`
}); });
res.send(htmlOutput); res.send(htmlOutput);
@@ -45,9 +55,6 @@ for (const file of commandFiles) {
client.commands.set(command.name, command); client.commands.set(command.name, command);
} }
let linkFlayerMap = [];
client.on('ready', () => { client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`); console.log(`Logged in as ${client.user.tag}!`);
}); });

View File

@@ -1,75 +1,93 @@
// JD Requires
let Parser = require('rss-parser'); let Parser = require('rss-parser');
const axios = require('axios'); const axios = require('axios');
let parser = new Parser(); let parser = new Parser();
var feeds = [];
var jsonfile = require('jsonfile'); var jsonfile = require('jsonfile');
var fs = require('fs'); var fs = require('fs');
var file = ('./feeds.json'); var file = ('./feeds.json');
var Airtable = require('airtable'); var Airtable = require('airtable');
var apiKey=process.env.KEY; // Data Structures
var userBase=process.env.BASE; var feeds = [];
var userTable =process.env.TABLE let linkFlayerMap = [];
let linkFlayerCats = [];
//Aitrable Setup
var apiKey = process.env.KEY;
var userBase = process.env.BASE;
var userTable = process.env.TABLE
token = process.env.TOKEN; token = process.env.TOKEN;
var base = new Airtable({apiKey: apiKey}).base(userBase); var base = new Airtable({
apiKey: apiKey
}).base(userBase);
let linkFlayerMap = []; //DuckDuckGo related structure
let answerData = { let answerData = {
text: ``, text: ``,
source: `` source: ``
} }
const { quotes } = require('./quotes.json'); //Local DB for quotes
const {
quotes
} = require('./quotes.json');
exports.addSource = function(title,link,category){ /**
* Adds a new source url to configured Airtable
* @constructor
* @param {string} title - Title/Name of the RSS feed.
* @param {string} link - URL of RSS feed.
* @param {string} category - Category of RSS feed.
*/
exports.addSource = function (title, link, category) {
for (i=0; i<feeds.length; i++){ for (i = 0; i < feeds.length; i++) {
if (feeds[i].link == link){ if (feeds[i].link == link) {
return; return;
} }
} }
base(userTable).create([ base(userTable).create([{
{ "fields": {
"fields": { "title": title,
"title": title, "link": link,
"link": link, "category": category
"category": category
}
} }
], function(err, record) { }], function (err, record) {
if (err) { if (err) {
console.error(err); console.error(err);
return; return;
} }
console.log(record.getId()); console.log(record.getId());
var linkData = { var linkData = {
title: `${title}`, title: `${title}`,
link: `${link}`, link: `${link}`,
category: `${category}`, category: `${category}`,
id: record.getId() id: record.getId()
} }
feeds.push(linkData); feeds.push(linkData);
}); });
} }
exports.deleteSource = function(title) { /**
* Deletes a new source url to configured Airtable by title
* @constructor
* @param {string} title - Title/Name of the RSS feed.
*/
exports.deleteSource = function (title) {
var deleteRecord = ""; var deleteRecord = "";
for (i=0; i<feeds.length; i++){ for (i = 0; i < feeds.length; i++) {
if (feeds[i].title == title){ if (feeds[i].title == title) {
deleteRecord = feeds[i].id; deleteRecord = feeds[i].id;
} }
} }
base(userTable).destroy(deleteRecord, function(err, deletedRecord) { base(userTable).destroy(deleteRecord, function (err, deletedRecord) {
if (err) { if (err) {
console.error(err); console.error(err);
return; return;
@@ -78,95 +96,108 @@ exports.deleteSource = function(title) {
}); });
} }
/**
exports.sleep = (ms) => new Promise((resolve) => { setTimeout(resolve, ms); }) * Adds a new source url to configured Airtable
* @constructor
* @param {string} feedType - Category to select Feed by.
*/
exports.getFeeds = function (feedType) { exports.getFeeds = function (feedType) {
var linkFlayerFilteredMap = []; var linkFlayerFilteredMap = [];
if (feedType == null || feedType == undefined || feedType == "") { if (feedType == null || feedType == undefined || feedType == "") {
return linkFlayerMap; return linkFlayerMap;
} else { } else {
linkFlayerMap.forEach(linkFlay => { linkFlayerMap.forEach(linkFlay => {
if (linkFlay.category.toLowerCase().indexOf(feedType.toLowerCase()) > -1) { if (linkFlay.category.toLowerCase().indexOf(feedType.toLowerCase()) > -1) {
linkFlayerFilteredMap.push(linkFlay); linkFlayerFilteredMap.push(linkFlay);
} }
}); });
return linkFlayerFilteredMap; return linkFlayerFilteredMap;
} }
} }
exports.getSources = function () { exports.loadFeeds = function () {
return feeds;
}
exports.getQuotes = function () {
return quotes;
}
exports.loadFeeds = function() {
feeds = []; feeds = [];
linkFlayerMap = [];
linkFlayerCats = [];
base(userTable) base(userTable)
.select().eachPage(function page(records, fetchNextPage) { .select().eachPage(function page(records, fetchNextPage) {
try { try {
records.forEach(function(record) { records.forEach(function (record) {
console.log('Retrieved title: ', record.get('title')); console.log('Retrieved title: ', record.get('title'));
console.log('Retrieved link:', record.get('link')); console.log('Retrieved link:', record.get('link'));
console.log('Retrieved category:', record.get('category')); console.log('Retrieved category:', record.get('category'));
var feedData = { var feedData = {
title: `${unescape(record.get('title'))}`, title: `${unescape(record.get('title'))}`,
link: `${unescape(record.get('link'))}`, link: `${unescape(record.get('link'))}`,
category: `${unescape(record.get('category'))}`, category: `${unescape(record.get('category'))}`,
id: record.getId() id: record.getId()
}
feeds.push(feedData);
});
} catch (error) {
console.log(error);
} }
linkFlayerMap = []; feeds.push(feedData);
feeds.forEach(feedBlock => {
let foundCat = false;
linkFlayerCats.forEach(cat => {
if (cat == record.get('category')) {
foundCat = true;
}
});
if (!foundCat) {
linkFlayerCats.push(record.get('category'));
}
});
} catch (error) {
console.log(error);
}
feeds.forEach(feedBlock => {
(async () => { (async () => {
try { try {
const feed = parser.parseURL(feedBlock.link, function(err, feed) { const feed = parser.parseURL(feedBlock.link, function (err, feed) {
if (err) { if (err) {
console.log(err + " " + feedBlock.link); console.log(err + " " + feedBlock.link);
//return; //return;
} }
console.log(feed.title); console.log(feed.title);
feed.items.forEach(item => { feed.items.forEach(item => {
var linkData = { var linkData = {
title: `${unescape(item.title)}`, title: `${unescape(item.title)}`,
link: `${unescape(item.link)}`, link: `${unescape(item.link)}`,
category: `${unescape(feedBlock.category)}` category: `${unescape(feedBlock.category)}`
} }
linkFlayerMap.push(linkData); linkFlayerMap.push(linkData);
}); });
}) })
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
})().then(); })().then();
});
return;
//fetchNextPage();
}, function done(error) {
console.log(error);
}); });
return;
//fetchNextPage();
}, function done(error) {
console.log(error);
});
} }
exports.getAnswer = async function (question) { exports.getAnswer = async function (question) {
var answerURL = `https://api.duckduckgo.com/?q=${question}&format=json&pretty=1`; var answerURL = `https://api.duckduckgo.com/?q=${question}&format=json&pretty=1`;
console.log(answerURL); console.log(answerURL);
await axios.get(answerURL) answerData = {
text: ``,
source: ``
}
await axios.get(answerURL)
.then(response => { .then(response => {
console.log(response.data.RelatedTopics[0].Text); console.log(response.data.RelatedTopics[0].Text);
console.log(response.data.RelatedTopics[0].FirstURL); console.log(response.data.RelatedTopics[0].FirstURL);
@@ -182,11 +213,42 @@ exports.getAnswer = async function (question) {
source: `${unescape(response.data.RelatedTopics[0].FirstURL)}` source: `${unescape(response.data.RelatedTopics[0].FirstURL)}`
} }
} }
return answerData;
}) })
.catch(error => { .catch(error => {
console.log(error); console.log(error);
}); });
return answerData; return answerData;
} }
/**
* getQuotes - Returns libFlayer feed sources
* @constructor
*/
exports.getSources = function () {
return feeds;
}
/**
* getQuotes - Returns libFlayer feed quotes
* @constructor
*/
exports.getQuotes = function () {
return quotes;
}
/**
* getCategories - Returns libFlayer feed categories
* @constructor
*/
exports.getCategories = function () {
return linkFlayerCats;
}
/**
* sleep - sleep/wait
* @constructor
*/
exports.sleep = (ms) => new Promise((resolve) => {
setTimeout(resolve, ms);
})

1135
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,9 @@
"dotenv": "^10.0.0", "dotenv": "^10.0.0",
"express": "^4.17.1", "express": "^4.17.1",
"fs": "^0.0.1-security", "fs": "^0.0.1-security",
"js-doc": "^0.5.0",
"jsonfile": "^6.1.0", "jsonfile": "^6.1.0",
"parse-files": "^0.1.1",
"rss-parser": "^3.12.0" "rss-parser": "^3.12.0"
}, },
"scripts": { "scripts": {
@@ -23,5 +25,8 @@
"local": "heroku local web" "local": "heroku local web"
}, },
"author": "John Facey", "author": "John Facey",
"license": "ISC" "license": "ISC",
"devDependencies": {
"jsdoc": "^3.6.7"
}
} }