From 288ba532de6855e40babc09d9536affe1a12e244 Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Fri, 29 Mar 2024 13:18:05 -0700 Subject: [PATCH] Remove Twitch stream announcement integration This feature appears to have broken earlier this month, and we have not been interested in maintaining this particular feature. --- README.md | 6 +-- lib/app.js | 20 -------- lib/config.js | 7 --- lib/twitch.js | 126 -------------------------------------------------- 4 files changed, 2 insertions(+), 157 deletions(-) delete mode 100644 lib/twitch.js diff --git a/README.md b/README.md index 705ce2333..1a00362cc 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,7 @@ 1. Run `npm install` 2. Set env `GITHUB_TOKEN` to your personal GitHub API token 3. Set env `DISCORD_TOKEN` to your Discord bot token -4. Set env `TWITCH_CLIENT_ID` to your Twitch Application Client ID -5. Set env `TWITCH_CLIENT_SECRET` to your Twitch Application Client Secret -5. (optional) Set env `LOG_LEVEL` to `debug` if you want debug logging -6. Run `node lib/app.js` (or without LOG_LEVEL to default to 'info') +4. (optional) Set env `LOG_LEVEL` to `debug` if you want debug logging +5. Run `node lib/app.js` (or without LOG_LEVEL to default to 'info') ![preview](https://i.imgur.com/45plIKX.png) diff --git a/lib/app.js b/lib/app.js index 6dd639fc3..5a9df5659 100644 --- a/lib/app.js +++ b/lib/app.js @@ -1,7 +1,6 @@ import fetch from 'node-fetch' import { Client, Intents } from 'discord.js' import { log, fetchAuditEntryFor, limitStrTo } from './common.js' -import { updateStream, updateStreams } from './twitch.js' import { fetchAllContributors } from './contributors.js' import { fetchBlocked } from './blocked.js' import { cleanup, processModMail, processModMailReply, processModMailTyping } from './modmail.js' @@ -68,7 +67,6 @@ client.on('ready', () => { scheduleWithFixedDelay(() => resetMessageCache(), 30 * 60000) scheduleWithFixedDelay(() => pruneDeletedMessages(), 10_000) scheduleWithFixedDelay(() => pruneRecentlyFlagged(), 5 * 60000) - scheduleWithFixedDelay(() => updateStreams(client.channels), 5 * 60000) scheduleWithFixedDelay(() => notice.cleanup(), 30_000) scheduleWithFixedDelay(() => cleanup(), 30_000) }) @@ -177,11 +175,6 @@ client.on('messageCreate', async message => { await addCommand(client.user.id, message.guild, createCommand(name, value)) return message.channel.send(`Successfully added command \`${name}\``) - } else if (command === 'stream') { - const value = args.join(' ').toLowerCase().trim() - updateStream(message.member, value) - updateStreams(client.channels) - return message.channel.send(value ? `Successfully added stream \`${value}\`` : 'Successfully removed stream') } else if (command === 'cfpurge') { const arg = args.shift() if (!arg) { @@ -280,19 +273,6 @@ function onMessageEdit (oldMessage, newMessage) { logs.send(withoutMentions(`:pencil: ${buildUserDetail(user)}'s message was modified: ${messageDetail}`)) } -client.on('presenceUpdate', (oldPresence, newPresence) => { - const newMember = newPresence.member - - if (!newMember || !newMember.roles.cache.some(r => r.name.toLowerCase() === config.roles.streams.toLowerCase())) { - return - } - - const activity = newPresence.activities && newPresence.activities.find(p => p.type === 'STREAMING') - const url = activity && activity.url - - updateStream(newMember, url) -}) - client.on('guildBanAdd', async (guildBan) => { const guild = guildBan.guild const user = guildBan.user diff --git a/lib/config.js b/lib/config.js index 3aa4bdcb8..3db7b87e8 100644 --- a/lib/config.js +++ b/lib/config.js @@ -19,9 +19,6 @@ export default { githubToken: process.env.GITHUB_TOKEN, // This is token used for bot to login, must be from Discord Application who has bot enabled discordToken: process.env.DISCORD_TOKEN, - // Used for getting information about streamer from Twitch API - twitchClientId: process.env.TWITCH_CLIENT_ID, - twitchClientSecret: process.env.TWITCH_CLIENT_SECRET, // Discord Application ID for RuneLite discordAppID: '409416265891971072', // Bad IDs to flag @@ -43,8 +40,6 @@ export default { channels: { // Name of Discord channels where custom commands will be ignored noCustomCommands: ['development'], - // Name of Discord channel where streamers will be announced - streams: 'twitch', // Name of Discord channel where moderation logs will be sent (user ban/unban, user role change) moderationLogs: 'mod-logs', // Name of Discord channel where server logs will be sent (user join/leave) @@ -79,8 +74,6 @@ export default { ], // Name of Discord role that will be used to mute people muted: 'muted', - // Name of Discord role that will be used to check if user can be announced in streamer channel - streams: 'streamer', // Name of Discord role that will be given to users authed via GitHub verified: 'github-verified', // Name of Discord role that will be given to users that contributed to main github repo diff --git a/lib/twitch.js b/lib/twitch.js deleted file mode 100644 index 8dc978d58..000000000 --- a/lib/twitch.js +++ /dev/null @@ -1,126 +0,0 @@ -import fetch from 'node-fetch' -import config from './config.js' -import { createEmbed, log } from './common.js' - -const streamingUsers = new Map() - -function parseStreamerId (url) { - if (!url || !url.match(/.*twitch.tv\/.*/)) { - return '' - } - - return url.replace(/.*twitch.tv\//, '').trim() -} - -async function sendStream (channel, member) { - const token = await fetch(`https://id.twitch.tv/oauth2/token?client_id=${config.twitchClientId}&client_secret=${config.twitchClientSecret}&grant_type=client_credentials`, { - method: 'POST' - }).then(res => res.json()) - - const headers = { - headers: { - 'Client-ID': config.twitchClientId, - Authorization: `Bearer ${token.access_token}` - } - } - - const users = await fetch(`https://api.twitch.tv/helix/users?login=${member.id}`, headers).then(res => res.json()) - const user = users.data[0] - - if (!user) { - return Promise.resolve(new Error(`Invalid game or stream for user name: ${member.id}`)) - } - - const streams = await fetch(`https://api.twitch.tv/helix/streams?user_id=${user.id}`, headers).then(res => res.json()) - const stream = streams.data[0] - - if (!stream) { - return Promise.resolve(new Error(`Invalid game or stream for user: ${member.id}`)) - } - - const games = await fetch(`https://api.twitch.tv/helix/games?id=${stream.game_id}`, headers).then(res => res.json()) - const game = games.data[0] - - if (!game || game.name.toLowerCase().indexOf('runescape') === -1) { - return Promise.resolve(new Error(`Invalid game or stream: ${game.name}`)) - } - - const image = stream.thumbnail_url - .replace('{width}', '1280') - .replace('{height}', '720') - - const channelUrl = `https://twitch.tv/${member.id}` - - const embed = createEmbed() - .setColor(6570406) - .setAuthor({ - name: member.name || user.display_name, - url: channelUrl, - iconURL: member.avatar || user.profile_image_url - }) - .setDescription(user.description) - .setThumbnail(user.profile_image_url) - .setTitle(`${stream.title}`) - .setURL(channelUrl) - .setImage(image) - - log.info(`Sending stream for streamer ${member.id}`) - return channel.send({ embeds: [embed] }) -} - -function updateStream (member, streamerUrl) { - const streamerId = parseStreamerId(streamerUrl) - - if (!streamerId) { - streamingUsers.delete(member.id) - return - } - - streamingUsers.set(member.id, { - id: streamerId, - name: member.displayName, - avatar: member.user.displayAvatarURL() - }) -} - -async function updateStreams (channels) { - log.info('Updating streams...') - const channel = channels.cache.find(c => c.name === config.channels.streams) - - if (!channel) { - return - } - - const messagesRaw = await channel.messages.fetch() - const filteredMessages = messagesRaw.filter(m => m.author.bot) - const messages = filteredMessages.map(m => { - const streamerId = parseStreamerId(m.embeds[0].url) - - if (!streamerId) { - return null - } - - if (!Array.from(streamingUsers.values()).find(u => u.id === streamerId)) { - m.delete() - return null - } - - return streamerId - }).filter(m => m != null) - - return Promise.all(Array.from(streamingUsers.keys()).map(k => { - const v = streamingUsers.get(k) - - if (messages.indexOf(v.id) === -1) { - return sendStream(channel, v) - } - - return Promise.resolve() - })).catch(log.warn) -} - -export { - sendStream, - updateStream, - updateStreams -}