this repo has no description
at main 6.1 kB view raw
1(*--------------------------------------------------------------------------- 2 Copyright (c) 2025 Anil Madhavapeddy. All rights reserved. 3 SPDX-License-Identifier: ISC 4 ---------------------------------------------------------------------------*) 5 6(** JMAP test client - connects to a JMAP server and queries recent emails *) 7 8let () = 9 (* Parse command line arguments *) 10 let usage = "Usage: jmap-test <session-url> <api-key>" in 11 let args = ref [] in 12 Arg.parse [] (fun arg -> args := arg :: !args) usage; 13 let session_url, api_key = 14 match List.rev !args with 15 | [url; key] -> (url, key) 16 | _ -> 17 prerr_endline usage; 18 exit 1 19 in 20 21 (* Run with Eio *) 22 Eio_main.run @@ fun env -> 23 Eio.Switch.run @@ fun sw -> 24 25 (* Create HTTP client with Bearer token auth *) 26 let requests = Requests.create ~sw env in 27 let auth = Requests.Auth.bearer ~token:api_key in 28 29 Printf.printf "Connecting to %s...\n%!" session_url; 30 31 (* Create JMAP client from session URL *) 32 match Jmap_eio.Client.create_from_url ~auth requests session_url with 33 | Error e -> 34 Printf.eprintf "Failed to connect: %s\n" (Jmap_eio.Client.error_to_string e); 35 exit 1 36 | Ok client -> 37 let session = Jmap_eio.Client.session client in 38 Printf.printf "Connected! Username: %s\n%!" (Jmap_proto.Session.username session); 39 40 (* Get primary mail account *) 41 let primary_account_id = 42 match Jmap_proto.Session.primary_account_for Jmap_proto.Capability.mail session with 43 | Some id -> id 44 | None -> 45 prerr_endline "No primary mail account found"; 46 exit 1 47 in 48 Printf.printf "Primary mail account: %s\n%!" (Jmap_proto.Id.to_string primary_account_id); 49 50 (* Query for recent emails - get the 10 most recent *) 51 let sort = [Jmap_proto.Filter.comparator ~is_ascending:false "receivedAt"] in 52 let query_inv = Jmap_eio.Client.Build.email_query 53 ~call_id:"q1" 54 ~account_id:primary_account_id 55 ~sort 56 ~limit:10L 57 () 58 in 59 60 (* Build request with mail capability *) 61 let req = Jmap_eio.Client.Build.make_request 62 ~capabilities:[Jmap_proto.Capability.core; Jmap_proto.Capability.mail] 63 [query_inv] 64 in 65 66 Printf.printf "Querying recent emails...\n%!"; 67 68 match Jmap_eio.Client.request client req with 69 | Error e -> 70 Printf.eprintf "Query failed: %s\n" (Jmap_eio.Client.error_to_string e); 71 exit 1 72 | Ok response -> 73 (* Parse the query response *) 74 match Jmap_eio.Client.Parse.parse_email_query ~call_id:"q1" response with 75 | Error e -> 76 Printf.eprintf "Failed to parse query response: %s\n" (Jsont.Error.to_string e); 77 exit 1 78 | Ok query_result -> 79 let email_ids = query_result.ids in 80 Printf.printf "Found %d emails\n%!" (List.length email_ids); 81 82 if List.length email_ids = 0 then ( 83 Printf.printf "No emails found.\n%!"; 84 ) else ( 85 (* Fetch the email details *) 86 let get_inv = Jmap_eio.Client.Build.email_get 87 ~call_id:"g1" 88 ~account_id:primary_account_id 89 ~ids:email_ids 90 ~properties:["id"; "subject"; "from"; "receivedAt"; "preview"] 91 () 92 in 93 94 let req2 = Jmap_eio.Client.Build.make_request 95 ~capabilities:[Jmap_proto.Capability.core; Jmap_proto.Capability.mail] 96 [get_inv] 97 in 98 99 Printf.printf "Fetching email details...\n%!"; 100 101 match Jmap_eio.Client.request client req2 with 102 | Error e -> 103 Printf.eprintf "Get failed: %s\n" (Jmap_eio.Client.error_to_string e); 104 exit 1 105 | Ok response2 -> 106 match Jmap_eio.Client.Parse.parse_email_get ~call_id:"g1" response2 with 107 | Error e -> 108 Printf.eprintf "Failed to parse get response: %s\n" (Jsont.Error.to_string e); 109 exit 1 110 | Ok get_result -> 111 Printf.printf "\n=== Recent Emails ===\n\n%!"; 112 List.iter (fun email -> 113 let id = Jmap_proto.Id.to_string (Jmap_mail.Email.id email) in 114 let subject = Option.value (Jmap_mail.Email.subject email) ~default:"(no subject)" in 115 let from_addrs = Option.value (Jmap_mail.Email.from email) ~default:[] in 116 let from_str = match from_addrs with 117 | [] -> "(unknown sender)" 118 | addr :: _ -> 119 let name = Option.value (Jmap_mail.Email_address.name addr) ~default:"" in 120 let email_addr = Jmap_mail.Email_address.email addr in 121 if name = "" then email_addr 122 else Printf.sprintf "%s <%s>" name email_addr 123 in 124 let received = 125 Jmap_proto.Date.Utc.to_string (Jmap_mail.Email.received_at email) 126 in 127 let preview = Jmap_mail.Email.preview email in 128 let preview_short = 129 if String.length preview > 80 then 130 String.sub preview 0 77 ^ "..." 131 else preview 132 in 133 Printf.printf "ID: %s\n" id; 134 Printf.printf "From: %s\n" from_str; 135 Printf.printf "Date: %s\n" received; 136 Printf.printf "Subject: %s\n" subject; 137 Printf.printf "Preview: %s\n" preview_short; 138 Printf.printf "\n%!"; 139 ) get_result.list; 140 Printf.printf "=== End of emails ===\n%!" 141 )