generated from nhcarrigan/template
chore: remove news feed feature #17
+1
-2
@@ -30,7 +30,6 @@
|
|||||||
"discord.js": "14.22.0",
|
"discord.js": "14.22.0",
|
||||||
"fastify": "5.7.4",
|
"fastify": "5.7.4",
|
||||||
"node-schedule": "2.1.1",
|
"node-schedule": "2.1.1",
|
||||||
"octokit": "5.0.5",
|
"octokit": "5.0.5"
|
||||||
"rss-parser": "3.13.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
-36
@@ -32,9 +32,6 @@ importers:
|
|||||||
octokit:
|
octokit:
|
||||||
specifier: 5.0.5
|
specifier: 5.0.5
|
||||||
version: 5.0.5
|
version: 5.0.5
|
||||||
rss-parser:
|
|
||||||
specifier: 3.13.0
|
|
||||||
version: 3.13.0
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@nhcarrigan/eslint-config':
|
'@nhcarrigan/eslint-config':
|
||||||
specifier: 5.2.0
|
specifier: 5.2.0
|
||||||
@@ -1099,9 +1096,6 @@ packages:
|
|||||||
electron-to-chromium@1.5.207:
|
electron-to-chromium@1.5.207:
|
||||||
resolution: {integrity: sha512-mryFrrL/GXDTmAtIVMVf+eIXM09BBPlO5IQ7lUyKmK8d+A4VpRGG+M3ofoVef6qyF8s60rJei8ymlJxjUA8Faw==}
|
resolution: {integrity: sha512-mryFrrL/GXDTmAtIVMVf+eIXM09BBPlO5IQ7lUyKmK8d+A4VpRGG+M3ofoVef6qyF8s60rJei8ymlJxjUA8Faw==}
|
||||||
|
|
||||||
entities@2.2.0:
|
|
||||||
resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
|
|
||||||
|
|
||||||
error-ex@1.3.2:
|
error-ex@1.3.2:
|
||||||
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
|
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
|
||||||
|
|
||||||
@@ -1984,9 +1978,6 @@ packages:
|
|||||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
rss-parser@3.13.0:
|
|
||||||
resolution: {integrity: sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w==}
|
|
||||||
|
|
||||||
run-parallel@1.2.0:
|
run-parallel@1.2.0:
|
||||||
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
||||||
|
|
||||||
@@ -2009,9 +2000,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==}
|
resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
sax@1.4.1:
|
|
||||||
resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
|
|
||||||
|
|
||||||
secure-json-parse@4.0.0:
|
secure-json-parse@4.0.0:
|
||||||
resolution: {integrity: sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA==}
|
resolution: {integrity: sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA==}
|
||||||
|
|
||||||
@@ -2401,14 +2389,6 @@ packages:
|
|||||||
utf-8-validate:
|
utf-8-validate:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
xml2js@0.5.0:
|
|
||||||
resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==}
|
|
||||||
engines: {node: '>=4.0.0'}
|
|
||||||
|
|
||||||
xmlbuilder@11.0.1:
|
|
||||||
resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==}
|
|
||||||
engines: {node: '>=4.0'}
|
|
||||||
|
|
||||||
yocto-queue@0.1.0:
|
yocto-queue@0.1.0:
|
||||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -3507,8 +3487,6 @@ snapshots:
|
|||||||
|
|
||||||
electron-to-chromium@1.5.207: {}
|
electron-to-chromium@1.5.207: {}
|
||||||
|
|
||||||
entities@2.2.0: {}
|
|
||||||
|
|
||||||
error-ex@1.3.2:
|
error-ex@1.3.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-arrayish: 0.2.1
|
is-arrayish: 0.2.1
|
||||||
@@ -4609,11 +4587,6 @@ snapshots:
|
|||||||
'@rollup/rollup-win32-x64-msvc': 4.46.3
|
'@rollup/rollup-win32-x64-msvc': 4.46.3
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
|
|
||||||
rss-parser@3.13.0:
|
|
||||||
dependencies:
|
|
||||||
entities: 2.2.0
|
|
||||||
xml2js: 0.5.0
|
|
||||||
|
|
||||||
run-parallel@1.2.0:
|
run-parallel@1.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
queue-microtask: 1.2.3
|
queue-microtask: 1.2.3
|
||||||
@@ -4643,8 +4616,6 @@ snapshots:
|
|||||||
|
|
||||||
safe-stable-stringify@2.5.0: {}
|
safe-stable-stringify@2.5.0: {}
|
||||||
|
|
||||||
sax@1.4.1: {}
|
|
||||||
|
|
||||||
secure-json-parse@4.0.0: {}
|
secure-json-parse@4.0.0: {}
|
||||||
|
|
||||||
semver@5.7.2: {}
|
semver@5.7.2: {}
|
||||||
@@ -5071,11 +5042,4 @@ snapshots:
|
|||||||
|
|
||||||
ws@8.18.3: {}
|
ws@8.18.3: {}
|
||||||
|
|
||||||
xml2js@0.5.0:
|
|
||||||
dependencies:
|
|
||||||
sax: 1.4.1
|
|
||||||
xmlbuilder: 11.0.1
|
|
||||||
|
|
||||||
xmlbuilder@11.0.1: {}
|
|
||||||
|
|
||||||
yocto-queue@0.1.0: {}
|
yocto-queue@0.1.0: {}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ export const ids = {
|
|||||||
mentorshipGoalForum: "1400629118110011526",
|
mentorshipGoalForum: "1400629118110011526",
|
||||||
mentorshipProjectForum: "1400616702265266186",
|
mentorshipProjectForum: "1400616702265266186",
|
||||||
naomiDiscussionForum: "1408154690121633917",
|
naomiDiscussionForum: "1408154690121633917",
|
||||||
news: "1407804798677418198",
|
|
||||||
partnershipRequests: "1451009066355654829",
|
partnershipRequests: "1451009066355654829",
|
||||||
policyIdeation: "1417294974046965842",
|
policyIdeation: "1417294974046965842",
|
||||||
pressInquiries: "1451011543482368163",
|
pressInquiries: "1451011543482368163",
|
||||||
|
|||||||
+2
-11
@@ -21,7 +21,6 @@ import { checkRetroAchievements } from "./modules/checkAchievements.js";
|
|||||||
import { getForumTagId } from "./modules/getForumTagId.js";
|
import { getForumTagId } from "./modules/getForumTagId.js";
|
||||||
import { logMenteeJoin } from "./modules/logMenteeJoin.js";
|
import { logMenteeJoin } from "./modules/logMenteeJoin.js";
|
||||||
import { logMenteeLeave } from "./modules/logMenteeLeave.js";
|
import { logMenteeLeave } from "./modules/logMenteeLeave.js";
|
||||||
import { postFreeCodeCampNews, postHackerNews } from "./modules/postNews.js";
|
|
||||||
import { postProgressReminders } from "./modules/postProgressReminders.js";
|
import { postProgressReminders } from "./modules/postProgressReminders.js";
|
||||||
import { processMentorshipRole } from "./modules/processMentorshipRole.js";
|
import { processMentorshipRole } from "./modules/processMentorshipRole.js";
|
||||||
import { processUserGuildTag } from "./modules/processUserGuildTag.js";
|
import { processUserGuildTag } from "./modules/processUserGuildTag.js";
|
||||||
@@ -60,12 +59,8 @@ const amari: Amari = {
|
|||||||
],
|
],
|
||||||
partials: [ Partials.Channel ],
|
partials: [ Partials.Channel ],
|
||||||
}),
|
}),
|
||||||
github: octokit,
|
github: octokit,
|
||||||
githubApp: githubApp,
|
githubApp: githubApp,
|
||||||
lastRssItems: {
|
|
||||||
freeCodeCamp: null,
|
|
||||||
hackerNews: null,
|
|
||||||
},
|
|
||||||
recentlyActiveChannels: new Set<string>(),
|
recentlyActiveChannels: new Set<string>(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -78,10 +73,6 @@ amari.discord.once(Events.ClientReady, () => {
|
|||||||
);
|
);
|
||||||
void cacheData(amari);
|
void cacheData(amari);
|
||||||
analytics.startCron();
|
analytics.startCron();
|
||||||
scheduleJob("post news", "0 * * * *", async() => {
|
|
||||||
await postFreeCodeCampNews(amari);
|
|
||||||
await postHackerNews(amari);
|
|
||||||
});
|
|
||||||
scheduleJob("check guild tags", "0 0 * * *", async() => {
|
scheduleJob("check guild tags", "0 0 * * *", async() => {
|
||||||
await logger.log("debug", "Auditing guild tags.");
|
await logger.log("debug", "Auditing guild tags.");
|
||||||
await cacheData(amari);
|
await cacheData(amari);
|
||||||
|
|||||||
@@ -8,12 +8,8 @@ import type { Client } from "discord.js";
|
|||||||
import type { App } from "octokit";
|
import type { App } from "octokit";
|
||||||
|
|
||||||
export interface Amari {
|
export interface Amari {
|
||||||
discord: Client;
|
discord: Client;
|
||||||
github: App["octokit"];
|
github: App["octokit"];
|
||||||
githubApp: App;
|
githubApp: App;
|
||||||
lastRssItems: {
|
|
||||||
freeCodeCamp: string | null;
|
|
||||||
hackerNews: string | null;
|
|
||||||
};
|
|
||||||
recentlyActiveChannels: Set<string>;
|
recentlyActiveChannels: Set<string>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,65 +0,0 @@
|
|||||||
/**
|
|
||||||
* @copyright NHCarrigan
|
|
||||||
* @license Naomi's Public License
|
|
||||||
* @author Naomi Carrigan
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/naming-convention -- Gonna have weird properties in this file. */
|
|
||||||
|
|
||||||
interface FreeCodeCampRSS {
|
|
||||||
items: Array<{
|
|
||||||
"creator": string;
|
|
||||||
"title": string;
|
|
||||||
"link": string;
|
|
||||||
"pubDate": string;
|
|
||||||
"content:encoded": string;
|
|
||||||
"dc:creator": string;
|
|
||||||
"content": string;
|
|
||||||
"contentSnippet": string;
|
|
||||||
"guid": string;
|
|
||||||
"categories": Array<string>;
|
|
||||||
"isoDate": Date;
|
|
||||||
}>;
|
|
||||||
feedUrl: string;
|
|
||||||
image: {
|
|
||||||
link: string;
|
|
||||||
url: string;
|
|
||||||
title: string;
|
|
||||||
};
|
|
||||||
paginationLinks: {
|
|
||||||
self: string;
|
|
||||||
};
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
generator: string;
|
|
||||||
link: string;
|
|
||||||
lastBuildDate: string;
|
|
||||||
ttl: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface HackerNewsRSS {
|
|
||||||
items: Array<{
|
|
||||||
"creator": string;
|
|
||||||
"title": string;
|
|
||||||
"link": string;
|
|
||||||
"pubDate": string;
|
|
||||||
"dc:creator": string;
|
|
||||||
"comments": string;
|
|
||||||
"content": string;
|
|
||||||
"contentSnippet": string;
|
|
||||||
"guid": string;
|
|
||||||
"isoDate": string;
|
|
||||||
}>;
|
|
||||||
feedUrl: string;
|
|
||||||
paginationLinks: {
|
|
||||||
self: string;
|
|
||||||
};
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
generator: string;
|
|
||||||
link: string;
|
|
||||||
lastBuildDate: string;
|
|
||||||
docs: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type { FreeCodeCampRSS, HackerNewsRSS };
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
/**
|
|
||||||
* @copyright NHCarrigan
|
|
||||||
* @license Naomi's Public License
|
|
||||||
* @author Naomi Carrigan
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* eslint-disable complexity -- These need a lot of logic. */
|
|
||||||
|
|
||||||
import { ChannelType } from "discord.js";
|
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention -- Importing a class.
|
|
||||||
import Parser from "rss-parser";
|
|
||||||
import { ids } from "../config/ids.js";
|
|
||||||
import { logger } from "../utils/logger.js";
|
|
||||||
import type { Amari } from "../interfaces/amari.js";
|
|
||||||
import type { FreeCodeCampRSS, HackerNewsRSS } from "../interfaces/rss.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We are completely aware that the contents of this regular expression
|
|
||||||
* are a violation of our Code of Conduct. Unfortunately, this is necessary
|
|
||||||
* to allow us to filter out the RSS feeds for inappropriate content.
|
|
||||||
* We apologise for any distress or harm this line may cause.
|
|
||||||
*/
|
|
||||||
const naughtyRegex
|
|
||||||
// eslint-disable-next-line stylistic/max-len -- Required for filtering.
|
|
||||||
= /\b(?:harass(?:ment|ing|ed)?|bully(?:ing)?|discriminat(?:e|ion|ory)|deadnam(?:e|ing)|misgender(?:ing|ed)?|doxx?(?:ing)?|threat(?:en(?:s|ing|ed)?)?|intimidat(?:e|ion|ing)|spam|scam|fraud|phish(?:ing)?|malware|exploit|attack(?:s|ing)?|hate\s*speech|slur|racist|sexist|homophobic|transphobic|ableist|xenophobic|bigot(?:ry|ed)?|troll(?:ing)?|abuse|derogat(?:ory|ing)|offensive|vulgar|obscene|nsfw|porn(?:o|ography)?|sexual(?:ly)?\s*(?:harass|explicit|content)|gore|violent|illegal|pirat(?:e|ed|ing)|crack(?:ed|ing)?|warez|torrent(?:s|ing)?|copyright\s*violat|stolen|leak(?:ed|ing)?\s*(?:data|info|personal)|dox|privacy\s*violat|confidential|unauthorized|solicitation|advertis(?:e|ing|ement)|promot(?:e|ion|ing)|affiliate|referral|spam(?:ming)?|sell(?:ing)?|buy(?:ing)?|commercial|marketing|drug\s*deal(?:er|ing)?|narcotics?|cocaine|heroin|meth(?:amphetamine)?|fentanyl|opiates?|opioids?|carfentanil|mdma|ecstasy|lsd|psilocybin|mushrooms?\s*trip|ketamine|pcp|ghb|rohypnol|roofies?|xanax|percocet|oxyco(?:done|ntin)|vicodin|adderall|ritalin|controlled\s*substance|illicit\s*drug|street\s*drug|drug\s*traffick(?:ing)?|prescription\s*fraud|pill\s*mill|cannabis\s*(?!legal|dispensary)|marijuana\s*(?!legal|dispensary)|weed\s*(?!control|killer)|pot\s*dealer|dope|murder(?:ing|ed)?|kill(?:ing|ed)?\s*(?:someone|person|people)|assassinat(?:e|ion)|homicide|manslaughter|assault(?:ing|ed)?|battery|kidnap(?:ping)?|abduct(?:ion|ed)?|human\s*traffick(?:ing)?|sex\s*traffick(?:ing)?|child\s*abuse|rape|sexual\s*assault|molest(?:ation|ing|ed)?|pedophil(?:e|ia)|child\s*porn|cp\s*(?=\s|$)|csam|robbery|burgl(?:ar|ary)|theft|steal(?:ing)?|shoplifting|embezzl(?:e|ement|ing)|launder(?:ing)?\s*money|extortion|blackmail|bribery|arson|terrorism|terrorist|bomb(?:ing)?|explo(?:sive|ding)|weapon\s*deal|arms\s*traffick|firearm\s*(?=illegal|unregistered)|gun\s*(?=illegal|unregistered)|counterfe(?:it|ing)|forg(?:e|ery|ing)|identity\s*theft|tax\s*evasion|insider\s*trading)\b/i;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to filter out naughty words from RSS feeds.
|
|
||||||
* @param titleOrContent - The title or content to check.
|
|
||||||
* @returns True if the title or content is naughty, false if it is clean.
|
|
||||||
*/
|
|
||||||
const hasNaughtyWords = (titleOrContent: string): boolean => {
|
|
||||||
return naughtyRegex.test(titleOrContent);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches the RSS feed from freeCodeCamp News and posts the latest updates.
|
|
||||||
* @param amari - Amari's instance.
|
|
||||||
*/
|
|
||||||
const postFreeCodeCampNews = async(amari: Amari): Promise<void> => {
|
|
||||||
try {
|
|
||||||
const parser = new Parser<FreeCodeCampRSS, FreeCodeCampRSS["items"]>();
|
|
||||||
const { items } = await parser.parseURL(
|
|
||||||
"https://www.freecodecamp.org/news/rss",
|
|
||||||
);
|
|
||||||
if (amari.lastRssItems.freeCodeCamp === null) {
|
|
||||||
amari.lastRssItems.freeCodeCamp = items[0]?.guid ?? null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const lastIndex = items.findIndex((item) => {
|
|
||||||
return item.guid === amari.lastRssItems.freeCodeCamp;
|
|
||||||
});
|
|
||||||
const latestPosts
|
|
||||||
= lastIndex > -1
|
|
||||||
? items.slice(0, Math.min(lastIndex, 5))
|
|
||||||
: items.slice(0, 5);
|
|
||||||
const channel
|
|
||||||
= amari.discord.channels.cache.get(ids.channels.news)
|
|
||||||
?? await amari.discord.channels.fetch(ids.channels.news);
|
|
||||||
if (channel === null) {
|
|
||||||
throw new Error("Cannot find news channel.");
|
|
||||||
}
|
|
||||||
if (!channel.isSendable()) {
|
|
||||||
throw new Error("News channel is not sendable.");
|
|
||||||
}
|
|
||||||
if (amari.lastRssItems.freeCodeCamp !== items[0]?.guid) {
|
|
||||||
amari.lastRssItems.freeCodeCamp = items[0]?.guid ?? null;
|
|
||||||
}
|
|
||||||
await Promise.all(
|
|
||||||
latestPosts.map(async(post) => {
|
|
||||||
if (
|
|
||||||
hasNaughtyWords(post.title)
|
|
||||||
|| hasNaughtyWords(post.contentSnippet)
|
|
||||||
|| hasNaughtyWords(post.content)
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const sent = await channel.send(post.link);
|
|
||||||
if (channel.type === ChannelType.GuildAnnouncement) {
|
|
||||||
await sent.crosspost();
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
if (error instanceof Error) {
|
|
||||||
await logger.error("post freecodecamp news module", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches the RSS feed from HackerNews and posts the latest updates.
|
|
||||||
* @param amari - Amari's instance.
|
|
||||||
*/
|
|
||||||
const postHackerNews = async(amari: Amari): Promise<void> => {
|
|
||||||
try {
|
|
||||||
const parser = new Parser<HackerNewsRSS, HackerNewsRSS["items"]>();
|
|
||||||
const { items } = await parser.parseURL(
|
|
||||||
"https://hnrss.org/newest?link=comments",
|
|
||||||
);
|
|
||||||
if (amari.lastRssItems.hackerNews === null) {
|
|
||||||
amari.lastRssItems.hackerNews = items[0]?.guid ?? null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const lastIndex = items.findIndex((item) => {
|
|
||||||
return item.guid === amari.lastRssItems.hackerNews;
|
|
||||||
});
|
|
||||||
const latestPosts
|
|
||||||
= lastIndex > -1
|
|
||||||
? items.slice(0, Math.min(lastIndex, 5))
|
|
||||||
: items.slice(0, 5);
|
|
||||||
const channel
|
|
||||||
= amari.discord.channels.cache.get(ids.channels.news)
|
|
||||||
?? await amari.discord.channels.fetch(ids.channels.news);
|
|
||||||
if (channel === null) {
|
|
||||||
throw new Error("Cannot find news channel.");
|
|
||||||
}
|
|
||||||
if (!channel.isSendable()) {
|
|
||||||
throw new Error("News channel is not sendable.");
|
|
||||||
}
|
|
||||||
if (amari.lastRssItems.hackerNews !== latestPosts[0]?.guid) {
|
|
||||||
amari.lastRssItems.hackerNews = latestPosts[0]?.guid ?? null;
|
|
||||||
}
|
|
||||||
await Promise.all(
|
|
||||||
latestPosts.map(async(post) => {
|
|
||||||
if (
|
|
||||||
hasNaughtyWords(post.title)
|
|
||||||
|| hasNaughtyWords(post.contentSnippet)
|
|
||||||
|| hasNaughtyWords(post.content)
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const sent = await channel.send(post.link);
|
|
||||||
if (channel.type === ChannelType.GuildAnnouncement) {
|
|
||||||
await sent.crosspost();
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
if (error instanceof Error) {
|
|
||||||
await logger.error("post hackernews module", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export { postFreeCodeCampNews, postHackerNews };
|
|
||||||
Reference in New Issue
Block a user