@levellr/crossgram
Version:
Repost Tweets to Telegram automatically
120 lines • 5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TwitterStreamer = void 0;
const twitter_api_v2_1 = require("twitter-api-v2");
const telegraf_1 = require("telegraf");
const dispatcher_1 = require("./dispatcher");
class TwitterStreamer {
constructor(twitter, stream, onErrorCallback, onConnectionClosedCallback) {
this.twitter = twitter;
this.stream = stream;
this.processStreamEvent = async (result) => {
if (!result.data.author_id) {
return;
}
const dispatcher = this.dispatchers.get(result.data.author_id);
if (!dispatcher) {
return;
}
return dispatcher.dispatch(result);
};
this.userIdsByUsername = new Map();
this.botsByToken = new Map();
this.dispatchers = new Map();
onErrorCallback !== null && onErrorCallback !== void 0 ? onErrorCallback : (onErrorCallback = (err) => {
console.log('Connection error', err);
});
onConnectionClosedCallback !== null && onConnectionClosedCallback !== void 0 ? onConnectionClosedCallback : (onConnectionClosedCallback = () => {
console.log('Connection has been closed');
});
stream.autoReconnect = true;
stream.on(twitter_api_v2_1.ETwitterStreamEvent.ConnectionError, onErrorCallback);
stream.on(twitter_api_v2_1.ETwitterStreamEvent.ConnectionClosed, onConnectionClosedCallback);
stream.on(twitter_api_v2_1.ETwitterStreamEvent.Data, this.processStreamEvent);
}
async registerStream(params) {
const { twitterUsername, telegramBotToken } = params;
let { telegramChatId } = params;
if (typeof telegramChatId === 'string') {
const numericTelegramChatId = parseInt(telegramChatId);
if (Number.isNaN(numericTelegramChatId)) {
throw new Error(`Invalid Telegram chat ID ${telegramChatId}`);
}
telegramChatId = numericTelegramChatId;
}
const user = await this.twitter.v2.userByUsername(twitterUsername);
if (!user.data) {
throw new Error(`No Twitter user found with username ${twitterUsername}`);
}
this.userIdsByUsername.set(twitterUsername, user.data.id);
let dispatcher = this.dispatchers.get(user.data.id);
if (!dispatcher) {
dispatcher = new dispatcher_1.TweetDispatcher();
this.dispatchers.set(user.data.id, dispatcher);
}
let bot = this.botsByToken.get(telegramBotToken);
if (!bot) {
bot = new telegraf_1.Telegraf(telegramBotToken);
await bot.launch();
this.botsByToken.set(telegramBotToken, bot);
}
dispatcher.registerChat(telegramChatId, bot);
await this.updateStreamRules(twitterUsername);
return;
}
unregisterStream(params) {
const { username, chatId } = params;
const userId = this.userIdsByUsername.get(username);
if (!userId) {
return;
}
const dispatcher = this.dispatchers.get(userId);
if (!dispatcher) {
return;
}
dispatcher.unregisterChat(chatId);
return;
}
async updateStreamRules(twitterUsername) {
var _a;
const rule = (_a = this.rules) === null || _a === void 0 ? void 0 : _a.find((rule) => rule.tag === twitterUsername);
if (!rule) {
await this.twitter.v2.updateStreamRules({
add: [
{
tag: twitterUsername,
value: `from:${twitterUsername} -is:retweet -is:quote -is:reply`,
},
],
});
}
const streamRulesResult = await this.twitter.v2.streamRules();
this.rules = streamRulesResult.data;
return;
}
static async create(params) {
const { twitterAppKey, twitterAppSecret, onErrorCallback, onConnectionClosedCallback, resetRules, } = params;
const twitterConsumerClient = new twitter_api_v2_1.default({
appKey: twitterAppKey,
appSecret: twitterAppSecret,
});
const twitter = await twitterConsumerClient.appLogin();
if (resetRules) {
const rules = await twitter.v2.streamRules();
await twitter.v2.updateStreamRules({
delete: { ids: rules.data.map((rule) => rule.id) },
});
}
const stream = await twitter.v2.searchStream({
expansions: [
'author_id',
'attachments.media_keys',
'attachments.poll_ids',
],
'media.fields': ['preview_image_url', 'url', 'alt_text'],
});
return new TwitterStreamer(twitter, stream, onErrorCallback, onConnectionClosedCallback);
}
}
exports.TwitterStreamer = TwitterStreamer;
//# sourceMappingURL=streamer.js.map