diff options
author | jeffweiss <jeff.weiss@puppetlabs.com> | 2014-11-24 00:24:37 -0800 |
---|---|---|
committer | jeffweiss <jeff.weiss@puppetlabs.com> | 2014-11-24 00:24:37 -0800 |
commit | 56e1e06e0e3c44c58f02a73be5feed3a51dd3608 (patch) | |
tree | c6abd0633576ac48848ed57ef74bf5057848d1e8 /examples | |
parent | Version 0.9.0 (diff) |
create example client application. Close #13.
Prior to this commit, the README illustrated a simplified version of a
client; however, this simplified version did not actually join the
specified channel because logon takes a non-trivial amount of time and
the code, as illustrated in the README, will immediately attempt to join
a channel even though we're not fully logged on yet. This has taken
several people quite a while to figure out. This commit adds an example
application (along with a stripped down version on it in the README)
with 3 handlers: Connection, Login, and business logic.
The ConnectionHandler is responsible to initiating the connection to the
IRC server and then when we've received a message that we've connected,
initiating the logon process. The LoginHandler waits until we've
received the logged_in message and then attempts to join the channels.
Next the bot's OhaiHandler will greet people as they enter the channels
that itself had just joined.
Diffstat (limited to 'examples')
-rw-r--r-- | examples/ohai/connection_handler.ex | 38 | ||||
-rw-r--r-- | examples/ohai/login_handler.ex | 32 | ||||
-rw-r--r-- | examples/ohai/ohai_handler.ex | 37 | ||||
-rw-r--r-- | examples/ohai/ohai_irc.ex | 23 |
4 files changed, 130 insertions, 0 deletions
diff --git a/examples/ohai/connection_handler.ex b/examples/ohai/connection_handler.ex new file mode 100644 index 0000000..2ba5aad --- /dev/null +++ b/examples/ohai/connection_handler.ex @@ -0,0 +1,38 @@ +defmodule ConnectionHandler do + defmodule State do + defstruct host: "chat.freenode.net", + port: 6667, + pass: "ohaipassword", + nick: "ohaibot", + user: "ohaibot", + name: "ohaibot welcomes you", + client: nil + end + + def start_link(client, state \\ %State{}) do + GenServer.start_link(__MODULE__, [%{state | client: client}]) + end + + def init([state]) do + ExIrc.Client.add_handler state.client, self + ExIrc.Client.connect! state.client, state.host, state.port + {:ok, state} + end + + def handle_info({:connected, server, port}, state) do + debug "Connected to #{server}:#{port}" + ExIrc.Client.logon state.client, state.pass, state.nick, state.user, state.name + {:noreply, state} + end + + # Catch-all for messages you don't care about + def handle_info(msg, state) do + debug "Received unknown messsage:" + IO.inspect msg + {:noreply, state} + end + + defp debug(msg) do + IO.puts IO.ANSI.yellow() <> msg <> IO.ANSI.reset() + end +end diff --git a/examples/ohai/login_handler.ex b/examples/ohai/login_handler.ex new file mode 100644 index 0000000..159e191 --- /dev/null +++ b/examples/ohai/login_handler.ex @@ -0,0 +1,32 @@ +defmodule LoginHandler do + @moduledoc """ + This is an example event handler that listens for login events and then + joins the appropriate channels. We actually need this because we can't + join channels until we've waited for login to complete. We could just + attempt to sleep until login is complete, but that's just hacky. This + as an event handler is a far more elegant solution. + """ + def start_link(client, channels) do + GenServer.start_link(__MODULE__, [client, channels]) + end + + def init([client, channels]) do + ExIrc.Client.add_handler client, self + {:ok, {client, channels}} + end + + def handle_info(:logged_in, state = {client, channels}) do + debug "Logged in to server" + channels |> Enum.map(&ExIrc.Client.join client, &1) + {:noreply, state} + end + + # Catch-all for messages you don't care about + def handle_info(_msg, state) do + {:noreply, state} + end + + defp debug(msg) do + IO.puts IO.ANSI.yellow() <> msg <> IO.ANSI.reset() + end +end diff --git a/examples/ohai/ohai_handler.ex b/examples/ohai/ohai_handler.ex new file mode 100644 index 0000000..3d411f0 --- /dev/null +++ b/examples/ohai/ohai_handler.ex @@ -0,0 +1,37 @@ +defmodule OhaiHandler do + @moduledoc """ + This is an example event handler that greets users when they join a channel + """ + def start_link(client) do + GenServer.start_link(__MODULE__, [client]) + end + + def init([client]) do + ExIrc.Client.add_handler client, self + {:ok, client} + end + + def handle_info({:joined, channel}, client) do + debug "Joined #{channel}" + {:noreply, client} + end + + def handle_info({:joined, channel, user}, client) do + # ExIrc currently has a bug that doesn't remove the \r\n from the end + # of the channel name with it sends along this kind of message + # so we ensure any trailing or leading whitespace is explicitly removed + channel = String.strip(channel) + debug "#{user} joined #{channel}" + ExIrc.Client.msg(client, :privmsg, channel, "ohai #{user}") + {:noreply, client} + end + + # Catch-all for messages you don't care about + def handle_info(_msg, state) do + {:noreply, state} + end + + defp debug(msg) do + IO.puts IO.ANSI.yellow() <> msg <> IO.ANSI.reset() + end +end diff --git a/examples/ohai/ohai_irc.ex b/examples/ohai/ohai_irc.ex new file mode 100644 index 0000000..27c05a2 --- /dev/null +++ b/examples/ohai/ohai_irc.ex @@ -0,0 +1,23 @@ +defmodule OhaiIrc do + use Application + + # See http://elixir-lang.org/docs/stable/elixir/Application.html + # for more information on OTP Applications + def start(_type, _args) do + import Supervisor.Spec, warn: false + + {:ok, client} = ExIrc.start_client! + + children = [ + # Define workers and child supervisors to be supervised + worker(ConnectionHandler, [client]), + worker(LoginHandler, [client, ["#ohaibot-testing"]]), + worker(OhaiHandler, [client]) + ] + + # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html + # for other strategies and supported options + opts = [strategy: :one_for_one, name: OhaiIrc.Supervisor] + Supervisor.start_link(children, opts) + end +end |