[erlang-questions] What's a solid way to have erlang automatically send email.
Raimo Niskanen
raimo+erlang-questions@REDACTED
Wed Nov 17 10:47:19 CET 2010
On Tue, Nov 16, 2010 at 09:37:39PM +1100, Anthony Shipman wrote:
> On Mon, 15 Nov 2010 10:31:09 am G.S. wrote:
> > Hello,
> >
> > I have a website where the administrator needs to receive email alert (to
> > login and fix a problem) when certain events occur. Is there an Erlang
> > module that allows one to easily send out an email? Or something that can
> > be used in the same manner?
> >
> > Thanks,
> > -Gene
>
> On UNIX, you could feed the text into stdin of /usr/sbin/sendmail
> or /usr/bin/mutt. erlang:open_port() will let you do this.
Here is a part of a larger (escript) program that does that.
I have made a perhaps overflexible cmd/2,3 that returns
a lazy list which may look like overengineering in this
case, but makes sense in the larger program.
%% Send a completely formatted mail with all
%% headers through the sendmail command.
sendmail(Text) ->
{_,Port,Cont} =
cmd(
["sendmail","/usr/sbin/sendmail",
"/usr/lib/sendmail","/usr/libexec/sendmail"],
["-t","-i"]),
erlang:port_command(Port, Text),
result(Cont).
result([_|Cont]) ->
result(Cont);
result(Fun) when is_function(Fun) ->
result(Fun());
result(Result) ->
Result.
%% Generic execute command returning a lazy list
%% -> {[Command|Args],Port,Cont}
%%
%% Cont() -> [Line, ... | Cont] | []
%% Cont() -> ExitStatus
cmd(Cmds, Args) ->
cmd(Cmds, Args, []).
%%
cmd([Cmd|Cmds], Args, Opts) ->
case os:find_executable(Cmd) of
false ->
case Cmds of
[] ->
erlang:error({not_found_executable,Cmd});
_ ->
cmd(Cmds, Args, Opts)
end;
Command ->
cmd_open(Command, Args, Opts)
end.
cmd_open(Command, Args, Opts) ->
cmd_open_port(Command, {spawn_executable,Command}, [{args,Args}|Opts]).
cmd_open_port(Command, PortName, Opts) ->
Port = erlang:open_port(PortName, [{line,80},exit_status,eof,hide|Opts]),
{Command,Port,cmd_cont(Port, [], undefined, false)}.
cmd_cont(Port, Buf, Exit, Eof) ->
fun () ->
cmd_loop(Port, Buf, Exit, Eof)
end.
cmd_loop(Port, Buf, Exit, Eof) ->
receive
{Port,{data,{Flag,Line}}} ->
case Flag of
noeol ->
cmd_loop(Port, lists:reverse(Line, Buf), Exit, Eof);
eol ->
Data = lists:reverse(Buf, Line),
[Data|cmd_cont(Port, [], Exit, Eof)]
end;
{Port,{exit_status,Status}} when Exit =:= undefined ->
case Eof of
true ->
cmd_close(Port, Buf, Status);
false ->
cmd_loop(Port, Buf, Status, Eof)
end;
{Port,eof} when Eof =:= false ->
case Exit of
undefined ->
cmd_loop(Port, Buf, Exit, true);
Status ->
cmd_close(Port, Buf, Status)
end;
{Port,_} = Unexpected ->
io:format("Unexpected from port: ~p~n~n", [Unexpected]),
cmd_loop(Port, Buf, Exit, Eof)
end.
cmd_close(Port, Buf, Status) ->
catch port_close(Port),
case Buf of
[] ->
Status;
Buf ->
[lists:reverse(Buf)|Status]
end.
>
> --
> Anthony Shipman Mamas don't let your babies
> als@REDACTED grow up to be outsourced.
>
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:erlang-questions-unsubscribe@REDACTED
--
/ Raimo Niskanen, Erlang/OTP, Ericsson AB
More information about the erlang-questions
mailing list