Update dependencies and other stuff
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Fabian Stamm 2023-04-12 22:18:27 +02:00
parent 1f5625877b
commit 536e75abba
12 changed files with 3343 additions and 1733 deletions

View File

@ -1,3 +0,0 @@
{
"url": "https://drone.hibas123.de/hibas123/THM_OSPLUS_NEWS_MAILER"
}

View File

@ -4,7 +4,7 @@ name: default
steps: steps:
- name: Build with node - name: Build with node
image: node:12 image: node:19
commands: commands:
- npm install - npm install
- npm run build - npm run build

2
.gitignore vendored
View File

@ -3,3 +3,5 @@ node_modules/
logs/ logs/
db.json db.json
lib/ lib/
.yarn/cache
.yarn/install-state.gz

File diff suppressed because one or more lines are too long

873
.yarn/releases/yarn-3.5.0.cjs vendored Normal file

File diff suppressed because one or more lines are too long

9
.yarnrc.yml Normal file
View File

@ -0,0 +1,9 @@
nodeLinker: node-modules
npmRegistryServer: "https://npm.hibas123.de"
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"
yarnPath: .yarn/releases/yarn-3.5.0.cjs

View File

@ -1,4 +1,4 @@
FROM node:12 FROM node:19
LABEL maintainer="Fabian Stamm <dev@fabianstamm.de>" LABEL maintainer="Fabian Stamm <dev@fabianstamm.de>"

1509
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,31 +5,32 @@
"author": "Fabian Stamm <dev@fabianstamm.de>", "author": "Fabian Stamm <dev@fabianstamm.de>",
"license": "MIT", "license": "MIT",
"private": true, "private": true,
"type": "module",
"scripts": { "scripts": {
"start": "node lib/index.js", "start": "node lib/index.js",
"build": "tsc", "build": "tsc",
"watch-ts": "tsc -w", "dev": "nodemon -e ts --exec 'node --loader ts-node/esm src/index.ts'"
"watch-js": "nodemon -i db.json lib/index.js",
"watch": "concurrently npm:watch-*"
}, },
"devDependencies": { "devDependencies": {
"@types/dotenv": "^8.2.0", "@types/dotenv": "^8.2.0",
"@types/html-entities": "^1.2.16", "@types/html-entities": "^1.3.4",
"@types/lowdb": "^1.0.5", "@types/node": "^18.15.11",
"@types/node": "^13.1.4", "@types/node-fetch": "^3.0.3",
"@types/node-fetch": "^2.5.4", "nodemon": "^2.0.22",
"concurrently": "^5.0.2", "ts-node": "^10.9.1",
"nodemon": "^2.0.2", "typescript": "^5.0.4"
"typescript": "^3.7.4"
}, },
"dependencies": { "dependencies": {
"@hibas123/nodelogging": "^2.1.2", "@hibas123/nodelogging": "^3.1.3",
"dotenv": "^8.2.0", "@types/lodash": "^4.14.192",
"html-entities": "^1.2.1", "dotenv": "^16.0.3",
"lowdb": "^1.0.0", "html-entities": "^2.3.3",
"node-fetch": "^2.6.0", "lodash": "^4.17.21",
"rss-parser": "^3.7.3", "lowdb": "^5.1.0",
"ssl-root-cas": "^1.2.5", "node-fetch": "^3.3.1",
"telegraf": "^3.35.0" "rss-parser": "^3.13.0",
} "ssl-root-cas": "^1.3.1",
"telegraf": "^4.12.2"
},
"packageManager": "yarn@3.5.0"
} }

View File

@ -1,40 +1,54 @@
require('https').globalAgent.options.ca = require('ssl-root-cas/latest').create(); // require('https').globalAgent.options.ca = require('ssl-root-cas/latest').create();
require('ssl-root-cas').inject(); // require('ssl-root-cas').inject();
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
import Logging from "@hibas123/nodelogging"; import Logging from "@hibas123/nodelogging";
import { createHash } from "crypto"; import { createHash } from "crypto";
import * as dotenv from "dotenv"; import * as dotenv from "dotenv";
import { AllHtmlEntities } from "html-entities"; import { decode } from "html-entities";
import low from "lowdb";
import FileSync from "lowdb/adapters/FileSync";
import fetch from "node-fetch"; import fetch from "node-fetch";
import rss from "rss-parser"; import rss from "rss-parser";
import Telegraf from "telegraf"; import { Telegraf } from "telegraf";
import { message } from "telegraf/filters";
import * as fs from "fs"; import * as fs from "fs";
import lodash from 'lodash'
dotenv.config();
const parser = new rss();
const entities = new AllHtmlEntities();
if (!fs.existsSync("./persist")) { Promise.resolve().then(async () => {
const { Low, LowSync } = await import("lowdb");
// @ts-ignore
const { JSONFileSync } = await import("lowdb/node") as any;
class LowWithLodash<T> extends LowSync<T> {
chain: lodash.ExpChain<this['data']> = lodash.chain(this).get('data')
}
dotenv.config();
const parser = new rss();
// const entities = new AllHtmlEntities();
if (!fs.existsSync("./persist")) {
fs.mkdirSync("./persist") fs.mkdirSync("./persist")
} }
const adapter = new FileSync<{ feeds: IDBFeed[] }>("persist/db.json"); // @ts-ignore
const db = low(adapter); const adapter = new JSONFileSync<{ feeds: IDBFeed[] }>("persist/db.json");
db.defaults({ feeds: [] }).write(); const db: any = new LowWithLodash(adapter);
db.read();
interface IDBFeed { db.chain.defaults({ feeds: [] });
db.write();
interface IDBFeed {
url: string; url: string;
subscriber: number[]; subscriber: number[];
oldEntries: string[]; oldEntries: string[];
} }
class Database { class Database {
static findFeed(url: string): DBFeed { static findFeed(url: string): DBFeed {
const feed = db.get("feeds").find(e => e.url === url).value(); const feed = db.chain.get("feeds").find(e => e.url === url).value();
return feed ? new DBFeed(feed) : undefined; return feed ? new DBFeed(feed) : undefined;
} }
@ -45,7 +59,8 @@ class Database {
oldEntries: [], oldEntries: [],
subscriber: [] subscriber: []
}; };
db.get("feeds").unshift(feed).write(); db.chain.get("feeds").unshift(feed)
db.write();
return feed; return feed;
} }
@ -58,28 +73,31 @@ class Database {
return; return;
} }
} }
db.get("feeds").find(e => e.url === url).get("subscriber").push(chatid).write(); db.chain.get("feeds").find(e => e.url === url).get("subscriber").push(chatid)
db.write();
} }
static findSubscribed(chatid: number) { static findSubscribed(chatid: number) {
return db.get("feeds").filter(e => e.subscriber.indexOf(chatid) >= 0).value(); return db.chain.get("feeds").filter(e => e.subscriber.indexOf(chatid) >= 0).value();
} }
static removeSubscriber(url: string, chatid: number) { static removeSubscriber(url: string, chatid: number) {
db.get("feeds").find(e => e.url === url).get("subscriber").remove(e => e === chatid).write(); db.chain.get("feeds").find(e => e.url === url).get("subscriber").remove(e => e === chatid)
db.write();
} }
static addItems(url: string, hashes: string[]) { static addItems(url: string, hashes: string[]) {
db.get("feeds").find(e => e.url === url).get("oldEntries").unshift(...hashes).write(); db.chain.get("feeds").find(e => e.url === url).get("oldEntries").unshift(...hashes)
db.write();
} }
static getAll() { static getAll() {
return db.get("feeds").map(feed => new DBFeed(feed)).value(); return db.chain.get("feeds").map(feed => new DBFeed(feed)).value();
}
} }
}
class DBFeed implements IDBFeed { class DBFeed implements IDBFeed {
url: string; url: string;
subscriber: number[]; subscriber: number[];
oldEntries: string[]; oldEntries: string[];
@ -99,27 +117,27 @@ class DBFeed implements IDBFeed {
addItems(items: IFeedItem[]) { addItems(items: IFeedItem[]) {
Database.addItems(this.url, items.map(item => calculateHash(item))); Database.addItems(this.url, items.map(item => calculateHash(item)));
} }
} }
interface Feed { interface Feed {
title: string; title: string;
language: string; language: string;
description: string; description: string;
copyright: string; copyright: string;
items: IFeedItem[]; items: IFeedItem[];
} }
interface IFeedItem { interface IFeedItem {
title: string; title: string;
link: string; link: string;
content: string, content: string,
contentSnippet: string; contentSnippet: string;
guid: string; guid: string;
} }
function calculateHash(item: IFeedItem) { function calculateHash(item: IFeedItem) {
let hash = createHash("sha512"); let hash = createHash("sha512");
if (item.content) if (item.content)
hash.update(item.content); hash.update(item.content);
@ -132,9 +150,9 @@ function calculateHash(item: IFeedItem) {
if (item.contentSnippet) if (item.contentSnippet)
hash.update(item.contentSnippet); hash.update(item.contentSnippet);
return hash.digest("hex"); return hash.digest("hex");
} }
async function checkFeed(feed: DBFeed) { async function checkFeed(feed: DBFeed) {
Logging.log("Fetching:", feed.url); Logging.log("Fetching:", feed.url);
let data = await fetch(feed.url).then(res => res.text()); let data = await fetch(feed.url).then(res => res.text());
Logging.log("Received Data"); Logging.log("Received Data");
@ -149,22 +167,22 @@ async function checkFeed(feed: DBFeed) {
await sendFeedTelegraf(feed, newItems); await sendFeedTelegraf(feed, newItems);
feed.addItems(newItems); feed.addItems(newItems);
} }
const bot = new Telegraf(process.env.TG_TOKEN) const bot = new Telegraf(process.env.TG_TOKEN)
bot.start(async ctx => { bot.start(async ctx => {
await ctx.reply("Send some RSS Feed URLs to get started."); await ctx.reply("Send some RSS Feed URLs to get started.");
}) })
bot.command("list", async (ctx) => { bot.command("list", async (ctx) => {
const chatid = ctx.chat.id; const chatid = ctx.chat.id;
const feeds = Database.findSubscribed(chatid).map(feed => feed.url).join("\n"); const feeds = Database.findSubscribed(chatid).map(feed => feed.url).join("\n");
await ctx.reply("You are currently subscribed to: \n" + feeds); await ctx.reply("You are currently subscribed to: \n" + feeds);
}) })
bot.on("message", async ctx => { bot.on(message("text", "entities"), async ctx => {
const chatid = ctx.chat.id; const chatid = ctx.chat.id;
Logging.debug("Message From:", chatid, ctx.message); Logging.debug("Message From:", chatid, ctx.message);
@ -178,47 +196,32 @@ bot.on("message", async ctx => {
else else
Logging.error("Cannot find created feed!") Logging.error("Cannot find created feed!")
})) }))
}) if (urls.length === 0)
await ctx.reply("No URLs found in message.");
})
bot.startPolling(); bot.launch()
async function sendFeedTelegraf(feed: DBFeed, items: IFeedItem[]) { async function sendFeedTelegraf(feed: DBFeed, items: IFeedItem[]) {
Logging.debug("Before send", feed, items); Logging.debug("Before send", feed, items);
await Promise.all(feed.subscriber.map( await Promise.all(feed.subscriber.map(
subscriber => Promise.all( subscriber => Promise.all(
items.map( items.map(
item => bot.telegram.sendMessage( item => bot.telegram.sendMessage(
subscriber, subscriber,
item.guid + "\n" + entities.decode(item.title) + "\n\n" + entities.decode(item.contentSnippet) item.guid + "\n" + decode(item.title) + "\n\n" + decode(item.contentSnippet)
).catch(err => Logging.error(err)).then(() => Logging.debug("Message Sent")) ).catch(err => Logging.error(err)).then(() => Logging.debug("Message Sent"))
) )
) )
)); ));
} }
function checkAll() { function checkAll() {
Database.getAll().map(feed => checkFeed(feed).catch(err => Logging.error(err))); Database.getAll().map(feed => checkFeed(feed).catch(err => Logging.error(err)));
} }
setInterval(() => { setInterval(() => {
checkAll(); checkAll();
}, 1000 * 60 * 60); }, 1000 * 60 * 60);
checkAll(); checkAll();
})
// import { AllHtmlEntities } from "html-entities";
// import { fstat } from "fs";
// const entities = new AllHtmlEntities();
// async function sendFeedMail(feed: Feed, item: IFeedItem) {
// Logging.log("Sending Mail!")
// let mailOptions = {
// from: process.env.MAIL_SENDER,
// to: process.env.MAIL_RECEIVER,
// subject: '[OSPLUS_UPDATE] ' + entities.decode(item.title),
// text: entities.decode(item.contentSnippet),
// html: item.content
// };
// let info = await transporter.sendMail(mailOptions);
// Logging.log('Message sent: %s', info.messageId);
// db.set(calculateHash(item), true).write();
// }

View File

@ -1,14 +1,14 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es2017", "target": "ESNext",
"module": "commonjs", "module": "ESNext",
"moduleResolution": "node", "moduleResolution": "node",
"outDir": "./lib", "outDir": "./lib",
"strict": false, "strict": false,
"esModuleInterop": true, "esModuleInterop": true,
"preserveWatchOutput": true "preserveWatchOutput": true,
"forceConsistentCasingInFileNames": true
}, },
"include": [ "include": ["./src"],
"./src" "exclude": ["node_modules"]
]
} }

1693
yarn.lock Normal file

File diff suppressed because it is too large Load Diff