Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v22.17.1
77 changes: 77 additions & 0 deletions src/crons/DavidRevoy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Cron, findTextChannelByName } from '../framework/index.ts';
import got from 'got';
import { parse } from 'node-html-parser';
import { decode } from 'html-entities';
import { KeyValue } from '../database/index.ts';
import { EmbedBuilder, SnowflakeUtil } from 'discord.js';

export default new Cron({
enabled: true,
name: 'David Revoy',
description:
'Vérifie toutes les 30 minutes si un nouveau strip de David Revoy est sorti',
schedule: '5,35 * * * *',
async handle(context) {
const strip = await getLastDavidRevoyStrip();

// vérifie le strip trouvé avec la dernière entrée
const lastStrip = await KeyValue.get<string>('Last-Cron-DavidRevoy');
const stripStoreIdentity = strip?.id ?? null;
if (lastStrip === stripStoreIdentity) return; // skip si identique

await KeyValue.set('Last-Cron-DavidRevoy', stripStoreIdentity); // met à jour sinon

if (!strip) return; // skip si pas de strip

context.logger.info(`Found a new David Revoy strip`, strip);

const channel = findTextChannelByName(context.client.channels, 'gif');

await channel.send({
embeds: [
new EmbedBuilder()
.setURL(strip.link)
.setTitle(strip.title)
.setImage(strip.imageUrl)
.setTimestamp(strip.date),
],
enforceNonce: true,
nonce: SnowflakeUtil.generate().toString(),
});
},
});

interface IDavidRevoyStrip {
id: string;
link: string;
title: string;
date: Date;
imageUrl: string;
}

export async function getLastDavidRevoyStrip(): Promise<IDavidRevoyStrip | null> {
const { body } = await got(
'https://www.davidrevoy.com/feed/rss/categorie2/webcomics/',
);
const rss = parse(body, {
blockTextElements: {
// link tag in XML RSS is a block with text content
link: true,
},
});

const item = rss.querySelector('item');
if (!item) return null;

const rawDescription = item.querySelector('description')?.textContent ?? '';
const description = parse(decode(rawDescription));
const img = description.querySelector('img');

return {
id: item.querySelector('guid')?.textContent?.trim() ?? '',
link: item.querySelector('link')?.textContent?.trim() ?? '',
title: item.querySelector('title')?.textContent?.trim() ?? '',
date: new Date(item.querySelector('pubDate')?.textContent ?? new Date()),
imageUrl: img?.parentNode?.getAttribute('href') ?? '',
};
}
20 changes: 20 additions & 0 deletions tests/cron/DavidRevoy.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { test, expect } from 'vitest';

import { getLastDavidRevoyStrip } from '../../src/crons/DavidRevoy.ts';

test('getLastDavidRevoyStrip', async () => {
const strip = await getLastDavidRevoyStrip();
if (!strip) return;

expect(strip.id).toBeTruthy();
expect(typeof strip.id).toBe('string');

expect(strip.link).toBeTruthy();
expect(typeof strip.link).toBe('string');

expect(strip.title).toBeTruthy();
expect(typeof strip.title).toBe('string');

expect(strip.imageUrl).toBeTruthy();
expect(typeof strip.imageUrl).toBe('string');
});