Skip to content

Instantly share code, notes, and snippets.

@marcaddeo
Created January 23, 2012 23:45
Show Gist options
  • Save marcaddeo/1666548 to your computer and use it in GitHub Desktop.
Save marcaddeo/1666548 to your computer and use it in GitHub Desktop.
A simple IRC bot
{Hook} = require 'hook.io'
irc = require 'irc'
http = require 'http'
redis = require 'redis'
config =
name: 'Hank'
delimiter: '@'
password: 'password'
server: 'irc.rizon.net'
channel: '#channel'
modes =
OWNER: 5
PROTECT: 4
OP: 3
HOP: 2
VOICE: 1
NONE: 0
'~': 5
'&': 4
'@': 3
'%': 2
'+': 1
'': 0
ircCodes =
'bold': '\02',
'underline': '\037',
'reverse': '\026',
'off': '\017',
'ctcp': '\01',
'color': '\003',
'colors':
'white': '\00300',
'black': '\00301',
'blue': '\00302',
'green': '\00303',
'red': '\00304',
'brown': '\00305',
'purple': '\00306',
'orange': '\00307',
'yellow': '\00308',
'neongreen': '\00309',
'teal': '\00310',
'cyan': '\00311',
'blue': '\00312',
'pink': '\00313',
'grey': '\00314',
'silver': '\00315'
irc.Client::on = (msg, callback) ->
@addListener msg, callback
hook = new Hook
name: 'hank'
debug: false
hank = new irc.Client config.server, config.name,
userName: 'Hank'
realName: 'Hank'
debug: false
showErrors: true
autoRejoin: true
autoConnect: true
channels: [ config.channel ]
floodProtection: true
client = redis.createClient()
hook.start()
client.on 'error', (err) ->
console.log "Redis connection error to #{client.host}:#{client.port} - #{err}"
cmd_help = (command) ->
u = command.from
hank.notice u, '____ Help Menu _____________________'
hank.notice u, 'Hank is a simple bot made for rainbow.tv by jackyyll'
hank.notice u, '____ Commands ______________________'
for c in Object.keys commands
do (c) ->
string = "@#{c}"
for alias in commands[c].alias
string += ", @#{alias}"
string += " - #{commands[c].description}"
hank.notice u, string if command.mode >= commands[c].mode
cmd_nowplaying = (command) ->
hook.emit 'get_nowplaying'
cmd_next = (command) ->
hook.emit 'get_next'
cmd_viewers = (command) ->
client.get 'stream', (err, reply) ->
return if err isnt null
options =
host: "x#{reply}x.api.channel.livestream.com"
port: 80
path: '/2.0/livestatus.json'
body = ''
req = http.get options, (res) ->
res.on 'data', (chunk) ->
body += chunk
res.on 'end', ->
json = JSON.parse body
hank.notice command.from, "Current Viewers: #{json.channel.currentViewerCount}"
req.on 'error', (err) ->
console.log 'Got Error:', err.message
cmd_stream = (command) ->
client.set 'stream', command.args.split(' ')[0]
hook.emit 'stream'
cmd_list = (command) ->
hank.notice command.from, 'Movie List: http://rtv.scumba.gs/movies.php'
cmd_schedule = (command) ->
hank.notice command.from, 'Current Playlist: http://rtv.scumba.gs/schedule.html'
commands =
help:
function: cmd_help
description: "Displays this menu!"
alias: []
mode: modes.NONE
nowplaying:
function: cmd_nowplaying
description: 'Gets the currently playing movie or tv show.'
alias: ['np']
mode: modes.NONE
next:
function: cmd_next
description: 'Gets the next movie in the playlist.'
alias: []
mode: modes.NONE
viewers:
function: cmd_viewers
description: 'Gets the current number of viewers on the current channel.'
alias: ['v']
mode: modes.OP
stream:
function: cmd_stream
description: 'Sets the channel for the stream.'
alias: []
mode: modes.PROTECT
list:
function: cmd_list
description: 'Displays a link to the movie list.'
alias: []
mode: modes.NONE
schedule:
function: cmd_schedule
description: 'Displays a link to the current schedule.'
alias: []
mode: modes.NONE
hank.on 'registered', ->
@say 'NickServ', "IDENTIFY #{config.password}"
hank.on 'error', (message) ->
console.log message
joinCounter = 0
hank.on 'join', (channel, who) ->
joinCounter++
if joinCounter is 15
@say config.channel, "#{ircCodes.bold}To change your nickname, type /nick <NewNick>#{ircCodes.bold}"
joinCounter = 0
hank.on 'message', (from, to, message) ->
return if message.charAt(0) isnt config.delimiter || to isnt config.channel
command = new Object
split = message.split ' '
userModes = @chans[to]?.users[from].split ''
for uMode, i in userModes
userModes[i] = modes[uMode]
mode = if not userModes.length then modes.NONE else Math.max.apply Math, userModes
command.name = split[0].substring(1).toLowerCase()
split.shift()
command.args = if split.length then split.join(' ') else null
command.from = from
command.channel = to
command.mode = mode
for c in Object.keys commands
if c is command.name
if mode >= commands[c].mode then (commands[c].function)(command)
for alias in commands[c].alias
if alias is command.name
if mode >= commands[c].mode then (commands[c].function)(command)
hook.on '*::now_playing', (data) ->
if data is 'ERROR'
hank.say config.channel, 'Error getting currently playing movie'
else
passed = new Date(data.passed)
hours = String(passed.getUTCHours())
minutes = String(passed.getUTCMinutes())
seconds = String(passed.getUTCSeconds())
hours = if hours.length < 2 then "0#{hours}" else hours
minutes = if minutes.length < 2 then "0#{minutes}" else minutes
seconds = if seconds.length < 2 then "0#{seconds}" else seconds
total = data.duration.split('.')[0]
hank.say config.channel, "#{ircCodes.bold}Now Playing: #{ircCodes.underline}#{data.name}#{ircCodes.underline} (#{data.year}) [#{hours}:#{minutes}:#{seconds}/#{total}]"
hook.on '*::next', (data) ->
if data is 'ERROR'
hank.say config.channel, 'Error getting next playing movie'
else
hank.say config.channel, "#{ircCodes.bold}Coming Up: #{ircCodes.underline}#{data.name}#{ircCodes.underline} (#{data.year})"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment