mirror of https://github.com/nealey/irc-bot
112 lines
3.0 KiB
OCaml
112 lines
3.0 KiB
OCaml
type bot = {
|
|
store: Infobot.t;
|
|
}
|
|
|
|
let debug = prerr_endline
|
|
|
|
let file_descr_of_int (i:int) =
|
|
let blob = Marshal.to_string i [] in
|
|
(Marshal.from_string blob 0 : Unix.file_descr)
|
|
|
|
let write iobuf command args text =
|
|
let cmd = Command.create None command args text in
|
|
debug ("--> " ^ (Command.as_string cmd));
|
|
Iobuf.write iobuf cmd
|
|
|
|
let msg iobuf recip text =
|
|
write iobuf "PRIVMSG" [recip] (Some text)
|
|
|
|
let split = Str.split (Str.regexp "[ \t]*\r?\n")
|
|
|
|
(** Callback upon completion of the external command helper *)
|
|
let extern_callback iobuf sender forum text =
|
|
let lines = split text in
|
|
let nlines = List.length lines in
|
|
let recip =
|
|
if (nlines > 5) then begin
|
|
if (forum <> sender) then
|
|
msg iobuf forum (Format.sprintf "%d lines, sending privately" nlines);
|
|
sender
|
|
end else
|
|
forum
|
|
in
|
|
let rec f = function
|
|
| [] ->
|
|
()
|
|
| "" :: tl ->
|
|
f tl
|
|
| line :: tl ->
|
|
if line.[0] == ':' then
|
|
(* Interpret as raw IRC commands *)
|
|
let ine = Str.string_after line 1 in
|
|
let cmd = Command.from_string ine in
|
|
Iobuf.write iobuf cmd
|
|
else
|
|
(* Naive case: send to the recipient *)
|
|
msg iobuf recip line;
|
|
f tl
|
|
in
|
|
f lines
|
|
|
|
let handle_privmsg bot iobuf sender forum text =
|
|
if text.[0] == '.' then
|
|
Process.create_canned
|
|
(Iobuf.dispatcher iobuf)
|
|
text
|
|
(extern_callback iobuf sender forum)
|
|
"./helper"
|
|
[|"./helper"; sender; forum|]
|
|
else
|
|
Infobot.handle_privmsg bot.store (msg iobuf forum) sender forum text
|
|
|
|
let handle_command bot outbuf thisbuf cmd =
|
|
debug ("<-- " ^ (Command.as_string cmd));
|
|
match (Command.as_tuple cmd) with
|
|
| (Some suhost, "PRIVMSG", [target], Some text) ->
|
|
let sender = Irc.nick (Irc.nuhost_of_string suhost) in
|
|
let forum =
|
|
if Irc.is_channel target then
|
|
target
|
|
else
|
|
sender
|
|
in
|
|
handle_privmsg bot outbuf sender forum text
|
|
| (_, "PING", _, text) ->
|
|
write outbuf "PONG" [] text
|
|
| (_, "001", _, _) ->
|
|
write outbuf "JOIN" ["#bot"] None;
|
|
| (Some sender, "JOIN", [], Some chan) ->
|
|
msg outbuf chan "hi asl"
|
|
| _ ->
|
|
()
|
|
|
|
let discard_command iobuf cmd = ()
|
|
|
|
let handle_error iobuf str =
|
|
prerr_endline ("!!! " ^ str)
|
|
|
|
let main () =
|
|
let bot = {store = Infobot.create "info.cdb"} in
|
|
let dispatcher = Dispatch.create () in
|
|
|
|
let conn_out, conn_in =
|
|
Process.spawn "socat" [|"socat";
|
|
"STDIO";
|
|
"OPENSSL:woozle.org:697,verify=0"|]
|
|
in
|
|
let iobuf_out = Iobuf.create dispatcher conn_out "collab_out"
|
|
discard_command
|
|
handle_error
|
|
in
|
|
let _ = Iobuf.create dispatcher conn_in "collab_in"
|
|
(handle_command bot iobuf_out)
|
|
handle_error
|
|
in
|
|
write iobuf_out "NICK" ["zinc"] None;
|
|
write iobuf_out "USER" ["zinc"; "zinc"; "zinc"] (Some "I'm a little printf, short and stdout");
|
|
Dispatch.run dispatcher
|
|
|
|
|
|
let _ =
|
|
main ()
|