mirror of
https://github.com/streamwall/streamwall.git
synced 2025-12-06 01:45:37 -05:00
Add experimental Twitch plays functionality
This commit is contained in:
@@ -54,6 +54,10 @@ json-url = ["https://woke.net/api/streams.json"]
|
||||
#interval = 60
|
||||
#delay = 30
|
||||
|
||||
[twitch.vote]
|
||||
#template = "Switching to #<%- selectedIdx %> (with <%- voteCount %> votes)"
|
||||
#interval = 15
|
||||
|
||||
[cert]
|
||||
# SSL certificates (optional)
|
||||
# If you specify an https:// URL for the "webserver" option, a certificate will be automatically generated and signed by Let's Encrypt.
|
||||
|
||||
@@ -4,10 +4,12 @@ import ejs from 'ejs'
|
||||
import { State } from 'xstate'
|
||||
import { ChatClient, SlowModeRateLimiter, LoginError } from 'dank-twitch-irc'
|
||||
|
||||
const VOTE_RE = /^!(\d+)$/
|
||||
|
||||
export default class TwitchBot extends EventEmitter {
|
||||
constructor(config) {
|
||||
super()
|
||||
const { username, token } = config
|
||||
const { username, token, vote } = config
|
||||
this.config = config
|
||||
this.announceTemplate = ejs.compile(config.announce.template)
|
||||
const client = new ChatClient({
|
||||
@@ -23,6 +25,12 @@ export default class TwitchBot extends EventEmitter {
|
||||
this.dwellTimeout = null
|
||||
this.announceTimeouts = new Map()
|
||||
|
||||
if (vote.interval) {
|
||||
this.voteTemplate = ejs.compile(config.vote.template)
|
||||
this.votes = new Map()
|
||||
setInterval(this.tallyVotes.bind(this), vote.interval * 1000)
|
||||
}
|
||||
|
||||
client.on('ready', () => {
|
||||
this.onReady()
|
||||
})
|
||||
@@ -38,6 +46,9 @@ export default class TwitchBot extends EventEmitter {
|
||||
console.error('Twitch bot disconnected due to error:', err)
|
||||
}
|
||||
})
|
||||
client.on('PRIVMSG', (msg) => {
|
||||
this.onMsg(msg)
|
||||
})
|
||||
}
|
||||
|
||||
connect() {
|
||||
@@ -105,4 +116,50 @@ export default class TwitchBot extends EventEmitter {
|
||||
}, announce.interval * 1000)
|
||||
this.announceTimeouts.set(listeningURL, timeout)
|
||||
}
|
||||
|
||||
async tallyVotes() {
|
||||
const { client } = this
|
||||
const { channel } = this.config
|
||||
if (this.votes.size === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
let voteCount = 0
|
||||
let selectedIdx = null
|
||||
for (const [idx, value] of this.votes) {
|
||||
if (value > voteCount) {
|
||||
voteCount = value
|
||||
selectedIdx = idx
|
||||
}
|
||||
}
|
||||
|
||||
const msg = this.voteTemplate({ selectedIdx, voteCount })
|
||||
await client.say(channel, msg)
|
||||
|
||||
// Index spaces starting with 1
|
||||
this.emit('setListeningView', selectedIdx - 1)
|
||||
|
||||
this.votes = new Map()
|
||||
}
|
||||
|
||||
onMsg(msg) {
|
||||
const { grid, vote } = this.config
|
||||
if (!vote.interval) {
|
||||
return
|
||||
}
|
||||
|
||||
const match = msg.messageText.match(VOTE_RE)
|
||||
if (!match) {
|
||||
return
|
||||
}
|
||||
|
||||
let idx
|
||||
try {
|
||||
idx = Number(match[1])
|
||||
} catch (err) {
|
||||
return
|
||||
}
|
||||
|
||||
this.votes.set(idx, (this.votes.get(idx) || 0) + 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,6 +98,8 @@ function parseArgs() {
|
||||
'twitch.color',
|
||||
'twitch.announce.template',
|
||||
'twitch.announce.interval',
|
||||
'twitch.vote.template',
|
||||
'twitch.vote.interval',
|
||||
],
|
||||
'Twitch Chat',
|
||||
)
|
||||
@@ -133,6 +135,15 @@ function parseArgs() {
|
||||
number: true,
|
||||
default: 30,
|
||||
})
|
||||
.option('twitch.vote.template', {
|
||||
describe: 'Message template for vote result announcements',
|
||||
default: 'Switching to #<%- selectedIdx %> (with <%- voteCount %> votes)',
|
||||
})
|
||||
.option('twitch.vote.interval', {
|
||||
describe: 'Time interval (in seconds) between votes (0 to disable)',
|
||||
number: true,
|
||||
default: 0,
|
||||
})
|
||||
.group(
|
||||
[
|
||||
'control.username',
|
||||
@@ -382,6 +393,9 @@ async function main() {
|
||||
|
||||
if (argv.twitch.token) {
|
||||
twitchBot = new TwitchBot(argv.twitch)
|
||||
twitchBot.on('setListeningView', (idx) => {
|
||||
streamWindow.setListeningView(idx)
|
||||
})
|
||||
twitchBot.connect()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user