plugins-evert/url-twitter/plugin.ts
2020-12-13 18:40:46 +02:00

126 lines
3.5 KiB
TypeScript

import {
Plugin,
Configurable,
EventListener,
DependencyLoad
} from '@squeebot/core/lib/plugin';
import { logger } from '@squeebot/core/lib/core';
import Twitter from 'twitter-lite';
import { IMessage } from '@squeebot/core/lib/types';
import { sanitizeEscapedText } from '@squeebot/core/lib/common';
interface TwitterUser {
id: number;
name: string;
screen_name: string;
description: string;
followers_count: number;
statuses_count: number;
}
interface TwitterTweet {
id: number;
full_text: string;
text?: string;
user: TwitterUser;
retweet_count: number;
favorite_count: number;
}
@Configurable({
consumer_key: null,
consumer_secret: null,
access_token_key: null,
access_token_secret: null,
})
class TwitterURLPlugin extends Plugin {
public twitter: Twitter | null = null;
public me: TwitterUser | null = null;
@EventListener('pluginUnload')
public unloadEventHandler(plugin: string | Plugin): void {
if (plugin === this.name || plugin === this) {
this.config.save().then(() =>
this.emit('pluginUnloaded', this));
}
}
async handleTweet(data: TwitterTweet, msg: IMessage): Promise<boolean> {
const keys = [];
const end = sanitizeEscapedText(data.text || data.full_text);
keys.push(['field', 'Twitter', { color: 'cyan', type: 'title' }]);
keys.push(['field', data.favorite_count.toString(), { color: 'red', label: ['♥', 'Likes'], type: 'metric' }]);
keys.push(['field', data.retweet_count.toString(), { color: 'green', label: ['↱↲', 'Retweets'], type: 'metric' }]);
keys.push(['bold', '@' + data.user.screen_name + ':']);
keys.push(['field', end, { type: 'content' }]);
msg.resolve(keys);
return true;
}
async getStatusById(id: string): Promise<any> {
if (!this.twitter) {
return null;
}
return this.twitter.get('statuses/show', {id, tweet_mode: 'extended'});
}
async twitterURLHandler(url: URL, msg: IMessage): Promise<boolean> {
const det = url.href.match(/\/\w+\/status\/(\d+[^&#?\s/])/i);
if (!det) {
return false;
}
try {
const tweet = await this.getStatusById(det[1]);
if (tweet) {
return this.handleTweet(tweet as TwitterTweet, msg);
}
} catch (e) {
msg.resolve('No such tweet!');
}
return false;
}
@DependencyLoad('urlreply')
addURLHandler(urlreply: any): void {
urlreply.registerHandler(this.name, 'twitter.com/', (url: URL, msg: IMessage) => {
return this.twitterURLHandler(url, msg);
});
urlreply.registerHandler(this.name, 'nitter.net/', (url: URL, msg: IMessage) => {
return this.twitterURLHandler(url, msg);
});
}
initialize(): void {
const consumerKey = this.config.get('consumer_key');
const consumerSecret = this.config.get('consumer_secret');
const accessToken = this.config.get('access_token_key');
const accessTokenSecret = this.config.get('access_token_secret');
if (!consumerKey || !consumerSecret || !accessToken || !accessTokenSecret) {
logger.error('[%s] Twitter credentials missing!', this.name);
return;
}
this.twitter = new Twitter({
consumer_key: consumerKey,
consumer_secret: consumerSecret,
access_token_key: accessToken,
access_token_secret: accessTokenSecret,
});
this.twitter.get('account/verify_credentials').then((data: TwitterUser) => {
this.me = data;
}, (err) => {
logger.error('[%s] Twitter threw an error!', this.name, err.stack);
});
}
}
module.exports = TwitterURLPlugin;