From 64bd4a713f528089c6332256ec0e12ca50e3fa6d Mon Sep 17 00:00:00 2001
From: liyunze <50455574+liyunze-coding@users.noreply.github.com>
Date: Fri, 17 Jan 2025 09:57:02 +0800
Subject: [PATCH] removed case sensitivity, new auth method
---
index.html | 4 +-
lib/comfy.min.js | 2 +-
lib/handleDCF.js | 270 ++++++++++++++++++++++++++++++++++++++
lib/initComfy.js | 14 ++
scripts/processCommand.js | 4 +-
5 files changed, 290 insertions(+), 4 deletions(-)
create mode 100644 lib/handleDCF.js
create mode 100644 lib/initComfy.js
diff --git a/index.html b/index.html
index 4132222..fe58ffb 100644
--- a/index.html
+++ b/index.html
@@ -6,8 +6,10 @@
+
+
-
+
diff --git a/lib/comfy.min.js b/lib/comfy.min.js
index afa9e7c..fcf4234 100644
--- a/lib/comfy.min.js
+++ b/lib/comfy.min.js
@@ -1 +1 @@
-!function e(t,n,s){function o(r,a){if(!n[r]){if(!t[r]){var c="function"==typeof require&&require;if(!a&&c)return c(r,!0);if(i)return i(r,!0);var u=new Error("Cannot find module '"+r+"'");throw u.code="MODULE_NOT_FOUND",u}var l=n[r]={exports:{}};t[r][0].call(l.exports,(function(e){return o(t[r][1][e]||e)}),l,l.exports,e,t,n,s)}return n[r].exports}for(var i="function"==typeof require&&require,r=0;r=0),"subs-only"in t&&(f.chatModes[n].subOnly=t["subs-only"]),"r9k"in t&&(f.chatModes[n].r9kMode=t.r9k),"slow"in t&&(f.chatModes[n].slowMode=t.slow),f.onChatMode(f.chatModes[n],n)}catch(e){f.onError(e)}})),m.on("message",(function(t,n,s,o){try{var i=n["display-name"]||n.username||e,a="#"+n.username===t,c=n.mod,u=n.badges&&"0"===n.badges.founder,l=u||n.badges&&void 0!==n.badges.subscriber||n.subscriber,m=n.badges&&"1"===n.badges.vip||!1,h="highlighted-message"===n["msg-id"],d=n["user-id"],p=n.id,g=n["room-id"],_=n.badges,b=n.color,y=n.emotes,v=n.flags,w=n["tmi-sent-ts"],C=n["emote-only"]||!1,k=n["message-type"],E=n["custom-reward-id"]||null,T={broadcaster:a,mod:c,founder:u,subscriber:l||u,vip:m,highlighted:h,customReward:!!E},x={id:p,channel:t.replace("#",""),roomId:g,messageType:k,messageEmotes:y,isEmoteOnly:C,userId:d,username:n.username,displayName:n["display-name"],userColor:b,userBadges:_,userState:n,customRewardId:E,flags:v,timestamp:w};if(o||"!"!==s[0])"action"===k||"chat"===k?f.onChat(i,s,T,o,x):"whisper"===k&&f.onWhisper(i,s,T,o,x);else{var S=s.split(/ (.*)/),O=S[0].slice(1).toLowerCase(),I=S[1]||"";x.sinceLastCommand=function(e,t){if(!e)return{any:null,user:null};var n=new Date,s={};return r.global[e]?s.any=n-r.global[e]:s.any=0,r.global[e]=n,t?(r.users[t]||(r.users[t]={}),r.users[t][e]?s.user=n-r.users[t][e]:s.user=0,r.users[t][e]=n):s.user=null,s}(O,d),f.onCommand(i,O,I,T,x)}}catch(e){f.onError(e)}})),m.on("messagedeleted",(function(e,t,n,s){try{var o=s["target-msg-id"],i={id:o,roomId:s["room-id"],username:t,message:n};f.onMessageDeleted(o,i)}catch(e){f.onError(e)}})),m.on("ban",(function(e,t,n,s){try{var o=t,i={roomId:s["room-id"],username:t,bannedUserId:s["target-user-id"]};f.onBan(o,i)}catch(e){f.onError(e)}})),m.on("timeout",(function(e,t,n,s,o){try{var i=t,r=s,a={roomId:o["room-id"],username:t,timedOutUserId:o["target-user-id"]};f.onTimeout(i,r,a)}catch(e){f.onError(e)}})),m.on("join",(function(e,t,n){var s={channel:e.replace("#","")};f.onJoin(t,n,s)})),m.on("part",(function(e,t,n){var s={channel:e.replace("#","")};f.onPart(t,n,s)})),m.on("hosted",(function(e,t,n,s){var o={channel:e.replace("#","")};f.onHosted(t,n,s,o)})),m.on("raided",(function(e,t,n){var s={channel:e.replace("#","")};f.onRaid(t,n,s)})),m.on("cheer",(function(e,t,n){var s=~~t.bits,o=t["room-id"],i=t["display-name"]||t.username||t.login,r=t["user-id"],a="#"+t.username===e,c=t.mod,u=t.badges&&"0"===t.badges.founder,l={broadcaster:a,mod:c,founder:u,subscriber:u||t.badges&&void 0!==t.badges.subscriber||t.subscriber,vip:t.badges&&"1"===t.badges.vip||!1},m={id:t.id,channel:e.replace("#",""),roomId:o,userId:r,username:t.username,userColor:t.color,userBadges:t.badges,userState:t,displayName:t["display-name"],messageEmotes:t.emotes,subscriber:t.subscriber};f.onCheer(i,n,s,l,m)})),m.on("subscription",(function(e,t,n,s,o){var i={id:o.id,roomId:o["room-id"],messageType:o["message-type"],messageEmotes:o.emotes,userId:o["user-id"],username:o.login,displayName:o["display-name"],userColor:o.color,userBadges:o.badges,userState:o,channel:e.replace("#","")};f.onSub(t,s,n,i)})),m.on("resub",(function(e,t,n,s,o,i){var r=~~o["msg-param-cumulative-months"],a={id:o.id,roomId:o["room-id"],messageType:o["message-type"],messageEmotes:o.emotes,userId:o["user-id"],username:o.login,displayName:o["display-name"],userColor:o.color,userBadges:o.badges,channel:e.replace("#","")};f.onResub(t,s,n,r,i,a)})),m.on("subgift",(function(e,t,n,s,o,i){var r=~~i["msg-param-sender-count"],a={id:i.id,roomId:i["room-id"],messageType:i["message-type"],messageEmotes:i.emotes,userId:i["user-id"],username:i.login,displayName:i["display-name"],userColor:i.color,userBadges:i.badges,userState:i,recipientDisplayName:i["msg-param-recipient-display-name"],recipientUsername:i["msg-param-recipient-user-name"],recipientId:i["msg-param-recipient-id"],channel:e.replace("#","")};f.onSubGift(t,n,s,r,o,a)})),m.on("submysterygift",(function(e,t,n,s,o){var i=~~o["msg-param-sender-count"],r={id:o.id,roomId:o["room-id"],messageType:o["message-type"],messageEmotes:o.emotes,userId:o["user-id"],username:o.login,displayName:o["display-name"],userColor:o.color,userBadges:o.badges,userState:o,recipientDisplayName:o["msg-param-recipient-display-name"],recipientUsername:o["msg-param-recipient-user-name"],recipientId:o["msg-param-recipient-id"],userMassGiftCount:~~o["msg-param-mass-gift-count"],channel:e.replace("#","")};f.onSubMysteryGift(t,n,i,s,r)})),m.on("giftpaidupgrade",(function(e,t,n,s){var o={id:s.id,roomId:s["room-id"],messageType:s["message-type"],messageEmotes:s.emotes,userId:s["user-id"],username:s.login,displayName:s["display-name"],userColor:s.color,userBadges:s.badges,userState:s,gifterUsername:s["msg-param-sender-login"],gifterDisplayName:s["msg-param-sender-name"],channel:e.replace("#","")};f.onGiftSubContinue(t,n,o)})),m.on("connected",(function(e,t){console.log("Connected:"+e+":"+t),f.onConnected(e,t,h),h=!1})),m.on("reconnect",(function(){console.log("Reconnecting"),d++,f.onReconnect(d)})),m.connect().catch(f.onError),t&&async function e(t,n){let s;n=n.replace("oauth:","");let r=await o("https://id.twitch.tv/oauth2/validate",{headers:{Authorization:"OAuth "+n}}).then(e=>e.json());if(!r.client_id||!r.scopes.includes("channel:read:redemptions")||!r.scopes.includes("user:read:email"))return void console.error("Invalid Password or Permission Scopes (channel:read:redemptions, user:read:email)");let c,u=(await o("https://api.twitch.tv/helix/users?login="+t,{headers:{"Client-ID":r.client_id,Authorization:"Bearer "+n}}).then(e=>e.json())).data[0].id;c="undefined"!=typeof window?new WebSocket("wss://pubsub-edge.twitch.tv"):new i("wss://pubsub-edge.twitch.tv"),c.onopen=function(e){c.send(JSON.stringify({type:"PING"})),s=setInterval(()=>{c.send(JSON.stringify({type:"PING"}))},6e4);let t={type:"LISTEN",nonce:a(15),data:{topics:["channel-points-channel-v1."+u],auth_token:n}};c.send(JSON.stringify(t))},c.onerror=function(e){console.error(e)},c.onmessage=function(s){switch(message=JSON.parse(s.data),message.type){case"RESPONSE":"ERR_BADAUTH"===message.error&&console.error("PubSub Authentication Failure");break;case"RECONNECT":setTimeout(()=>{e(t,n)},3e3);break;case"MESSAGE":if(message.data.topic.startsWith("channel-points-channel")){let e=JSON.parse(message.data.message);if("reward-redeemed"===e.type){let t=e.data.redemption;var o=t.reward,i={id:o.id,channelId:o.channel_id,title:o.title,prompt:o.prompt,cost:o.cost,userInputRequired:o.is_user_input_required,subOnly:o.is_sub_only,image:{url1x:o.image?o.image.url_1x:null,url2x:o.image?o.image.url_2x:null,url4x:o.image?o.image.url_4x:null},defaultImage:{url1x:o.default_image.url_1x,url2x:o.default_image.url_2x,url4x:o.default_image.url_4x},backgroundColor:o.background_color,enabled:o.is_enabled,paused:o.is_paused,inStock:o.is_in_stock,maxPerStream:{enabled:o.max_per_stream.is_enabled,maxPerStream:o.max_per_stream.max_per_stream},shouldRedemptionsSkipRequestQueue:o.should_redemptions_skip_request_queue,templateId:o.template_id,updatedForIndicatorAt:o.updated_for_indicator_at,maxPerUserPerStream:{enabled:o.max_per_user_per_stream.is_enabled,maxPerUserPerStream:o.max_per_user_per_stream.max_per_user_per_stream},globalCooldown:{enabled:o.global_cooldown.is_enabled,globalCooldownSeconds:o.global_cooldown.global_cooldown_seconds},redemptionsRedeemedCurrentStream:o.redemptions_redeemed_current_stream,cooldownExpiresAt:o.cooldown_expires_at},r={channelId:t.channel_id,reward:i,rewardFulfilled:"FULFILLED"===t.status,userId:t.user.id,username:t.user.login,displayName:t.user.display_name,customRewardId:t.id,timestamp:t.redeemed_at};f.onReward(t.user.display_name||t.user.login,t.reward.title,t.reward.cost,t.user_input||"",r)}}}},c.onclose=function(){clearInterval(s),setTimeout(()=>{e(t,n)},3e3)}}(c,t)},Disconnect:function(){m.disconnect().catch(f.onError)},GetChannelRewards:async function(e,t=!1){if(u){if(!l){let t=await o("https://api.twitch.tv/helix/users?login="+c,{headers:{"Client-ID":e,Authorization:"Bearer "+u}}).then(e=>e.json());l=t.data[0]}return(await o(`https://api.twitch.tv/helix/channel_points/custom_rewards?broadcaster_id=${l.id}&only_manageable_rewards=${t}`,{headers:{"Client-ID":e,Authorization:"Bearer "+u}}).then(e=>e.json())).data||[]}return[]},CreateChannelReward:async function(e,t){if(u){if(!l){let t=await o("https://api.twitch.tv/helix/users?login="+c,{headers:{"Client-ID":e,Authorization:"Bearer "+u}}).then(e=>e.json());l=t.data[0]}return(await o("https://api.twitch.tv/helix/channel_points/custom_rewards?broadcaster_id="+l.id,{method:"POST",headers:{"Client-ID":e,Authorization:"Bearer "+u,"Content-Type":"application/json"},body:JSON.stringify(t)}).then(e=>e.json())).data[0]}throw new Error("Missing Channel Password")},UpdateChannelReward:async function(e,t,n){if(u){if(!l){let t=await o("https://api.twitch.tv/helix/users?login="+c,{headers:{"Client-ID":e,Authorization:"Bearer "+u}}).then(e=>e.json());l=t.data[0]}return(await o(`https://api.twitch.tv/helix/channel_points/custom_rewards?broadcaster_id=${l.id}&id=${t}`,{method:"PATCH",headers:{"Client-ID":e,Authorization:"Bearer "+u,"Content-Type":"application/json"},body:JSON.stringify(n)}).then(e=>e.json())).data[0]}throw new Error("Missing Channel Password")},DeleteChannelReward:async function(e,t){if(u){if(!l){let t=await o("https://api.twitch.tv/helix/users?login="+c,{headers:{"Client-ID":e,Authorization:"Bearer "+u}}).then(e=>e.json());l=t.data[0]}return await o(`https://api.twitch.tv/helix/channel_points/custom_rewards?broadcaster_id=${l.id}&id=${t}`,{method:"DELETE",headers:{"Client-ID":e,Authorization:"Bearer "+u}}).then(e=>e.text())}throw new Error("Missing Channel Password")}};void 0!==t&&t.exports&&(t.exports=f),"undefined"!=typeof window&&(window.ComfyJS=f,s=window.tmi)},{"node-fetch":2,"tmi.js":4,ws:3}],2:[function(e,t,n){(function(e){(function(){"use strict";var e=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==e)return e;throw new Error("unable to locate global object")}();t.exports=n=e.fetch,e.fetch&&(n.default=e.fetch.bind(e)),n.Headers=e.Headers,n.Request=e.Request,n.Response=e.Response}).call(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],3:[function(e,t,n){"use strict";t.exports=function(){throw new Error("ws does not work in the browser. Browser clients must use the native WebSocket object")}},{}],4:[function(e,t,n){(function(t){(function(){!function t(n,s,o){function i(a,c){if(!s[a]){if(!n[a]){var u="function"==typeof e&&e;if(!c&&u)return u(a,!0);if(r)return r(a,!0);throw(u=new Error("Cannot find module '"+a+"'")).code="MODULE_NOT_FOUND",u}u=s[a]={exports:{}},n[a][0].call(u.exports,(function(e){return i(n[a][1][e]||e)}),u,u.exports,t,n,s,o)}return s[a].exports}for(var r="function"==typeof e&&e,a=0;ae.length)&&(t=e.length);for(var n=0,s=new Array(t);n: ").concat(d)),b.hasOwn(e.tags,"username")||(e.tags.username=q),e.tags["message-type"]="whisper",q=b.channel(e.tags.username),this.emits(["whisper","message"],[[q,e.tags,d,!1]]);break;case"PRIVMSG":e.tags.username=e.prefix.split("!")[0],"jtv"===e.tags.username?(u=b.username(d.split(" ")[0]),l=d.includes("auto"),d.includes("hosting you for")?(c=b.extractNumber(d),this.emit("hosted",h,u,c,l)):d.includes("hosting you")&&this.emit("hosted",h,u,0,l)):(c=b.get(this.opts.options.messagesLogLevel,"info"),u=b.actionMessage(d),e.tags["message-type"]=u?"action":"chat",d=u?u[1]:d,b.hasOwn(e.tags,"bits")?this.emit("cheer",h,e.tags,d):(b.hasOwn(e.tags,"msg-id")?"highlighted-message"===e.tags["msg-id"]?(l=e.tags["msg-id"],this.emit("redeem",h,e.tags.username,l,e.tags,d)):"skip-subs-mode-message"===e.tags["msg-id"]&&(m=e.tags["msg-id"],this.emit("redeem",h,e.tags.username,m,e.tags,d)):b.hasOwn(e.tags,"custom-reward-id")&&(m=e.tags["custom-reward-id"],this.emit("redeem",h,e.tags.username,m,e.tags,d)),u?(this.log[c]("[".concat(h,"] *<").concat(e.tags.username,">: ").concat(d)),this.emits(["action","message"],[[h,e.tags,d,!1]])):(this.log[c]("[".concat(h,"] <").concat(e.tags.username,">: ").concat(d)),this.emits(["chat","message"],[[h,e.tags,d,!1]]))));break;default:this.log.warn("Could not parse message:\n".concat(JSON.stringify(e,null,4)))}}},a.prototype.connect=function(){var e=this;return new Promise((function(t,n){e.server=b.get(e.opts.connection.server,"irc-ws.chat.twitch.tv"),e.port=b.get(e.opts.connection.port,80),e.secure&&(e.port=443),443===e.port&&(e.secure=!0),e.reconnectTimer=e.reconnectTimer*e.reconnectDecay,e.reconnectTimer>=e.maxReconnectInterval&&(e.reconnectTimer=e.maxReconnectInterval),e._openConnection(),e.once("_promiseConnect",(function(s){s?n(s):t([e.server,~~e.port])}))}))},a.prototype._openConnection=function(){var e="".concat(this.secure?"wss":"ws","://").concat(this.server,":").concat(this.port,"/"),t={};"agent"in this.opts.connection&&(t.agent=this.opts.connection.agent),this.ws=new l(e,"irc",t),this.ws.onmessage=this._onMessage.bind(this),this.ws.onerror=this._onError.bind(this),this.ws.onclose=this._onClose.bind(this),this.ws.onopen=this._onOpen.bind(this)},a.prototype._onOpen=function(){var e=this;this._isConnected()&&(this.log.info("Connecting to ".concat(this.server," on port ").concat(this.port,"..")),this.emit("connecting",this.server,~~this.port),this.username=b.get(this.opts.identity.username,b.justinfan()),this._getToken().then((function(t){var n=b.password(t);e.log.info("Sending authentication to server.."),e.emit("logon"),t="twitch.tv/tags twitch.tv/commands",e._skipMembership||(t+=" twitch.tv/membership"),e.ws.send("CAP REQ :"+t),n?e.ws.send("PASS ".concat(n)):b.isJustinfan(e.username)&&e.ws.send("PASS SCHMOOPIIE"),e.ws.send("NICK ".concat(e.username))})).catch((function(t){e.emits(["_promiseConnect","disconnected"],[[t],["Could not get a token."]])})))},a.prototype._getToken=function(){var e,t=this.opts.identity.password;return"function"==typeof t?(e=t())instanceof Promise?e:Promise.resolve(e):Promise.resolve(t)},a.prototype._onMessage=function(e){var t=this;e.data.trim().split("\r\n").forEach((function(e){(e=g.msg(e))&&t.handleMessage(e)}))},a.prototype._onError=function(){var e=this;this.moderators={},this.userstate={},this.globaluserstate={},clearInterval(this.pingLoop),clearTimeout(this.pingTimeout),clearTimeout(this._updateEmotesetsTimer),this.reason=null===this.ws?"Connection closed.":"Unable to connect.",this.emits(["_promiseConnect","disconnected"],[[this.reason]]),this.reconnect&&this.reconnections===this.maxReconnectAttempts&&(this.emit("maxreconnect"),this.log.error("Maximum reconnection attempts reached.")),this.reconnect&&!this.reconnecting&&this.reconnections<=this.maxReconnectAttempts-1&&(this.reconnecting=!0,this.reconnections=this.reconnections+1,this.log.error("Reconnecting in ".concat(Math.round(this.reconnectTimer/1e3)," seconds..")),this.emit("reconnect"),setTimeout((function(){e.reconnecting=!1,e.connect().catch((function(t){return e.log.error(t)}))}),this.reconnectTimer)),this.ws=null},a.prototype._onClose=function(){var e=this;this.moderators={},this.userstate={},this.globaluserstate={},clearInterval(this.pingLoop),clearTimeout(this.pingTimeout),clearTimeout(this._updateEmotesetsTimer),this.wasCloseCalled?(this.wasCloseCalled=!1,this.reason="Connection closed.",this.log.info(this.reason),this.emits(["_promiseConnect","_promiseDisconnect","disconnected"],[[this.reason],[null],[this.reason]])):(this.emits(["_promiseConnect","disconnected"],[[this.reason]]),this.reconnect&&this.reconnections===this.maxReconnectAttempts&&(this.emit("maxreconnect"),this.log.error("Maximum reconnection attempts reached.")),this.reconnect&&!this.reconnecting&&this.reconnections<=this.maxReconnectAttempts-1&&(this.reconnecting=!0,this.reconnections=this.reconnections+1,this.log.error("Could not connect to server. Reconnecting in ".concat(Math.round(this.reconnectTimer/1e3)," seconds..")),this.emit("reconnect"),setTimeout((function(){e.reconnecting=!1,e.connect().catch((function(t){return e.log.error(t)}))}),this.reconnectTimer))),this.ws=null},a.prototype._getPromiseDelay=function(){return this.currentLatency<=600?600:this.currentLatency+100},a.prototype._sendCommand=function(e,t,n,s){var o=this;return new Promise((function(i,r){if(!o._isConnected())return r("Not connected to server.");var a;null!==e&&"number"!=typeof e||(null===e&&(e=o._getPromiseDelay()),b.promiseDelay(e).then((function(){return r("No response from Twitch.")}))),null!==t?(a=b.channel(t),o.log.info("[".concat(a,"] Executing command: ").concat(n)),o.ws.send("PRIVMSG ".concat(a," :").concat(n))):(o.log.info("Executing command: ".concat(n)),o.ws.send(n)),"function"==typeof s?s(i,r):i()}))},a.prototype._sendMessage=function(e,t,n,s){var o=this;return new Promise((function(i,r){if(!o._isConnected())return r("Not connected to server.");if(b.isJustinfan(o.getUsername()))return r("Cannot send anonymous messages.");var a,c=b.channel(t);o.userstate[c]||(o.userstate[c]={}),500<=n.length&&(a=b.splitLine(n,500),n=a[0],setTimeout((function(){o._sendMessage(e,t,a[1],(function(){}))}),350)),o.ws.send("PRIVMSG ".concat(c," :").concat(n));var u={};Object.keys(o.emotesets).forEach((function(e){return o.emotesets[e].forEach((function(e){return(b.isRegex(e.code)?g.emoteRegex:g.emoteString)(n,e.code,e.id,u)}))}));var l=Object.assign(o.userstate[c],g.emotes({emotes:g.transformEmotes(u)||null})),m=b.get(o.opts.options.messagesLogLevel,"info"),h=b.actionMessage(n);h?(l["message-type"]="action",o.log[m]("[".concat(c,"] *<").concat(o.getUsername(),">: ").concat(h[1])),o.emits(["action","message"],[[c,l,h[1],!0]])):(l["message-type"]="chat",o.log[m]("[".concat(c,"] <").concat(o.getUsername(),">: ").concat(n)),o.emits(["chat","message"],[[c,l,n,!0]])),"function"==typeof s?s(i,r):i()}))},a.prototype._updateEmoteset=function(e){var t,n=this,s=void 0!==e;s&&(e===this.emotes?s=!1:this.emotes=e),this._skipUpdatingEmotesets?s&&this.emit("emotesets",e,{}):(t=function(){0n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},o.prototype.once=function(e,t){if(!i(t))throw TypeError("listener must be a function");var n=!1;if(this._events.hasOwnProperty(e)&&"_"===e.charAt(0)){var s,o=1,r=e;for(s in this._events)this._events.hasOwnProperty(s)&&s.startsWith(r)&&o++;e+=o}function a(){"_"!==e.charAt(0)||isNaN(e.substr(e.length-1))||(e=e.substring(0,e.length-1)),this.removeListener(e,a),n||(n=!0,t.apply(this,arguments))}return a.listener=t,this.on(e,a),this},o.prototype.removeListener=function(e,t){var n,s,o,a;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(o=(n=this._events[e]).length,s=-1,n===t||i(n.listener)&&n.listener===t){if(delete this._events[e],this._events.hasOwnProperty(e+"2")&&"_"===e.charAt(0)){var c,u=e;for(c in this._events)this._events.hasOwnProperty(c)&&c.startsWith(u)&&(isNaN(parseInt(c.substr(c.length-1)))||(this._events[e+parseInt(c.substr(c.length-1)-1)]=this._events[c],delete this._events[c]));this._events[e]=this._events[e+"1"],delete this._events[e+"1"]}this._events.removeListener&&this.emit("removeListener",e,t)}else if(r(n)){for(a=o;0n?(t.command=e.slice(n),t):null;for(t.command=e.slice(n,s),n=s+1;32===e.charCodeAt(n);)n++;for(;n").replace(/\\"\\;/g,'"').replace(/\\'\\;/g,"'")},unescapeIRC:function(e){return e&&"string"==typeof e&&e.includes("\\")?e.replace(r,(function(e,t){return t in c?c[t]:t})):e},escapeIRC:function(e){return e&&"string"==typeof e?e.replace(a,(function(e,t){return t in u?"\\".concat(u[t]):t})):e},addWord:function(e,t){return e.length?e+" "+t:e+t},splitLine:function(e,t){var n=e.substring(0,t).lastIndexOf(" ");return[e.substring(0,n=-1===n?t-1:n),e.substring(n+1)]},extractNumber:function(e){for(var t=e.split(" "),n=0;n=0),"subs-only"in t&&(p.chatModes[n].subOnly=t["subs-only"]),"r9k"in t&&(p.chatModes[n].r9kMode=t.r9k),"slow"in t&&(p.chatModes[n].slowMode=t.slow),p.onChatMode(p.chatModes[n],n)}catch(e){p.onError(e)}})),h.on("message",(function(t,n,s,o){try{var i=n["display-name"]||n.username||e,r="#"+n.username===t,c=n.mod,u=n.badges&&"0"===n.badges.founder,l=u||n.badges&&void 0!==n.badges.subscriber||n.subscriber,m=n.badges&&"1"===n.badges.vip||!1,h="highlighted-message"===n["msg-id"],d=n["user-id"],f=n.id,g=n["room-id"],_=n.badges,b=n.color,y=n.emotes,v=n.flags,w=n["tmi-sent-ts"],C=n["emote-only"]||!1,k=n["message-type"],E=n["custom-reward-id"]||null,T={broadcaster:r,mod:c,founder:u,subscriber:l||u,vip:m,highlighted:h,customReward:!!E},x={id:f,channel:t.replace("#",""),roomId:g,messageType:k,messageEmotes:y,isEmoteOnly:C,userId:d,username:n.username,displayName:n["display-name"],userColor:b,userBadges:_,userState:n,customRewardId:E,flags:v,timestamp:w};if(o||"!"!==s[0])if(!o&&s.split(" ").length>0&&"@"===s[0]&&"!"===s.split(" ")[1][0]){O=(S=s.split(" "))[1].slice(1).toLowerCase(),I=S.slice(2).join(" ");x.sinceLastCommand=a(O,d),p.onCommand(i,O,I,T,x)}else"action"===k||"chat"===k?p.onChat(i,s,T,o,x):"whisper"===k&&p.onWhisper(i,s,T,o,x);else{var S,O=(S=s.split(/ (.*)/))[0].slice(1).toLowerCase(),I=S[1]||"";x.sinceLastCommand=a(O,d),p.onCommand(i,O,I,T,x)}}catch(e){p.onError(e)}})),h.on("messagedeleted",(function(e,t,n,s){try{var o=s["target-msg-id"],i={id:o,roomId:s["room-id"],username:t,message:n};p.onMessageDeleted(o,i)}catch(e){p.onError(e)}})),h.on("ban",(function(e,t,n,s){try{var o=t,i={roomId:s["room-id"],username:t,bannedUserId:s["target-user-id"]};p.onBan(o,i)}catch(e){p.onError(e)}})),h.on("timeout",(function(e,t,n,s,o){try{var i=t,r=s,a={roomId:o["room-id"],username:t,timedOutUserId:o["target-user-id"]};p.onTimeout(i,r,a)}catch(e){p.onError(e)}})),h.on("join",(function(e,t,n){var s={channel:e.replace("#","")};p.onJoin(t,n,s)})),h.on("part",(function(e,t,n){var s={channel:e.replace("#","")};p.onPart(t,n,s)})),h.on("hosted",(function(e,t,n,s){var o={channel:e.replace("#","")};p.onHosted(t,n,s,o)})),h.on("raided",(function(e,t,n){var s={channel:e.replace("#","")};p.onRaid(t,n,s)})),h.on("cheer",(function(e,t,n){var s=~~t.bits,o=t["room-id"],i=t["display-name"]||t.username||t.login,r=t["user-id"],a="#"+t.username===e,c=t.mod,u=t.badges&&"0"===t.badges.founder,l={broadcaster:a,mod:c,founder:u,subscriber:u||t.badges&&void 0!==t.badges.subscriber||t.subscriber,vip:t.badges&&"1"===t.badges.vip||!1},m={id:t.id,channel:e.replace("#",""),roomId:o,userId:r,username:t.username,userColor:t.color,userBadges:t.badges,userState:t,displayName:t["display-name"],messageEmotes:t.emotes,subscriber:t.subscriber};p.onCheer(i,n,s,l,m)})),h.on("subscription",(function(e,t,n,s,o){var i={id:o.id,roomId:o["room-id"],messageType:o["message-type"],messageEmotes:o.emotes,userId:o["user-id"],username:o.login,displayName:o["display-name"],userColor:o.color,userBadges:o.badges,userState:o,channel:e.replace("#","")};p.onSub(t,s,n,i)})),h.on("resub",(function(e,t,n,s,o,i){var r=~~o["msg-param-cumulative-months"],a={id:o.id,roomId:o["room-id"],messageType:o["message-type"],messageEmotes:o.emotes,userId:o["user-id"],username:o.login,displayName:o["display-name"],userColor:o.color,userBadges:o.badges,channel:e.replace("#","")};p.onResub(t,s,n,r,i,a)})),h.on("subgift",(function(e,t,n,s,o,i){var r=~~i["msg-param-sender-count"],a={id:i.id,roomId:i["room-id"],messageType:i["message-type"],messageEmotes:i.emotes,userId:i["user-id"],username:i.login,displayName:i["display-name"],userColor:i.color,userBadges:i.badges,userState:i,recipientDisplayName:i["msg-param-recipient-display-name"],recipientUsername:i["msg-param-recipient-user-name"],recipientId:i["msg-param-recipient-id"],channel:e.replace("#","")};p.onSubGift(t,n,s,r,o,a)})),h.on("submysterygift",(function(e,t,n,s,o){var i=~~o["msg-param-sender-count"],r={id:o.id,roomId:o["room-id"],messageType:o["message-type"],messageEmotes:o.emotes,userId:o["user-id"],username:o.login,displayName:o["display-name"],userColor:o.color,userBadges:o.badges,userState:o,recipientDisplayName:o["msg-param-recipient-display-name"],recipientUsername:o["msg-param-recipient-user-name"],recipientId:o["msg-param-recipient-id"],userMassGiftCount:~~o["msg-param-mass-gift-count"],channel:e.replace("#","")};p.onSubMysteryGift(t,n,i,s,r)})),h.on("giftpaidupgrade",(function(e,t,n,s){var o={id:s.id,roomId:s["room-id"],messageType:s["message-type"],messageEmotes:s.emotes,userId:s["user-id"],username:s.login,displayName:s["display-name"],userColor:s.color,userBadges:s.badges,userState:s,gifterUsername:s["msg-param-sender-login"],gifterDisplayName:s["msg-param-sender-name"],channel:e.replace("#","")};p.onGiftSubContinue(t,n,o)})),h.on("connected",(function(e,t){console.log("Connected:"+e+":"+t),p.onConnected(e,t,d),d=!1})),h.on("reconnect",(function(){console.log("Reconnecting"),f++,p.onReconnect(f)})),h.connect().catch(p.onError),t&&async function e(t,n){let s;n=n.replace("oauth:","");let r=await o("https://id.twitch.tv/oauth2/validate",{headers:{Authorization:"OAuth "+n}}).then(e=>e.json());if(!r.client_id||!r.scopes.includes("channel:read:redemptions")||!r.scopes.includes("user:read:email"))return void console.error("Invalid Password or Permission Scopes (channel:read:redemptions, user:read:email)");let a,u=(await o("https://api.twitch.tv/helix/users?login="+t,{headers:{"Client-ID":r.client_id,Authorization:"Bearer "+n}}).then(e=>e.json())).data[0].id;a="undefined"!=typeof window?new WebSocket("wss://pubsub-edge.twitch.tv"):new i("wss://pubsub-edge.twitch.tv"),a.onopen=function(e){a.send(JSON.stringify({type:"PING"})),s=setInterval(()=>{a.send(JSON.stringify({type:"PING"}))},6e4);let t={type:"LISTEN",nonce:c(15),data:{topics:["channel-points-channel-v1."+u],auth_token:n}};a.send(JSON.stringify(t))},a.onerror=function(e){console.error(e)},a.onmessage=function(s){switch(message=JSON.parse(s.data),message.type){case"RESPONSE":"ERR_BADAUTH"===message.error&&console.error("PubSub Authentication Failure");break;case"RECONNECT":setTimeout(()=>{e(t,n)},3e3);break;case"MESSAGE":if(message.data.topic.startsWith("channel-points-channel")){let e=JSON.parse(message.data.message);if("reward-redeemed"===e.type){let t=e.data.redemption;var o=t.reward,i={id:o.id,channelId:o.channel_id,title:o.title,prompt:o.prompt,cost:o.cost,userInputRequired:o.is_user_input_required,subOnly:o.is_sub_only,image:{url1x:o.image?o.image.url_1x:null,url2x:o.image?o.image.url_2x:null,url4x:o.image?o.image.url_4x:null},defaultImage:{url1x:o.default_image.url_1x,url2x:o.default_image.url_2x,url4x:o.default_image.url_4x},backgroundColor:o.background_color,enabled:o.is_enabled,paused:o.is_paused,inStock:o.is_in_stock,maxPerStream:{enabled:o.max_per_stream.is_enabled,maxPerStream:o.max_per_stream.max_per_stream},shouldRedemptionsSkipRequestQueue:o.should_redemptions_skip_request_queue,templateId:o.template_id,updatedForIndicatorAt:o.updated_for_indicator_at,maxPerUserPerStream:{enabled:o.max_per_user_per_stream.is_enabled,maxPerUserPerStream:o.max_per_user_per_stream.max_per_user_per_stream},globalCooldown:{enabled:o.global_cooldown.is_enabled,globalCooldownSeconds:o.global_cooldown.global_cooldown_seconds},redemptionsRedeemedCurrentStream:o.redemptions_redeemed_current_stream,cooldownExpiresAt:o.cooldown_expires_at},r={channelId:t.channel_id,reward:i,rewardFulfilled:"FULFILLED"===t.status,userId:t.user.id,username:t.user.login,displayName:t.user.display_name,customRewardId:t.id,timestamp:t.redeemed_at};p.onReward(t.user.display_name||t.user.login,t.reward.title,t.reward.cost,t.user_input||"",r)}}}},a.onclose=function(){clearInterval(s),setTimeout(()=>{e(t,n)},3e3)}}(u,t)},Disconnect:function(){h.disconnect().catch(p.onError)},GetChannelRewards:async function(e,t=!1){if(l){if(!m){let t=await o("https://api.twitch.tv/helix/users?login="+u,{headers:{"Client-ID":e,Authorization:"Bearer "+l}}).then(e=>e.json());m=t.data[0]}return(await o(`https://api.twitch.tv/helix/channel_points/custom_rewards?broadcaster_id=${m.id}&only_manageable_rewards=${t}`,{headers:{"Client-ID":e,Authorization:"Bearer "+l}}).then(e=>e.json())).data||[]}return[]},CreateChannelReward:async function(e,t){if(l){if(!m){let t=await o("https://api.twitch.tv/helix/users?login="+u,{headers:{"Client-ID":e,Authorization:"Bearer "+l}}).then(e=>e.json());m=t.data[0]}return(await o("https://api.twitch.tv/helix/channel_points/custom_rewards?broadcaster_id="+m.id,{method:"POST",headers:{"Client-ID":e,Authorization:"Bearer "+l,"Content-Type":"application/json"},body:JSON.stringify(t)}).then(e=>e.json())).data[0]}throw new Error("Missing Channel Password")},UpdateChannelReward:async function(e,t,n){if(l){if(!m){let t=await o("https://api.twitch.tv/helix/users?login="+u,{headers:{"Client-ID":e,Authorization:"Bearer "+l}}).then(e=>e.json());m=t.data[0]}return(await o(`https://api.twitch.tv/helix/channel_points/custom_rewards?broadcaster_id=${m.id}&id=${t}`,{method:"PATCH",headers:{"Client-ID":e,Authorization:"Bearer "+l,"Content-Type":"application/json"},body:JSON.stringify(n)}).then(e=>e.json())).data[0]}throw new Error("Missing Channel Password")},DeleteChannelReward:async function(e,t){if(l){if(!m){let t=await o("https://api.twitch.tv/helix/users?login="+u,{headers:{"Client-ID":e,Authorization:"Bearer "+l}}).then(e=>e.json());m=t.data[0]}return await o(`https://api.twitch.tv/helix/channel_points/custom_rewards?broadcaster_id=${m.id}&id=${t}`,{method:"DELETE",headers:{"Client-ID":e,Authorization:"Bearer "+l}}).then(e=>e.text())}throw new Error("Missing Channel Password")}};void 0!==t&&t.exports&&(t.exports=p),"undefined"!=typeof window&&(window.ComfyJS=p,s=window.tmi)},{"node-fetch":2,"tmi.js":4,ws:3}],2:[function(e,t,n){(function(e){(function(){"use strict";var e=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==e)return e;throw new Error("unable to locate global object")}();t.exports=n=e.fetch,e.fetch&&(n.default=e.fetch.bind(e)),n.Headers=e.Headers,n.Request=e.Request,n.Response=e.Response}).call(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],3:[function(e,t,n){"use strict";t.exports=function(){throw new Error("ws does not work in the browser. Browser clients must use the native WebSocket object")}},{}],4:[function(e,t,n){(function(t){(function(){!function t(n,s,o){function i(a,c){if(!s[a]){if(!n[a]){var u="function"==typeof e&&e;if(!c&&u)return u(a,!0);if(r)return r(a,!0);throw(u=new Error("Cannot find module '"+a+"'")).code="MODULE_NOT_FOUND",u}u=s[a]={exports:{}},n[a][0].call(u.exports,(function(e){return i(n[a][1][e]||e)}),u,u.exports,t,n,s,o)}return s[a].exports}for(var r="function"==typeof e&&e,a=0;ae.length)&&(t=e.length);for(var n=0,s=new Array(t);n: ").concat(d)),b.hasOwn(e.tags,"username")||(e.tags.username=q),e.tags["message-type"]="whisper",q=b.channel(e.tags.username),this.emits(["whisper","message"],[[q,e.tags,d,!1]]);break;case"PRIVMSG":e.tags.username=e.prefix.split("!")[0],"jtv"===e.tags.username?(u=b.username(d.split(" ")[0]),l=d.includes("auto"),d.includes("hosting you for")?(c=b.extractNumber(d),this.emit("hosted",h,u,c,l)):d.includes("hosting you")&&this.emit("hosted",h,u,0,l)):(c=b.get(this.opts.options.messagesLogLevel,"info"),u=b.actionMessage(d),e.tags["message-type"]=u?"action":"chat",d=u?u[1]:d,b.hasOwn(e.tags,"bits")?this.emit("cheer",h,e.tags,d):(b.hasOwn(e.tags,"msg-id")?"highlighted-message"===e.tags["msg-id"]?(l=e.tags["msg-id"],this.emit("redeem",h,e.tags.username,l,e.tags,d)):"skip-subs-mode-message"===e.tags["msg-id"]&&(m=e.tags["msg-id"],this.emit("redeem",h,e.tags.username,m,e.tags,d)):b.hasOwn(e.tags,"custom-reward-id")&&(m=e.tags["custom-reward-id"],this.emit("redeem",h,e.tags.username,m,e.tags,d)),u?(this.log[c]("[".concat(h,"] *<").concat(e.tags.username,">: ").concat(d)),this.emits(["action","message"],[[h,e.tags,d,!1]])):(this.log[c]("[".concat(h,"] <").concat(e.tags.username,">: ").concat(d)),this.emits(["chat","message"],[[h,e.tags,d,!1]]))));break;default:this.log.warn("Could not parse message:\n".concat(JSON.stringify(e,null,4)))}}},a.prototype.connect=function(){var e=this;return new Promise((function(t,n){e.server=b.get(e.opts.connection.server,"irc-ws.chat.twitch.tv"),e.port=b.get(e.opts.connection.port,80),e.secure&&(e.port=443),443===e.port&&(e.secure=!0),e.reconnectTimer=e.reconnectTimer*e.reconnectDecay,e.reconnectTimer>=e.maxReconnectInterval&&(e.reconnectTimer=e.maxReconnectInterval),e._openConnection(),e.once("_promiseConnect",(function(s){s?n(s):t([e.server,~~e.port])}))}))},a.prototype._openConnection=function(){var e="".concat(this.secure?"wss":"ws","://").concat(this.server,":").concat(this.port,"/"),t={};"agent"in this.opts.connection&&(t.agent=this.opts.connection.agent),this.ws=new l(e,"irc",t),this.ws.onmessage=this._onMessage.bind(this),this.ws.onerror=this._onError.bind(this),this.ws.onclose=this._onClose.bind(this),this.ws.onopen=this._onOpen.bind(this)},a.prototype._onOpen=function(){var e=this;this._isConnected()&&(this.log.info("Connecting to ".concat(this.server," on port ").concat(this.port,"..")),this.emit("connecting",this.server,~~this.port),this.username=b.get(this.opts.identity.username,b.justinfan()),this._getToken().then((function(t){var n=b.password(t);e.log.info("Sending authentication to server.."),e.emit("logon"),t="twitch.tv/tags twitch.tv/commands",e._skipMembership||(t+=" twitch.tv/membership"),e.ws.send("CAP REQ :"+t),n?e.ws.send("PASS ".concat(n)):b.isJustinfan(e.username)&&e.ws.send("PASS SCHMOOPIIE"),e.ws.send("NICK ".concat(e.username))})).catch((function(t){e.emits(["_promiseConnect","disconnected"],[[t],["Could not get a token."]])})))},a.prototype._getToken=function(){var e,t=this.opts.identity.password;return"function"==typeof t?(e=t())instanceof Promise?e:Promise.resolve(e):Promise.resolve(t)},a.prototype._onMessage=function(e){var t=this;e.data.trim().split("\r\n").forEach((function(e){(e=g.msg(e))&&t.handleMessage(e)}))},a.prototype._onError=function(){var e=this;this.moderators={},this.userstate={},this.globaluserstate={},clearInterval(this.pingLoop),clearTimeout(this.pingTimeout),clearTimeout(this._updateEmotesetsTimer),this.reason=null===this.ws?"Connection closed.":"Unable to connect.",this.emits(["_promiseConnect","disconnected"],[[this.reason]]),this.reconnect&&this.reconnections===this.maxReconnectAttempts&&(this.emit("maxreconnect"),this.log.error("Maximum reconnection attempts reached.")),this.reconnect&&!this.reconnecting&&this.reconnections<=this.maxReconnectAttempts-1&&(this.reconnecting=!0,this.reconnections=this.reconnections+1,this.log.error("Reconnecting in ".concat(Math.round(this.reconnectTimer/1e3)," seconds..")),this.emit("reconnect"),setTimeout((function(){e.reconnecting=!1,e.connect().catch((function(t){return e.log.error(t)}))}),this.reconnectTimer)),this.ws=null},a.prototype._onClose=function(){var e=this;this.moderators={},this.userstate={},this.globaluserstate={},clearInterval(this.pingLoop),clearTimeout(this.pingTimeout),clearTimeout(this._updateEmotesetsTimer),this.wasCloseCalled?(this.wasCloseCalled=!1,this.reason="Connection closed.",this.log.info(this.reason),this.emits(["_promiseConnect","_promiseDisconnect","disconnected"],[[this.reason],[null],[this.reason]])):(this.emits(["_promiseConnect","disconnected"],[[this.reason]]),this.reconnect&&this.reconnections===this.maxReconnectAttempts&&(this.emit("maxreconnect"),this.log.error("Maximum reconnection attempts reached.")),this.reconnect&&!this.reconnecting&&this.reconnections<=this.maxReconnectAttempts-1&&(this.reconnecting=!0,this.reconnections=this.reconnections+1,this.log.error("Could not connect to server. Reconnecting in ".concat(Math.round(this.reconnectTimer/1e3)," seconds..")),this.emit("reconnect"),setTimeout((function(){e.reconnecting=!1,e.connect().catch((function(t){return e.log.error(t)}))}),this.reconnectTimer))),this.ws=null},a.prototype._getPromiseDelay=function(){return this.currentLatency<=600?600:this.currentLatency+100},a.prototype._sendCommand=function(e,t,n,s){var o=this;return new Promise((function(i,r){if(!o._isConnected())return r("Not connected to server.");var a;null!==e&&"number"!=typeof e||(null===e&&(e=o._getPromiseDelay()),b.promiseDelay(e).then((function(){return r("No response from Twitch.")}))),null!==t?(a=b.channel(t),o.log.info("[".concat(a,"] Executing command: ").concat(n)),o.ws.send("PRIVMSG ".concat(a," :").concat(n))):(o.log.info("Executing command: ".concat(n)),o.ws.send(n)),"function"==typeof s?s(i,r):i()}))},a.prototype._sendMessage=function(e,t,n,s){var o=this;return new Promise((function(i,r){if(!o._isConnected())return r("Not connected to server.");if(b.isJustinfan(o.getUsername()))return r("Cannot send anonymous messages.");var a,c=b.channel(t);o.userstate[c]||(o.userstate[c]={}),500<=n.length&&(a=b.splitLine(n,500),n=a[0],setTimeout((function(){o._sendMessage(e,t,a[1],(function(){}))}),350)),o.ws.send("PRIVMSG ".concat(c," :").concat(n));var u={};Object.keys(o.emotesets).forEach((function(e){return o.emotesets[e].forEach((function(e){return(b.isRegex(e.code)?g.emoteRegex:g.emoteString)(n,e.code,e.id,u)}))}));var l=Object.assign(o.userstate[c],g.emotes({emotes:g.transformEmotes(u)||null})),m=b.get(o.opts.options.messagesLogLevel,"info"),h=b.actionMessage(n);h?(l["message-type"]="action",o.log[m]("[".concat(c,"] *<").concat(o.getUsername(),">: ").concat(h[1])),o.emits(["action","message"],[[c,l,h[1],!0]])):(l["message-type"]="chat",o.log[m]("[".concat(c,"] <").concat(o.getUsername(),">: ").concat(n)),o.emits(["chat","message"],[[c,l,n,!0]])),"function"==typeof s?s(i,r):i()}))},a.prototype._updateEmoteset=function(e){var t,n=this,s=void 0!==e;s&&(e===this.emotes?s=!1:this.emotes=e),this._skipUpdatingEmotesets?s&&this.emit("emotesets",e,{}):(t=function(){0n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},o.prototype.once=function(e,t){if(!i(t))throw TypeError("listener must be a function");var n=!1;if(this._events.hasOwnProperty(e)&&"_"===e.charAt(0)){var s,o=1,r=e;for(s in this._events)this._events.hasOwnProperty(s)&&s.startsWith(r)&&o++;e+=o}function a(){"_"!==e.charAt(0)||isNaN(e.substr(e.length-1))||(e=e.substring(0,e.length-1)),this.removeListener(e,a),n||(n=!0,t.apply(this,arguments))}return a.listener=t,this.on(e,a),this},o.prototype.removeListener=function(e,t){var n,s,o,a;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(o=(n=this._events[e]).length,s=-1,n===t||i(n.listener)&&n.listener===t){if(delete this._events[e],this._events.hasOwnProperty(e+"2")&&"_"===e.charAt(0)){var c,u=e;for(c in this._events)this._events.hasOwnProperty(c)&&c.startsWith(u)&&(isNaN(parseInt(c.substr(c.length-1)))||(this._events[e+parseInt(c.substr(c.length-1)-1)]=this._events[c],delete this._events[c]));this._events[e]=this._events[e+"1"],delete this._events[e+"1"]}this._events.removeListener&&this.emit("removeListener",e,t)}else if(r(n)){for(a=o;0n?(t.command=e.slice(n),t):null;for(t.command=e.slice(n,s),n=s+1;32===e.charCodeAt(n);)n++;for(;n").replace(/\\"\\;/g,'"').replace(/\\'\\;/g,"'")},unescapeIRC:function(e){return e&&"string"==typeof e&&e.includes("\\")?e.replace(r,(function(e,t){return t in c?c[t]:t})):e},escapeIRC:function(e){return e&&"string"==typeof e?e.replace(a,(function(e,t){return t in u?"\\".concat(u[t]):t})):e},addWord:function(e,t){return e.length?e+" "+t:e+t},splitLine:function(e,t){var n=e.substring(0,t).lastIndexOf(" ");return[e.substring(0,n=-1===n?t-1:n),e.substring(n+1)]},extractNumber:function(e){for(var t=e.split(" "),n=0;nCopy Link to browser:
${verificationUri}
+ `;
+ }
+
+ async pollForToken(deviceCode, clientId) {
+ const endpoint = "https://id.twitch.tv/oauth2/token";
+ const body = new FormData();
+ body.append("client_id", clientId);
+ body.append(
+ "grant_type",
+ "urn:ietf:params:oauth:grant-type:device_code"
+ );
+ body.append("device_code", deviceCode);
+
+ const response = await fetch(endpoint, {
+ method: "POST",
+ body,
+ });
+ const data = await response.json();
+
+ if (data.access_token) {
+ return data;
+ } else {
+ console.error("Error:", data);
+ }
+ }
+
+ async saveToken(tokenData) {
+ localStorage.setItem("twitch_token", JSON.stringify(tokenData));
+ }
+
+ getToken() {
+ return JSON.parse(localStorage.getItem("twitch_token")) || null;
+ }
+
+ setupAuthModal() {
+ // modal overlay
+ const modalOverlay = document.createElement("div");
+ modalOverlay.id = "modal-overlay";
+ modalOverlay.style.fontFamily = "Arial, sans-serif";
+ modalOverlay.style.position = "fixed";
+ modalOverlay.style.top = "0";
+ modalOverlay.style.left = "0";
+ modalOverlay.style.width = "100%";
+ modalOverlay.style.height = "100%";
+ modalOverlay.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
+ modalOverlay.style.display = "flex";
+ modalOverlay.style.justifyContent = "center";
+ modalOverlay.style.alignItems = "center";
+ modalOverlay.style.zIndex = "1000";
+
+ modalOverlay.innerHTML = `
+
+
Authorization Required
+
Step 1:
+
Copy Link to browser:
+
Step 2:
+ Click below AFTER authorizing
+
+
+ `;
+
+ // Append modal overlay to body
+ document.body.appendChild(modalOverlay);
+
+ // Add event listener to the authorization button
+ document.getElementById("authorized").addEventListener("click", () => {
+ document.body.removeChild(modalOverlay);
+ });
+ }
+
+ displayNoClientId() {
+ // modal overlay
+ const modalOverlay = document.createElement("div");
+ modalOverlay.id = "modal-overlay";
+ modalOverlay.style.position = "fixed";
+ modalOverlay.style.top = "0";
+ modalOverlay.style.left = "0";
+ modalOverlay.style.width = "100%";
+ modalOverlay.style.height = "100%";
+ modalOverlay.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
+ modalOverlay.style.display = "flex";
+ modalOverlay.style.justifyContent = "center";
+ modalOverlay.style.alignItems = "center";
+ modalOverlay.style.zIndex = "1000";
+ modalOverlay.style.fontFamily = "Arial, sans-serif";
+
+ modalOverlay.innerHTML = `
+
+
Missing Client ID
+
+
+ Step 2:
+ Enter information for the app.
+ Redirect URL: http://localhost
+ Category: Chat Bot
+ Client Type: Public
+
+
+ Step 3:
+ Obtain Client ID from the registered application
+
+
+ Step 4:
+ Enter Client ID in index.js file
+
+
+
+ `;
+
+ // Append modal overlay to body
+ document.body.appendChild(modalOverlay);
+
+ // Add event listener to the refresh button
+ document
+ .getElementById("refresh-button")
+ .addEventListener("click", () => {
+ location.reload();
+ });
+ }
+
+ async refreshToken(data) {
+ const now = Date.now();
+ const url = "https://id.twitch.tv/oauth2/token";
+ const body = new URLSearchParams({
+ client_id: data.client_id,
+ grant_type: "refresh_token",
+ refresh_token: data.refresh_token,
+ });
+
+ const res = await fetch(url, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ body,
+ });
+
+ const json = await res.json();
+
+ if (!res.ok) {
+ throw new Error(
+ `[${res.status}] ${json.message || "Failed to refresh token"}`
+ );
+ }
+
+ return {
+ ...json,
+ createdAt: now,
+ };
+ }
+
+ async init() {
+ return new Promise(async (resolve, reject) => {
+ let token = await this.getToken();
+
+ if (
+ token &&
+ this.clientId &&
+ token.client_id == this.clientId &&
+ token.scopes == this.scopes
+ ) {
+ try {
+ let token_refresh = await this.refreshToken(token);
+
+ const tokenToSave = {
+ client_id: this.clientId,
+ scopes: this.scopes,
+ access_token: token_refresh.access_token,
+ refresh_token: token_refresh.refresh_token,
+ };
+
+ this.access_token = token_refresh.access_token;
+ this.refresh_token = token_refresh.refresh_token;
+
+ await this.saveToken(tokenToSave);
+ resolve(tokenToSave);
+ } catch (error) {
+ console.error("Error refreshing token:", error);
+ reject(error);
+ }
+ } else if (this.clientId == null || this.clientId == "") {
+ this.displayNoClientId();
+ reject(new Error("Client ID is missing"));
+ } else {
+ this.setupAuthModal();
+ var codeData = await this.startAuthFlow();
+
+ document
+ .getElementById("authorized")
+ .addEventListener("click", async (e) => {
+ try {
+ await this.continueAuthFlow(codeData);
+ location.reload();
+ resolve();
+ } catch (error) {
+ reject(error);
+ }
+ });
+ }
+ });
+ }
+}
+
+export default TwitchAuth;
diff --git a/lib/initComfy.js b/lib/initComfy.js
new file mode 100644
index 0000000..09c5136
--- /dev/null
+++ b/lib/initComfy.js
@@ -0,0 +1,14 @@
+// Usage
+import TwitchAuth from "./handleDCF.js";
+import credentials from "../auth.js";
+
+const twitchAuth = new TwitchAuth(credentials.clientId, credentials.scopes);
+twitchAuth.init().then((data) => {
+ console.log(data);
+ console.log(credentials);
+ ComfyJS.Init(
+ credentials.sender,
+ `oauth:${twitchAuth.access_token}`,
+ credentials.channel
+ );
+});
diff --git a/scripts/processCommand.js b/scripts/processCommand.js
index fd4f779..94b2c08 100644
--- a/scripts/processCommand.js
+++ b/scripts/processCommand.js
@@ -10,6 +10,8 @@ async function processCommand(user, command, message, flags, extra) {
taskName: getSetting("taskName"),
};
+ command = command.toLowerCase();
+
if (getCommand("addTaskCommands").includes(command)) {
let addRequest = await addTask(user, extra.userColor, message);
@@ -461,8 +463,6 @@ async function processCommand(user, command, message, flags, extra) {
await syncPointsToCount();
respond(getResponse("syncCountPoints"), params, extra.id);
} else if (getCommand("addPointsCommands").includes(command)) {
- // !addpoints @user 100
-
if (!isMod(flags)) {
respond(getResponse("notMod"), params, extra.id);
return;