diff --git a/app.js b/app.js index 7e9fec1..fac0474 100644 --- a/app.js +++ b/app.js @@ -102,7 +102,7 @@ clientChatBot.on('connect', async connection => { connection.sendUTF(`PASS oauth:${user_access_token}`) connection.sendUTF(`NICK ${user_name}`) connection.sendUTF(`JOIN #${channel_name}`) - connection.sendUTF(`${chatBeginMsg} Salut tout le monde !`) + //connection.sendUTF(`${chatBeginMsg} Salut tout le monde !`) connection.on('message', async message => { if (message.type === 'utf8') { try { let data = parseMessage(message.utf8Data) @@ -113,14 +113,17 @@ clientChatBot.on('connect', async connection => { let message = data.parameters.split('\r\n')[0] console.log(`${data.source.nick}: ${message}`) + // Handle commands if (message.slice(0, 2) === bot_prefix) { - if (data.tags.badges.moderator !== '1') return connection.sendUTF(`${chatReplyMsg(data.tags.id)} Oh lache ça, t'es fou toi !`) - let command = message.split(bot_prefix)[1].split(' ')[0] let args = message.split(' ').slice(1) if (command === 'ping') connection.sendUTF(`${chatReplyMsg(data.tags.id)} Pong !`) + else if (command === 'coubeh') { + // Restrict to moderators + if (data.tags.badges.moderator !== '1') return connection.sendUTF(`${chatReplyMsg(data.tags.id)} Oh lache ça, t'es fou toi !`) + if (bot_coubeh === 'true') { bot_coubeh = 'false' connection.sendUTF(`${chatReplyMsg(data.tags.id)} Ok j'arrête de flop les viewers...`) } else { bot_coubeh = 'true' @@ -128,6 +131,9 @@ clientChatBot.on('connect', async connection => { writeEnv('BOT_COUBEH', bot_coubeh) } else if (command === 'mention') { + // Restrict to moderators + if (data.tags.badges.moderator !== '1') return connection.sendUTF(`${chatReplyMsg(data.tags.id)} Oh lache ça, t'es fou toi !`) + if (bot_mention === 'true') { bot_mention = 'false' connection.sendUTF(`${chatReplyMsg(data.tags.id)} Ah tu veux plus que je te répondes ? Ok dac`) } else { bot_mention = 'true' @@ -146,21 +152,38 @@ clientChatBot.on('connect', async connection => { ) return connection.sendUTF(`${chatReplyMsg(data.tags.id)} Syntaxe: J/arrow <@viewer> | <@viewer> [current|permanent]`) let action = args[0] + if (action !== 'get' && data.tags.badges.moderator !== '1') return connection.sendUTF(`${chatReplyMsg(data.tags.id)} Oh lache ça, t'es fou toi !`) + let viewer_login = args[1].split('@')[1].toLowerCase() let viewer_id = await getUserID(client_id, user_access_token, viewer_login) + let quantity = parseInt(args[2]) - let type = args[3] if (quantity < 0) return connection.sendUTF(`${chatReplyMsg(data.tags.id)} Tu veux spawn un trou noir dans le stand ou quoi ?!`) + let type = args[3] + let result = await modifyReward(viewer_id, viewer_login, action, quantity, type) - if (result.status === 'get_entry') connection.sendUTF(`${chatReplyMsg(data.tags.id)} ${args[1]} a ${result.count} flèche(s) dans son carquois et ${result.current_count} flèche(s) permanente(s) !`) + if (result.status === 'get_entry') connection.sendUTF(`${chatReplyMsg(data.tags.id)} ${args[1]} a ${result.current_count} flèche(s) dans son carquois et ${result.count} flèche(s) permanente(s) !`) else if (result.status === 'insert_entry') connection.sendUTF(`${chatReplyMsg(data.tags.id)} ${args[1]} a été ajouté au stand avec ${quantity} flèche(s) !`) - else if (result.status === 'update_entry') connection.sendUTF(`${chatReplyMsg(data.tags.id)} ${quantity} flèche(s) ajoutée(s) à ${args[1]} !`) + else if (result.status === 'update_add_entry') connection.sendUTF(`${chatReplyMsg(data.tags.id)} ${quantity} flèche(s) ajoutée(s) à ${args[1]} !`) + else if (result.status === 'update_remove_entry') connection.sendUTF(`${chatReplyMsg(data.tags.id)} ${quantity} flèche(s) retirée(s) à ${args[1]} !`) + else if (result.status === 'update_set_entry') connection.sendUTF(`${chatReplyMsg(data.tags.id)} ${quantity} flèche(s) mises à jour à ${args[1]} !`) else if (result.status === 'no_get_entry') connection.sendUTF(`${chatReplyMsg(data.tags.id)} ${args[1]} ne dispose d'aucune flèche, il n'est même pas dans le stand !`) - else if (result.status === 'no_delete_entry') connection.sendUTF(`${chatReplyMsg(data.tags.id)} Impossble de retirer des flèches à ${args[1]}, il n'en a aucune !`) + else if (result.status === 'no_remove_entry') connection.sendUTF(`${chatReplyMsg(data.tags.id)} Impossble de retirer des flèches à ${args[1]}, il n'en a aucune !`) else if (result.status === 'not_enough_count') connection.sendUTF(`${chatReplyMsg(data.tags.id)} ${args[1]} n'a pas assez de flèches permanentes pour lui en enlever ${quantity} !`) else if (result.status === 'not_enough_current_count') connection.sendUTF(`${chatReplyMsg(data.tags.id)} ${args[1]} n'a pas assez de flèches dans son carquois pour lui en enlever ${quantity} !`) } + else if (command == 'leaderboard') { + let panel_data = await getRewardData() + let leaderboard = '' + for (let i = 0; i < 10; i++) { + if (panel_data[i]) { + leaderboard += `${i + 1}. ${panel_data[i].viewer_name} (${panel_data[i].count} flèches)` + if (i < 9) leaderboard += '\n' + } + } + connection.sendUTF(`${chatBeginMsg} ${leaderboard}`) + } else connection.sendUTF(`${chatReplyMsg(data.tags.id)} Commande inconnue !`) } else if (message.includes('@Bot_Laytho') && bot_mention === 'true') { @@ -178,7 +201,7 @@ clientChatBot.on('connect', async connection => { .on('error', error => { console.error(error) }) .on('close', () => { console.log('[SYS] Twitch ChatBot Connection Closed !') - if (connectionEventSub.state === 'open') clientChatBot.connect('wss://irc-ws.chat.twitch.tv:443') + clientChatBot.connect('wss://irc-ws.chat.twitch.tv:443') }) }).on('connectFailed', error => { console.error(error) }) @@ -231,14 +254,25 @@ clientEventSub.on('connect', async connection => { let { subscription, event } = data.payload if (subscription.type === 'channel.channel_points_custom_reward_redemption.add') { + console.log(subscription) + console.log(event) + let viewer_id = event.user_id let viewer_name = event.user_name console.log(`[SYS] Viewer ${viewer_name} claimed reward ${event.reward.title} !`) - let result = await rewardRedemption(viewer_id, viewer_name) + let channel_access_token = process.env.TWITCH_CHANNEL_ACCESS_TOKEN + let broadcaster_user_id = await getUserInfo(client_id, channel_access_token, 'id') + let reward_id = await getRewardID(client_id, channel_access_token, broadcaster_user_id, channel_reward_name) + + let result = await rewardRedemption(viewer_id, viewer_name, client_id, channel_access_token, event.id, broadcaster_user_id, reward_id) - if (result.status === 'insert_entry') connectionChatBot.sendUTF(`${chatReplyMsg(viewer_id)} a récupéré sa première ${event.reward.title}, GG !`) - else if (result.status === 'update_entry') connectionChatBot.sendUTF(`${chatReplyMsg(viewer_id)} a récupéré sa ${event.reward.title}, t'en as ${result.current_count} dans ton carquois et récupéré ${result.count} depuis le début !`) + if (result.status === 'insert_entry') { + return connectionChatBot.sendUTF(`${chatBeginMsg} @${viewer_name} a récupéré sa première ${event.reward.title}, GG !`) + } + else if (result.status === 'update_entry') { + return connectionChatBot.sendUTF(`${chatBeginMsg} @${viewer_name} a récupéré sa ${event.reward.title}, t'en as ${result.current_count} dans ton carquois et récupéré ${result.count} depuis le début !`) + } } else if (subscription.type === 'stream.online') { console.log(`[SYS] Stream from ${event.broadcaster_user_name} is now online, connecting to chat...`) @@ -254,7 +288,10 @@ clientEventSub.on('connect', async connection => { } catch (error) { console.error(error) } } }) .on('error', error => { console.error(error) }) - .on('close', () => { console.log('[SYS] Twitch EventSub Connection Closed !') }) + .on('close', () => { + console.log('[SYS] Twitch EventSub Connection Closed !') + clientEventSub.connect('wss://eventsub.wss.twitch.tv/ws') + }) }).on('connectFailed', error => { console.error(error) }) clientEventSub.connect('wss://eventsub.wss.twitch.tv/ws') \ No newline at end of file diff --git a/utils/modifyReward.js b/utils/modifyReward.js index 748d855..82a4446 100644 --- a/utils/modifyReward.js +++ b/utils/modifyReward.js @@ -17,8 +17,6 @@ module.exports = modifyReward = (async (viewer_id, viewer_name, action, quantity // Check if the viewer already exists in the rewards table await connection.query('SELECT * FROM rewards WHERE viewer_id = ?', [viewer_id]) .then(async ([rows, fields]) => { - console.log(rows) - if (rows.length === 0) { // Viewer doesn't exist, insert a new row sql_data = { viewer_id, viewer_name } @@ -44,6 +42,8 @@ module.exports = modifyReward = (async (viewer_id, viewer_name, action, quantity if (type === 'permanent') sql_data.count = rows[0].count + quantity else if (type === 'current') sql_data.current_count = rows[0].current_count + quantity else { sql_data.count = rows[0].count + quantity; sql_data.current_count = rows[0].current_count + quantity } + + result.status = 'update_add_entry' } else if (action === 'remove') { // Remove the quantity if (type === 'permanent') sql_data.count = rows[0].count - quantity @@ -52,15 +52,18 @@ module.exports = modifyReward = (async (viewer_id, viewer_name, action, quantity if (sql_data.count < 0) return result.status = 'not_enough_count' // Can't delete more than the count if (sql_data.current_count < 0) return result.status = 'not_enough_current_count' // Can't delete more than the current_count + + result.status = 'update_remove_entry' } else if (action === 'set') { // Set the quantity if (type === 'permanent') sql_data.count = quantity else if (type === 'current') sql_data.current_count = quantity else { sql_data.count = quantity; sql_data.current_count = quantity } + + result.status = 'update_set_entry' } await connection.query('UPDATE rewards SET ? WHERE viewer_id = ?', [sql_data, viewer_id]).catch(error => { console.error(error) }) - return result.status = 'update_entry' } }).catch(error => { console.error(error) }) diff --git a/utils/rewardRedemption.js b/utils/rewardRedemption.js index 7c16f33..bcb5a55 100644 --- a/utils/rewardRedemption.js +++ b/utils/rewardRedemption.js @@ -1,7 +1,8 @@ const mysql = require('mysql2/promise') +const axios = require('axios') require('dotenv').config() -module.exports = rewardRedemption = (async (viewer_id, viewer_name) => { +module.exports = rewardRedemption = (async (viewer_id, viewer_name, client_id, access_token, id, broadcaster_id, reward_id) => { // Create a connection to the MySQL database const connection = await mysql.createConnection({ host: process.env.MYSQL_HOST, @@ -18,16 +19,15 @@ module.exports = rewardRedemption = (async (viewer_id, viewer_name) => { .then(async ([rows, fields]) => { if (rows.length === 0) { // Viewer doesn't exist, insert a new row - let sql_data = { viewer_id, viewer_name, count: 1, current_count: 1 } await connection.query('INSERT INTO rewards SET ?', sql_data).catch(error => { console.error(error) }) return result.status = 'insert_entry' - } else { + } + else { // Viewer exists, update the count result.count = rows[0].count + 1 result.current_count = rows[0].current_count + 1 - let sql_data = { count: result.count, current_count: result.current_count } await connection.query('UPDATE rewards SET ? WHERE viewer_id = ?', [sql_data, viewer_id]).catch(error => { console.error(error) }) @@ -38,6 +38,21 @@ module.exports = rewardRedemption = (async (viewer_id, viewer_name) => { // Terminate the connection to the database await connection.end() - //return [newRow.current_count, newRow.count] + // Fullfil the reward redemption + if (result.status === 'insert_entry' || result.status === 'update_entry') { + await axios.patch(`https://api.twitch.tv/helix/channel_points/custom_rewards/redemptions?id=${id}&broadcaster_id=${broadcaster_id}&reward_id=${reward_id}`, { + status: 'FULFILLED' + }, { + headers: { + 'Authorization': `Bearer ${access_token}`, + 'Client-Id': client_id, + 'Content-Type': 'application/json' + } + }).then(response => { + console.log(response.data) + //return response.data.data[0].status + }).catch(error => { console.log(error.response.data) }) + } + return result }) \ No newline at end of file