add bot to announce playlist and current track #2
140
src/playlistbot.js
Normal file
140
src/playlistbot.js
Normal file
@ -0,0 +1,140 @@
|
||||
const icy = require('icy')
|
||||
const devnull = require('dev-null')
|
||||
const IRC = require('irc-framework')
|
||||
const bot = new IRC.Client()
|
||||
const chalk = require('chalk')
|
||||
|
||||
const radioUrl = 'https://radio.anarchyplanet.org/live'
|
||||
const owners = ['data', 'notnull']
|
||||
var channels = ['#traumschule', '#apradio', '#anarchyplanet']
|
||||
var announcing = ['#apradio']
|
||||
const host = process.env.HOST || 'irc.anarchyplanet.org'
|
||||
const port = process.env.PORT || 6667
|
||||
const nick = process.env.NICK || 'playlist'
|
||||
|
||||
var currentTrack = {}
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
|
||||
|
||||
// TODO on new streams to /live w/o metadata !np will give outdated data
|
||||
|
||||
const log = message => {
|
||||
console.log(chalk.magenta(message))
|
||||
}
|
||||
|
||||
const announceTrack = msg => {
|
||||
announcing.map(channel => bot.say(channel, msg))
|
||||
}
|
||||
|
||||
const connectRadio = () => {
|
||||
log('[ICY] Connecting')
|
||||
try {
|
||||
icy.get(radioUrl, function(res) {
|
||||
console.error(res.headers)
|
||||
|
||||
res.on('metadata', metadata => {
|
||||
const parsed = icy.parse(metadata)
|
||||
const track = parsed.StreamTitle
|
||||
currentTrack = { track }
|
||||
console.error(track)
|
||||
announceTrack(track)
|
||||
})
|
||||
|
||||
res.pipe(devnull())
|
||||
})
|
||||
} catch (e) {
|
||||
log(`[ICY] Failed to connect: $(e.message)`)
|
||||
}
|
||||
}
|
||||
|
||||
const connectIRC = () => {
|
||||
log(`[IRC] Connecting to ${host}`)
|
||||
try {
|
||||
bot.connect({ host, port, nick })
|
||||
bot.on('connected', () => {
|
||||
log(`[IRC] Joining ${channels.join(', ')}`)
|
||||
channels.map(c => bot.join(c))
|
||||
connectRadio()
|
||||
})
|
||||
bot.on('socket close', () => {
|
||||
log('[IRC] Reconnecting ..')
|
||||
bot.connect({ host, port, nick })
|
||||
})
|
||||
|
||||
// handle commands
|
||||
bot.matchMessage(/^\?np/, event => sendCurrentTrack(event))
|
||||
bot.matchMessage(/^\?help/, event => sendHelp(event))
|
||||
bot.matchMessage(/^\?join/, event => handleJoin(event))
|
||||
bot.matchMessage(/^\?part/, event => handlePart(event))
|
||||
bot.matchMessage(/^\?quit/, event => handleQuit(event))
|
||||
bot.matchMessage(/^\?announce/, event => handleAnnounce(event))
|
||||
bot.matchMessage(/^\?unannounce/, event => handleUnannounce(event))
|
||||
bot.matchMessage(/^\?channels/, event => sendChannels(event))
|
||||
} catch (e) {
|
||||
log(`[IRC] Failed to connect: ${e.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
const sendHelp = event => {
|
||||
const chans = announcing.join(', ')
|
||||
const helpMsg = `Announcing radio playlist in ${chans} | ?np shows current track.`
|
||||
const adminMsg =
|
||||
' ?[un]announce [OPTIONAL #chan] shows playlist in current or supplied channel. Other comamnds: ?channels ?join ?part ?quit'
|
||||
if (owners.includes(event.nick)) return event.reply(helpMsg + adminMsg)
|
||||
event.reply(helpMsg)
|
||||
}
|
||||
|
||||
const sendCurrentTrack = event => {
|
||||
const { error, track } = currentTrack
|
||||
if (error) return event.reply('Something went wrong.')
|
||||
if (track.length === 0) return event.reply('Nothing is currently playing.')
|
||||
event.reply(track)
|
||||
}
|
||||
|
||||
const sendChannels = event => {
|
||||
if (!owners.includes(event.nick)) return
|
||||
const str = [announcing.join(' '), channels.join(' ')]
|
||||
event.reply(`Announcing radio playlist in ${str[0]}. Joined ${str[1]}.`)
|
||||
}
|
||||
|
||||
const handleJoin = event => {
|
||||
if (!owners.includes(event.nick)) return
|
||||
const channel = event.message.split(' ')[1]
|
||||
log(`Joining ${channel} (${event.nick})`)
|
||||
bot.join(channel)
|
||||
channels.concat(channel)
|
||||
}
|
||||
|
||||
const handlePart = event => {
|
||||
if (!owners.includes(event.nick)) return
|
||||
const channel = event.message.split(' ')[1]
|
||||
log(`Parting ${channel} (${event.nick})`)
|
||||
bot.part(channel)
|
||||
channels.filter(c => c !== channel)
|
||||
}
|
||||
|
||||
const handleQuit = event => {
|
||||
if (!owners.includes(event.nick)) return
|
||||
log(`${event.nick} requested to quit.`)
|
||||
bot.quit('time to die')
|
||||
process.exit()
|
||||
}
|
||||
|
||||
const handleAnnounce = event => {
|
||||
console.log(event)
|
||||
if (!owners.includes(event.nick)) return
|
||||
const arg = event.message.split(' ')[1]
|
||||
const channel = arg ? arg : event.target
|
||||
log(`Announcing in ${channel} (${event.nick})`)
|
||||
announcing = announcing.concat(channel)
|
||||
if (!arg) sendCurrentTrack(event)
|
||||
}
|
||||
|
||||
const handleUnannounce = event => {
|
||||
if (!owners.includes(event.nick)) return
|
||||
const arg = event.message.split(' ')[1]
|
||||
const channel = arg ? arg : event.target
|
||||
log(`Unannouncing in ${channel} (${event.nick})`)
|
||||
announcing = announcing.filter(c => c !== channel)
|
||||
}
|
||||
|
||||
connectIRC()
|
Loading…
Reference in New Issue
Block a user