@copoko/space
Version:
CoPoKo Space
182 lines (179 loc) • 6.23 kB
text/typescript
/*!
* ==========================================================================
* "CoPoKo Space" License
* GNU General Public License version 3.0 (GPLv3)
* ==========================================================================
* This file is part of "CoPoKo Space"
*
* "CoPoKo Space" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "CoPoKo Space" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "CoPoKo Space". If not, see <http://www.gnu.org/licenses/>.
* ==========================================================================
*/
import RSSContext from "../../../types/RSSContext";
import Space from "../../Space";
import bot from "../../TelegrafBot";
import HandleMessage from "../../TelegrafBot/TGBot/HandleMessage";
import Setting from "../Setting";
const list = async () => {
let sub: RSSContext[] = await Space.API.KV.Get("RSSSUB").then(JSON.parse);
if (!sub) {
sub = []
}
return sub
}
const add = async (url: string) => {
const feed = await Space.API.XML2JSON(url)
const rss: RSSContext = {
title: feed.title,
url: url,
status: true,
errorTime: 0,
notify: true,
lastPost: feed.items[0]?.title,
lastLink: feed.items[0]?.link,
lastUpdateTime: feed.items[0]?.pubDate,
lastPostView: await page(feed.items[0]?.title, feed.items[0]?.content)
};
let sub = await list()
sub.push(rss);
// 去重
sub = sub.filter((item: { url: any; }, index: any, self: any[]) => {
return self.findIndex(t => t.url === item.url) === index
});
await Space.API.KV.Put("RSSSUB", JSON.stringify(sub));
return sub
}
const del = async (url: string) => {
let sub = await list()
if (url.startsWith("https://") || url.startsWith("http://")) {
sub = sub.filter((item: any) => item.url !== url);
} else {
sub = sub.filter((item: any) => item.title !== url);
}
await Space.API.KV.Put("RSSSUB", JSON.stringify(sub));
return sub
}
const update = async (that?: HandleMessage) => {
let sub = await list()
for await (const item of sub) {
if (!item.status) {
return
}
if (item.errorTime > 0) {
return
}
const feed: any = await Space.API.XML2JSON(item.url);
try {
if (feed.items[0]?.pubDate != item.lastUpdateTime) {
const rss: RSSContext = {
title: feed.title,
url: item.url,
status: item.status,
errorTime: 0,
notify: item.notify,
lastPost: feed.items[0]?.title,
lastLink: feed.items[0]?.link,
lastUpdateTime: feed.items[0]?.pubDate,
lastPostView: await page(feed.items[0]?.title, feed.items[0]?.content)
};
sub = sub.filter((it: any) => it.url !== item.url);
sub.push(rss);
await Space.API.KV.Put("RSSSUB", JSON.stringify(sub));
if (rss.notify) {
for (const iterator of feed.items) {
if (new Date(iterator.pubDate) > new Date(item.lastUpdateTime)) {
const msg = `<b>${rss.title}</b>\n ${iterator.title}\n <a target="_blank" rel="noopener noreferrer" href="${iterator.link}">Link</a> <a target="_blank" rel="noopener noreferrer" href="${await page(iterator.title, iterator.content)}">View</a>\n`
await sendMessage(msg, that)
await Space.Helpers.Notify.Success(`RSS: ${rss.title}`, msg.replace(/\n/g, "<br>"))
}
}
}
}
} catch (error) {
const rss: RSSContext = {
title: item.title,
url: item.url,
status: item.status,
errorTime: item.errorTime + 1,
notify: item.notify,
lastPost: item.lastPost,
lastLink: item.lastLink,
lastUpdateTime: item.lastUpdateTime,
lastPostView: item.lastPostView
};
sub = sub.filter((it: any) => it.url !== item.url);
sub.push(rss);
await Space.API.KV.Put("RSSSUB", JSON.stringify(sub));
const msg = `<b>${rss.title}</b>\n 订阅失败,已暂停订阅。`
await sendMessage(msg, that)
await Space.Helpers.Notify.Danger(`RSS: ${item.title}`, msg.replace(/\n/g, "<br>"))
}
}
return sub
}
const page = async (tittle: string, content: string) => {
content = content.replace(/<img.*?>/g, "")
const html = `<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${tittle}</title>
<style>
article{
margin: 0 auto;
max-width: 800px;
}
</style>
</head>
<body>
<article>
<h1>${tittle}</h1>
${content}
</article>
</body>
</html>`
const hash = await Space.API.IPFS.Put(html, "text/html").then(e => { return e.json() }).then((e: any) => { return e.Hash })
return "https://ipfs.infura.io/ipfs/" + hash
}
const last = async (that?: HandleMessage) => {
let sub = await list()
for await (const item of sub) {
if (!item.status) {
return
}
if (item.notify) {
const msg = `<b>${item.title}</b>\n ${item.lastPost}\n <a target="_blank" rel="noopener noreferrer" href="${item.lastLink}">Link</a> <a target="_blank" rel="noopener noreferrer" href="${item.lastPostView}">View</a>\n`
await sendMessage(msg, that)
await Space.Helpers.Notify.Primary(`RSS: ${item.title}`, msg.replace(/\n/g, "<br>"))
}
}
}
const RSS = {
list,
add,
del,
update,
page,
last,
};
export default RSS;
async function sendMessage(msg: string, that?: HandleMessage) {
if (that) {
await that.ctx.reply(msg, { parse_mode: "HTML" })
} else {
const set = await Setting("TelegrafBot")
const ADMIN_GROUP_ID = set.ADMIN_GROUP_ID
await bot.telegram.sendMessage(ADMIN_GROUP_ID, msg, { parse_mode: "HTML" });
}
}