Skip to content

Instantly share code, notes, and snippets.

@nicholasf
Created February 17, 2014 23:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicholasf/9061767 to your computer and use it in GitHub Desktop.
Save nicholasf/9061767 to your computer and use it in GitHub Desktop.
#A simple, one server, multiple channels IRC bridge.
defprotocol Speaker do
def speak(spoon_response, device)
end
defmodule Bridge.IRC do
use GenServer.Behaviour
@moduledoc false
defimpl Speaker, for: SpoonResponse do
def speak(spoon_response, socket) do
IO.puts('ok')
IO.puts(spoon_response.msg)
IO.inspect(socket)
Bridge.IRC.say(socket, spoon_response.msg)
end
end
def run(vocab) do
{ :ok, config } = :application.get_env(:spoonbot, :conf)
{ server, port, nickname } = Enum.at(config, 0)
{ :ok, socket } = :gen_tcp.connect(:erlang.binary_to_list(server), port, [:binary, {:active, false}])
:ok = transmit(socket, "NICK #{nickname}")
:ok = transmit(socket, "USER #{nickname} #{server} spoonbot :spoonbot")
do_listen(socket, vocab)
end
def do_listen(socket, vocab) do
ping = ~r/\APING/
motd_end = ~r/\/MOTD/
msg = ~r/PRIVMSG spoonbot/
case :gen_tcp.recv(socket, 0) do
{ :ok, data } ->
IO.puts "#{data}"
if Regex.match?(motd_end, data), do: join(socket)
if Regex.match?(ping, data), do: pong(socket, data)
if Regex.match?(msg, data) do
matched_command = Enum.find(vocab, fn(command) -> Regex.match?(command.pattern, data) end)
IO.puts "ok .... "
Speaker.speak(matched_command.cmd(data), socket)
end
do_listen(socket, vocab)
{ :error, :closed } ->
IO.puts "The client closed the connection..."
end
end
def transmit(socket, msg) do
IO.puts "sending #{msg}"
:gen_tcp.send(socket, "#{msg} \r\n")
end
#needs to become channel aware
def say(socket, data) do
pieces = String.split(data, ":")
phrase = Enum.drop(pieces, 2)
IO.puts("Saying: #{phrase}")
transmit(socket, "PRIVMSG #cbt :#{phrase}")
end
def join(socket) do
{ :ok, config} = :application.get_env(:spoonbot, :conf )
channel_list = Enum.at(config, 1)
joiner = fn
{ channel } -> transmit(socket, "JOIN #{ channel }")
{ channel, password } -> transmit(socket, "JOIN #{ channel } #{ password }")
end
Enum.each(channel_list, joiner)
end
def pong(socket, data) do
server = Enum.at(Regex.split(~r/\s/, data), 1)
transmit(socket, "PONG #{ server }")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment