plugins-evert/url-fediverse/plugin.ts

148 lines
3.6 KiB
TypeScript
Raw Normal View History

2020-12-05 10:00:00 +00:00
import { httpGET, sanitizeEscapedText } from '@squeebot/core/lib/common';
import {
Plugin,
EventListener,
2023-08-14 14:08:05 +00:00
DependencyLoad,
2020-12-05 10:00:00 +00:00
} from '@squeebot/core/lib/plugin';
2023-08-14 14:08:05 +00:00
import { IMessage, ProtocolFeatureFlag } from '@squeebot/core/lib/types';
2020-12-05 10:00:00 +00:00
2023-08-14 14:08:05 +00:00
async function mastodonResponse(
msg: IMessage,
url: string,
type = 'Mastodon',
limit = true
): Promise<boolean> {
2020-12-05 10:00:00 +00:00
let murl;
if (type === 'Mastodon') {
2023-08-14 14:08:05 +00:00
murl = url.match(
/^(https?):\/\/((?:[\w\d-]+\.)*[\w\d-]+\.\w{2,16})\/(?:users\/)?@?([\w-_]+)\/(?:statuses\/)?(\d+[^&#?\s/])/i
);
2020-12-05 10:00:00 +00:00
} else if (type === 'Pleroma') {
2023-08-14 14:08:05 +00:00
murl = url.match(
/^(https?):\/\/((?:[\w\d-]+\.)*[\w\d-]+\.\w{2,16})\/(notice)\/([^&#?\s/]+)/i
);
2020-12-05 10:00:00 +00:00
}
if (!murl) {
return false;
}
const url2go = `${murl[1]}://${murl[2]}/api/v1/statuses/${murl[4]}`;
let data;
try {
data = await httpGET(url2go);
if (!data) {
2021-04-23 10:39:12 +00:00
throw new Error('No API response, probably not ' + type + ' after all.');
2020-12-05 10:00:00 +00:00
}
data = JSON.parse(data);
} catch (e) {
return false;
}
let content = data.content;
if (!content) {
return false;
}
if (data.spoiler_text) {
content = '[CW] ' + data.spoiler_text;
}
const keys = [];
2023-08-14 14:08:05 +00:00
let end = sanitizeEscapedText(
content
.replace(/<\/p>/g, '\n') // Add newlines to paragraph endings
.replace(/<br \/>/g, '\n') // Add newlines instead of <br />
.replace(/(<([^>]+)>)/gi, '')
); // Strip the rest of the HTML out
if (end.length > 220 && limit) {
2020-12-05 10:00:00 +00:00
end = end.substring(0, 220) + '…';
}
keys.push(['field', type, { color: 'cyan', type: 'title' }]);
2023-08-14 14:08:05 +00:00
keys.push([
'field',
data.favourites_count.toString(),
{ color: 'red', label: ['★', 'Favourites'], type: 'metric' },
]);
keys.push([
'field',
data.reblogs_count.toString(),
{ color: 'green', label: ['↱↲', 'Reblogs'], type: 'metric' },
]);
2020-12-05 10:00:00 +00:00
keys.push(['bold', '@' + data.account.acct + ':']);
keys.push(['field', end, { type: 'content' }]);
2021-06-15 19:54:17 +00:00
if (data.media_attachments?.length) {
const amount = data.media_attachments.length;
2023-08-14 14:08:05 +00:00
keys.push([
'field',
`[${amount} attachment${amount !== 1 ? 's' : ''}]`,
{ color: 'brown' },
]);
2021-06-15 19:54:17 +00:00
}
2020-12-05 10:00:00 +00:00
msg.resolve(keys);
return true;
}
class FediResponsePlugin extends Plugin {
@EventListener('pluginUnload')
public unloadEventHandler(plugin: string | Plugin): void {
if (plugin === this.name || plugin === this) {
this.emit('pluginUnloaded', this);
}
}
@DependencyLoad('urlreply')
addUrlReply(urlreply: any): void {
2021-12-15 16:38:18 +00:00
urlreply.registerHandler(
this.name,
'html/mastodon',
2023-08-14 14:08:05 +00:00
async (
url: string,
msg: IMessage,
title: string,
body: any
): Promise<boolean> => {
2021-12-15 16:38:18 +00:00
const type = url.match('/notice/') ? 'Pleroma' : 'Mastodon';
let pass = false;
if (type === 'Pleroma') {
pass = true;
} else {
2023-11-08 18:55:38 +00:00
const tag = body('a[href="https://joinmastodon.org"]');
const initTag = body('head > script[id="initial-state"][type="application/json"]');
2023-08-14 14:08:05 +00:00
if (
2023-11-08 18:55:38 +00:00
initTag || (tag &&
2023-08-14 14:08:05 +00:00
tag.text() &&
((tag.text() as string).includes('Mastodon') ||
2023-11-08 18:55:38 +00:00
(tag.text() as string).includes('About')))
2023-08-14 14:08:05 +00:00
) {
2021-12-15 16:38:18 +00:00
pass = true;
}
}
if (pass) {
2023-08-14 14:08:05 +00:00
const mastodonTest = await mastodonResponse(
msg,
url,
type,
msg.source.supports(ProtocolFeatureFlag.SHORT_FORM_MESSAGING)
);
2021-12-15 16:38:18 +00:00
if (mastodonTest) {
return true;
}
}
return false;
2020-12-05 10:00:00 +00:00
}
2021-12-15 16:38:18 +00:00
);
2020-12-05 10:00:00 +00:00
}
}
module.exports = FediResponsePlugin;