import { httpGET, sanitizeEscapedText } from '@squeebot/core/lib/common'; import { Plugin, EventListener, DependencyLoad } from '@squeebot/core/lib/plugin'; import { IMessage } from '@squeebot/core/lib/types'; async function mastodonResponse(msg: IMessage, url: string, type = 'Mastodon'): Promise { let murl; if (type === 'Mastodon') { murl = url.match(/^(https?):\/\/((?:[\w\d-]+\.)*[\w\d-]+\.\w{2,16})\/(?:users\/)?@?([\w-_]+)\/(?:statuses\/)?(\d+[^&#?\s/])/i); } else if (type === 'Pleroma') { murl = url.match(/^(https?):\/\/((?:[\w\d-]+\.)*[\w\d-]+\.\w{2,16})\/(notice)\/([^&#?\s/]+)/i); } if (!murl) { return false; } const url2go = `${murl[1]}://${murl[2]}/api/v1/statuses/${murl[4]}`; let data; try { data = await httpGET(url2go); if (!data) { throw new Error('No API response, probably not ' + type + ' after all.') } 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 = []; let end = sanitizeEscapedText(content.replace(/<\/p>/g, '\n') // Add newlines to paragraph endings .replace(/
/g, '\n') // Add newlines instead of
.replace(/(<([^>]+)>)/ig, '')); // Strip the rest of the HTML out if (end.length > 220) { end = end.substring(0, 220) + '…'; } keys.push(['field', type, { color: 'cyan', type: 'title' }]); 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' }]); keys.push(['bold', '@' + data.account.acct + ':']); keys.push(['field', end, { type: 'content' }]); 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 { urlreply.registerHandler(this.name, 'html/mastodon', async (url: string, msg: IMessage, title: string, body: any): Promise => { const type = title === 'Pleroma' ? 'Pleroma' : 'Mastodon'; let pass = false; if (type === 'Pleroma') { pass = true; } else { const tag = body('a[href="https://joinmastodon.org/"]'); if (tag && tag.text() && tag.text().indexOf('Mastodon') !== -1) { pass = true; } } if (pass) { const mastodonTest = await mastodonResponse(msg, url, type); if (mastodonTest) { return true; } } return false; }); } } module.exports = FediResponsePlugin;