defmodule Irc.Shout do alias Irc.{Connection, Line} def shout(nick, host, target, message, opts \\ []) do opts = opts |> Keyword.put(:reconnect, false) |> Keyword.put_new(:await_up_timeout, :timer.seconds(30)) |> Keyword.put_new(:quit, "bye") do_shout(Connection.start(nick, host, opts), target, message, opts) end def do_shout({:ok, conn}, target, message, opts) do mon = Process.monitor(conn) result = with \ {_, {:ok, _info}} <- {:await_up, Connection.await_up(conn, Keyword.get(opts, :await_up_timeout))}, {_, :ok} <- {:join, join(conn, target)}, {_, :ok} <- {:send, Connection.sendline(conn, ['PRIVMSG ', target, ' :', message])} do :ok else error -> error end Process.demonitor(mon, [:flush]) Connection.disconnect(conn, Keyword.get(opts, :quit), true) Connection.flush(conn) result end def do_shout(error, _, _, _) do error end def join(conn, target = "#"<>_) do case Connection.sendline(conn, ['JOIN ', target]) do :ok -> await_join(conn, target) error -> error end end def join(conn, _) do :ok end def await_join(conn, target) do receive do {:irc_conn_line, conn, %Line{command: "JOIN", args: [target]}} -> :ok {:irc_conn_error, conn, reason} -> {:error, reason} {:DOWN, _, _, conn, reason} -> {:error, {:conn_down, reason}} after 10_000 -> :join_timeout end end end