UNPKG

artibot-twitter

Version:
170 lines 7.18 kB
import { Global, Module, log } from "artibot"; import Localizer from "artibot-localizer"; import { TwitterApi, ETwitterStreamEvent } from "twitter-api-v2"; import { ChannelType, roleMention, EmbedBuilder } from "discord.js"; import path from "path"; import { fileURLToPath } from "url"; import { createRequire } from 'module'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const require = createRequire(import.meta.url); const { version } = require('../package.json'); export class ArtibotTwitterConfigBuilder { users = []; token; channel = "twitter"; everyone = false; role; banner; /** Add a twitter username */ addUser(username) { if (username.startsWith("@")) username = username.replace("@", ""); this.users.push(username); return this; } /** Add multiple twitter usernames */ addUsers(...usernames) { for (const username of usernames) { if (Array.isArray(username)) this.addUsers(...username); else this.addUser(username); } return this; } /** Set the authentication token for Twitter API */ setToken(token) { this.token = token; return this; } /** Set the channel name where to send notifications */ setChannel(channel) { this.channel = channel; return this; } /** Tag everyone when a new tweet is posted? */ tagEveryone(value = true) { this.everyone = value; return this; } /** Set the role name to ping when a new tweet is posted */ setRole(roleName) { this.role = roleName; return this; } /** Set the banner image URL */ setBanner(bannerURL) { this.banner = bannerURL; return this; } } let config; let twitter; const localizer = new Localizer({ filePath: path.join(__dirname, "..", "locales.json") }); export default function artibotTwitter({ config: { lang } }, twitterConfig) { localizer.setLocale(lang); config = twitterConfig; if (!config.token) throw new Error(localizer._("No token provided for Twitter API")); twitter = new TwitterApi(config.token); return new Module({ id: "twitter", name: "Twitter", version, langs: ["fr", "en"], repo: "GoudronViande24/artibot-twitter", packageName: "artibot-twitter", parts: [ new Global({ id: "twitter", mainFunction }) ] }); } async function mainFunction({ client, config: { embedColor }, createEmbed }) { const add = []; const toDelete = { ids: [] }; for (const user of config.users) { add.push({ value: "from:" + user, tag: user }); } while (true) { try { const activeRules = await twitter.v2.streamRules(); if (activeRules.data) for (const { id } of activeRules.data) toDelete.ids.push(id); if (toDelete.ids.length) await twitter.v2.updateStreamRules({ delete: toDelete }); await twitter.v2.updateStreamRules({ add }); for (const user of config.users) log("Twitter", localizer.__("Following [[0]]", { placeholders: [user] }), "log"); const stream = await twitter.v2.searchStream({ expansions: "author_id,attachments.media_keys", "user.fields": "profile_image_url", "media.fields": "url" }); stream.on(ETwitterStreamEvent.Data, async (tweet) => { if (!tweet.includes || !tweet.includes.users || !tweet.includes.users[0]) return; log("Twitter", localizer.__("New tweet by [[0]]", { placeholders: [tweet.includes.users[0].name] }), "info"); for (const [, guild] of client.guilds.cache) { const channel = guild.channels.cache.find(channel => channel.type == ChannelType.GuildText && channel.name.toLowerCase() == config.channel.toLowerCase()); if (!channel) { log("Twitter", localizer.__("No channel named [[0]] found in guild [[1]]", { placeholders: [config.channel, guild.name] })); continue; } let tag; if (config.everyone) { tag = "@everyone "; } else if (config.role) { const role = guild.roles.cache.find(role => role.name.toLowerCase() == config.role.toLowerCase()); if (role) tag = roleMention(role.id) + " "; } try { const message = { embeds: [] }; const embed = createEmbed() .setTitle(localizer._("New Tweet")) .setAuthor({ name: `${tweet.includes.users[0].name} (${tweet.includes.users[0].username})`, iconURL: tweet.includes.users[0].profile_image_url, url: "https://twitter.com/" + tweet.includes.users[0].username }) .setURL(`https://twitter.com/${tweet.includes.users[0].username}/status/${tweet.data.id}`); if (tweet.data.text) embed.setDescription(tweet.data.text); const image = tweet.includes?.media?.find(media => media.type == "photo" || media.type == "animated_gif"); if (image) embed.setImage(image.url); message.embeds.push(embed); if (config.banner) message.embeds.push(new EmbedBuilder() .setImage(config.banner) .setColor(embedColor)); if (tag) message.content = tag; await channel.send(message); log("Twitter", localizer.__("Sent notification to [[0]] in channel [[1]]", { placeholders: [guild.name, channel.name] })); } catch (e) { log("Twitter", localizer.__("Impossible to send embed to [[0]]", { placeholders: [guild.name] })); log("Twitter", e.message, "debug"); } } }); log("Twitter", localizer._("Connected to Twitter and listening for new tweets"), "info"); break; } catch (e) { log("Twitter", localizer._("error detected, restarting..."), "warn"); log("Twitter", e.message, "debug"); continue; } } } //# sourceMappingURL=index.js.map