My agentic slop goes here. Not intended for anyone else!
1(* Test script to verify real-time bot event processing *) 2 3open Zulip_bot 4 5(* Logging setup *) 6let src = Logs.Src.create "test_realtime_bot" ~doc:"Test real-time bot" 7module Log = (val Logs.src_log src : Logs.LOG) 8 9(* Simple test bot that logs everything *) 10module Test_bot_handler : Bot_handler.S = struct 11 let initialize _config = 12 Log.info (fun m -> m "Bot initialized"); 13 Ok () 14 15 let usage () = "Test Bot - Verifies real-time event processing" 16 17 let description () = "A test bot that logs all messages received" 18 19 let handle_message ~config:_ ~storage ~identity:_ ~message ~env:_ = 20 Log.info (fun m -> m "Received message"); 21 22 (* Extract and log message details *) 23 let content = Bot_handler.Message_context.content message in 24 let sender = Bot_handler.Message_context.sender_email message in 25 let is_direct = Bot_handler.Message_context.is_direct message in 26 27 Log.info (fun m -> m "Content: %s" 28 (Option.value content ~default:"<none>")); 29 Log.info (fun m -> m "Sender: %s" 30 (Option.value sender ~default:"<unknown>")); 31 Log.info (fun m -> m "Direct: %b" is_direct); 32 33 (* Test storage *) 34 let test_key = "last_message" in 35 let test_value = Option.value content ~default:"" in 36 37 (match Bot_storage.put storage ~key:test_key ~value:test_value with 38 | Ok () -> Log.info (fun m -> m "Stored message in bot storage") 39 | Error e -> Log.err (fun m -> m "Storage error: %s" (Zulip.error_message e))); 40 41 (* Always reply with confirmation *) 42 let reply = Printf.sprintf "Test bot received: %s" 43 (Option.value content ~default:"<empty>") in 44 Ok (Bot_handler.Response.Reply reply) 45end 46 47let run_test verbosity env = 48 (* Setup logging *) 49 Logs.set_reporter (Logs_fmt.reporter ()); 50 Logs.set_level (Some (match verbosity with 51 | 0 -> Logs.Info 52 | 1 -> Logs.Debug 53 | _ -> Logs.Debug)); 54 55 Log.info (fun m -> m "Real-time Bot Test"); 56 Log.info (fun m -> m "=================="); 57 58 (* Load auth *) 59 let auth = match Zulip.Auth.from_zuliprc () with 60 | Ok a -> 61 Log.info (fun m -> m "Loaded auth for: %s" (Zulip.Auth.email a)); 62 Log.info (fun m -> m "Server: %s" (Zulip.Auth.server_url a)); 63 a 64 | Error e -> 65 Log.err (fun m -> m "Failed to load .zuliprc: %s" (Zulip.error_message e)); 66 exit 1 67 in 68 69 Eio.Switch.run @@ fun sw -> 70 let client = Zulip.Client.create ~sw env auth in 71 72 (* Create bot components *) 73 let config = Bot_config.create [] in 74 let bot_email = Zulip.Auth.email auth in 75 let storage = Bot_storage.create client ~bot_email in 76 let identity = Bot_handler.Identity.create 77 ~full_name:"Test Bot" 78 ~email:bot_email 79 ~mention_name:"testbot" 80 in 81 82 (* Create handler and runner *) 83 let handler = Bot_handler.create 84 (module Test_bot_handler) 85 ~config ~storage ~identity 86 in 87 let runner = Bot_runner.create ~env ~client ~handler in 88 89 Log.info (fun m -> m "Starting bot in real-time mode..."); 90 Log.info (fun m -> m "The bot will:"); 91 Log.info (fun m -> m "- Register for message events"); 92 Log.info (fun m -> m "- Poll for new messages"); 93 Log.info (fun m -> m "- Process and reply to messages"); 94 Log.info (fun m -> m "- Store messages in Zulip bot storage"); 95 Log.info (fun m -> m "Press Ctrl+C to stop."); 96 97 (* Run the bot *) 98 Bot_runner.run_realtime runner 99 100(* Command-line interface *) 101open Cmdliner 102 103let verbosity = 104 let doc = "Increase verbosity (can be used multiple times)" in 105 let verbosity_flags = Arg.(value & flag_all & info ["v"; "verbose"] ~doc) in 106 Term.(const List.length $ verbosity_flags) 107 108let main_cmd = 109 let doc = "Test real-time bot for Zulip" in 110 let man = [ 111 `S Manpage.s_description; 112 `P "This bot tests real-time event processing with the Zulip API. \ 113 It will echo received messages and store them in bot storage."; 114 `P "The bot requires a configured ~/.zuliprc file with API credentials."; 115 ] in 116 let info = Cmd.info "test_realtime_bot" ~version:"1.0.0" ~doc ~man in 117 let run verbosity = 118 Eio_main.run (run_test verbosity) 119 in 120 let term = Term.(const run $ verbosity) in 121 Cmd.v info term 122 123let () = exit (Cmd.eval main_cmd)