-record(irc_state, {instance, % instance name
config, % initial configuration params
+ joined = false,% indicates whether we have joined the channels
socket,
buffer = "" % for the TCP session
}).
gen_server:start_link(?MODULE,
{Instance, Config}, []).
-init({Instance, Config = {Host, Port, Nick, Realname, Channels}}) ->
+init({Instance, Config = {Host, Port, Nick, Realname, _Channels}}) ->
{ok, Socket} = gen_tcp:connect(Host, Port, [list]),
send_command(#irc_command{command = "NICK", middles = [Nick]}),
send_command(#irc_command{command = "USER",
middles = ["user", "host", "server"],
trailing = Realname
}),
- lists:foreach(fun join_channel/1, Channels),
State = #irc_state{instance = Instance,
config = Config,
socket = Socket
%% Handle incoming data
handle_info({tcp, _Socket, Data}, State = #irc_state{ socket = _Socket }) ->
Buf1 = State#irc_state.buffer ++ Data,
- Buf2 = case parse_lines(Buf1) of
+ NewState = case parse_lines(Buf1) of
{ok, Lines, Rem} ->
- lists:foreach(fun do_line/1, Lines),
- Rem;
+ State1 = lists:foldl(fun do_line/2, State, Lines),
+ State1#irc_state{buffer = Rem};
none ->
- Buf1
+ State#irc_state{buffer = Buf1}
end,
- {noreply, State#irc_state{buffer = Buf2}}.
+ {noreply, NewState}.
%% @doc Handles a line received from the IRC server.
-do_line(Line) ->
+do_line(Line, State) ->
Command = irc_util:list_to_command(Line),
case Command#irc_command.command of
"PING" ->
% return the command to the IRC server with a PONG
% leaving the rest of the line (usually a timestamp) alone
NewCommand = Command#irc_command{prefix = none, command = "PONG"},
- send_command(NewCommand);
+ send_command(NewCommand),
+ State;
+ "376" when State#irc_state.joined == false ->
+ % end of MOTD, which should normally be sent on connect
+ error_logger:info_msg("Joining my channels now.", []),
+ {_, _, _, _, Channels} = State#irc_state.config,
+ lists:foreach(fun join_channel/1, Channels),
+ State#irc_state{joined = true};
_ ->
% for now, just know that it happened
- error_logger:info_msg("Received a line ~p~n", [Line])
+ error_logger:info_msg("Received a line ~p~n", [Line]),
+ State
end.
terminate(_Reason, _State) ->