summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorjeffweiss <jeff.weiss@puppetlabs.com>2014-11-24 00:24:37 -0800
committerjeffweiss <jeff.weiss@puppetlabs.com>2014-11-24 00:24:37 -0800
commit56e1e06e0e3c44c58f02a73be5feed3a51dd3608 (patch)
treec6abd0633576ac48848ed57ef74bf5057848d1e8 /examples
parentVersion 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.ex38
-rw-r--r--examples/ohai/login_handler.ex32
-rw-r--r--examples/ohai/ohai_handler.ex37
-rw-r--r--examples/ohai/ohai_irc.ex23
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