Skip to content

Instantly share code, notes, and snippets.

@CaitlynMainer
Forked from allaryin/auth.json
Created December 13, 2015 18:53
Show Gist options
  • Save CaitlynMainer/244ed80221d6bb782b79 to your computer and use it in GitHub Desktop.
Save CaitlynMainer/244ed80221d6bb782b79 to your computer and use it in GitHub Desktop.
Fiddled-together IRC - Discord bridge bot
{
"irc": {
"server": "irc.esper.net",
"nick": "nick",
"password": "ircpass",
"userName": "MCU Discord-IRC Bridge",
"autoConnect": false,
"channels": ["#channelOne","#SomeOtherchannel"]
},
"discord": {
"email": "user@example.com",
"password": "discordpass"
}
}
# Fiddled-together IRC - Discord bridge bot
# Currently set up to relay messages to channels of the same name.
# Discord APIs are very likely to change, and so this will probably break.
require! {
irc # npm install node-irc
"discord.js": Discord # npm install discord.js
"prelude-ls": { find } # npm install prelude-ls
"./auth" # Configuration goes in auth.json file
# auth.irc contains IRC information, see clientIrc
# auth.discord contains "email" and "password" field
}
messageLimit = 200
String.prototype.limit = (repl) ->
if @length > messageLimit
then "#{@substr 0, messageLimit - 4} #{repl or '...'}"
else @
String.prototype.splice = (index, count, str) ->
"#{@slice 0, index}#str#{@slice index + count}"
# See here for options that may be contained in auth.irc:
# autoConnect MUST be set to false. I've seen strange
# things happen if connect is called a second time.
# https://node-irc.readthedocs.org/en/latest/API.html#client
clientIrc = new irc.Client auth.irc.server, auth.irc.nick, auth.irc
clientIrc.on \registered, !->
# IRC client has no "disconnect" event, so we have to make do with this.
# (clientIrc.conn is not initialized until clientItc.connect is called.)
clientIrc.conn.on \close, !->
console.log "[= IRC =] Sir, they spotted us, I have to kill the connection!"
console.log "[= IRC =] We hacked into their mainframes, sir!"
# Identify with nickserv. This requires the account to be set up already.
clientIrc.say "NickServ", "IDENTIFY #auth.irc.password" if auth.irc.password
clientIrc.on \message#, (nick, channel, message) !->
response = "<#nick> #{message.limit!}"
console.log "[= IRC =] [#channel] #response"
clientDiscord.sendToChannel channel.toLowerCase(), response
clientIrc.on \action, (nick, channel, message) !->
# Ignore actions not sent channel a channel.
#if channel.empty() || !channel.startsWith "#" then return
if !channel || channel == "" || channel.charAt 0 != "#" then return
response = "\\* #nick *#{message.limit!}*"
clientDiscord.sendToChannel channel, response
clientDiscord = new Discord.Client!
clientDiscord.sendToChannel = (channelName, message, callback) !->
# Find the Discord channel with a matching name, or don't send it.
channel = clientDiscord.channels |> find (ch) -> "##{ch.name}" == channelName
clientDiscord.sendMessage channel, message, callback if channel
clientDiscord.on \ready, !->
console.log "[Discord] Ready to serve, copy-sensei."
clientDiscord.on \disconnected, !->
console.log "[Discord] I have failed you, copy-sensei..."
clientDiscord.on \message, (msg) !->
# You receive message events from your own sent messages, so ignore those.
if msg.author.id == clientDiscord.user.id then return
# Only relay messages to channels that the bot is actually in.
if !("##{msg.channel.name}" of clientIrc.chans) then return
from = msg.author.username
text = msg.content
# Replace user mentions (<@long-ass user id>) with actual user name (@username).
# TODO: Do the same for #channel "mentions" (currently displays <#long-ass channel id>)
for user in msg.mentions
text .= replace (new RegExp "<@#{user.id}>", "g"), "@#{user.username}"
# Format message differently if it seems to be a message generated by /me:
# Needs to start and end with a *, no *'s in the message itself, so
# "*this* is *bullshit*" or "*this *is* bullshit* don't count.
response = if /^\*[^\*]+\*$/g.test text
"* #from #{text.substr 1, text.length - 2 .limit!}"
else "<#from> #{text.limit!}"
console.log "[Discord] [##{msg.channel.name}] #response"
# Insert zero-width space in name to avoid
# highlighting IRC users with the same name.
# Because lazyness, this only works for 3+ char nicks.
response .= splice 3, 0, "\u200B"
clientIrc.say "##{msg.channel.name}", response
clientIrc.connect 0 # retryCount = 0
clientDiscord.login auth.discord.email, auth.discord.password
exitHandler = !->
# Wait for both clients to disconnect.
num = 0
onLogout = !->
if ++num >= 2
process.exit!
clientIrc.disconnect "I have been terminated T_T", onLogout
clientDiscord.logout onLogout
process.on \exit, exitHandler
process.on \SIGINT, exitHandler # ctrl-c
#!/bin/sh
nohup lsc cord.ls >discord.log 2>&1 &
tail -F discord.log
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment