Files
legica-bot/src/controllers/Client.controller.ts
Fran Jurmanović fb98df8f98 initialize redoc
2023-10-03 00:08:14 +02:00

150 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Client, MessageEmbed, TextChannel } from "discord.js";
import * as cron from "cron";
import axios from "axios";
import cheerio from "cheerio";
import { Router } from "express";
import { IController, Legica } from "@models";
import { config } from "@constants";
import basicAuth from "express-basic-auth";
class ClientController implements IController {
private legicaTask: cron.CronJob | null = null;
public path: string = "task";
constructor(private client: Client) {}
public register = (): void => {
this.client.on("ready", (): void => {
this.legicaTask = new cron.CronJob(
config.CRON_LEGICA,
this.sendNextMessage,
null,
true,
"utc"
);
});
};
public registerRouter = (): Router => {
const router = Router();
router.use(
basicAuth({
users: {
admin: config.PASSWORD,
},
})
);
router.get("", (_, res) => {
res.send(this.legicaTask?.running);
});
router.get("next", (_, res) => {
if (!this.legicaTask?.running) {
res.status(400).send("Task is not running.");
} else {
res.send(this.legicaTask.nextDate().toISO());
}
});
router.post("", (_, res) => {
if (this.legicaTask?.running) {
res.status(400).send("Task already running.");
} else {
this.legicaTask?.start();
res.send("Task started.");
}
});
router.delete("", (_, res) => {
if (!this.legicaTask?.running) {
res.status(400).send("Task already stopped.");
} else {
this.legicaTask.stop();
res.send("Task stopped.");
}
});
router.post("send-latest", async (_, res) => {
try {
await this.sendNextMessage();
res.send(true);
} catch (err) {
res.status(400).send(err);
}
});
router.post("send", async (req, res) => {
try {
const url = req.body.url;
await this.sendMessage(url);
res.send(true);
} catch (err) {
res.status(400).send(err);
}
});
return router;
};
private sendNextMessage = async (): Promise<void> => {
try {
const href = await getFirstHtml();
await this.sendMessage(href);
} catch (err) {
console.error(err);
}
};
private sendMessage = async (url: string): Promise<void> => {
if (!url) return;
const { img, title } = await getImgTitle(url);
this.client.channels.cache.forEach(async (channel) => {
try {
if (channel.type !== "text") return null;
const embeddedMessage = new MessageEmbed().setTitle(title).setImage(img);
const msg = await (channel as TextChannel).send(embeddedMessage);
const reactions = [
"1⃣",
"2⃣",
"3⃣",
"4⃣",
"5⃣",
"6⃣",
"7⃣",
"8⃣",
"9⃣",
"🔟",
];
for (const reaction of reactions) {
try {
await msg.react(reaction);
} catch {
console.error(`Reaction ${reaction} to channel ${channel.id} failed.`);
}
}
} catch {
console.error(`Message to channel ${channel.id} failed.`);
}
});
};
}
async function getImgTitle(href: string): Promise<Legica> {
const response = await axios.get(href);
const html = response.data;
const $ = cheerio.load(html);
const title = $(".Article-inner > h1").text();
const { src: img } = $(".Article-media > img").attr() || {};
return { title, img };
}
async function getFirstHtml(): Promise<string> {
const response = await axios.get("https://sib.net.hr/legica-dana");
const html = response.data;
const $ = cheerio.load(html);
const { href } = $(".News-link.c-def")?.attr() || {};
return href;
}
export default ClientController;