My agentic slop goes here. Not intended for anyone else!
at main 4.6 kB view raw
1(** Fastmail Example using high-level JMAP client API 2 3 This example demonstrates the new JMAP client API inspired by the Rust 4 jmap-client library. It shows how to connect to Fastmail and fetch recent 5 emails using the simplified high-level interface. 6 7 Key improvements over manual JSON construction: 8 - Single-line operations for common tasks 9 - Automatic result reference handling 10 - Built-in error handling and resource management 11 - Rich error context for debugging *) 12 13open Printf 14 15let (let*) = Result.bind 16 17let show_error = function 18 | `Network_error (kind, msg, retryable) -> 19 let retry_hint = if retryable then " (retryable)" else " (not retryable)" in 20 printf "Network Error%s: %s\n" retry_hint msg 21 | `Auth_error (kind, msg) -> 22 printf "Authentication Error: %s\n" msg 23 | `Parse_error (kind, context) -> 24 printf "Parse Error: %s\n" context 25 | error -> 26 printf "Error: %s\n" (Jmap.Error.Utils.context error) 27let main () = 28 (* Initialize crypto for TLS *) 29 Mirage_crypto_rng_unix.use_default (); 30 31 Eio_main.run @@ fun env -> 32 33 printf "JMAP Client Example - Fastmail\n"; 34 printf "===============================\n\n"; 35 36 (* Read API credentials *) 37 let api_key = 38 try 39 let ic = open_in ".api-key" in 40 let key = String.trim (input_line ic) in 41 close_in ic; key 42 with 43 | Sys_error _ -> failwith "Please create .api-key file with your Fastmail API token" 44 in 45 46 printf "Loaded API credentials\n"; 47 48 (* Connect to server using high-level client *) 49 let* client = Jmap_unix.Client.connect 50 ~credentials:(`Bearer api_key) 51 env "https://api.fastmail.com" in 52 53 printf "Connected to Fastmail JMAP server\n"; 54 printf "Account: %s\n\n" (Jmap_unix.Client.primary_account client); 55 56 (* Query recent emails with filtering *) 57 let* emails = Jmap_unix.Client.query_emails client 58 ~filter:(Jmap_email.Query.Filter.has_keyword "$draft" |> Jmap_email.Query.Filter.negate) 59 ~sort:[Jmap_email.Query.Sort.by_date_desc] 60 ~limit:5 61 ~properties:[`Id; `ThreadId; `From; `Subject; `ReceivedAt; `Preview; `Keywords] 62 () in 63 64 printf "Found %d recent emails:\n\n" (List.length emails); 65 66 (* Display emails *) 67 List.iteri (fun i email -> 68 printf "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"; 69 printf "Email #%d:\n" (i + 1); 70 printf " Subject: %s\n" (Jmap_email.Email.subject email |> Option.value ~default:"(No Subject)"); 71 72 (* Show sender *) 73 (match Jmap_email.Email.from email with 74 | Some (sender :: _) -> 75 let name = Jmap_email.Address.name sender |> Option.value ~default:"" in 76 let email_addr = Jmap_email.Address.email sender in 77 printf " From: %s <%s>\n" name email_addr 78 | _ -> printf " From: (Unknown)\n"); 79 80 (* Show received date *) 81 (match Jmap_email.Email.received_at email with 82 | Some timestamp -> 83 let date_str = Jmap.Types.Date.of_timestamp timestamp |> Jmap.Types.Date.to_rfc3339 in 84 printf " Date: %s\n" date_str 85 | None -> ()); 86 87 (* Show preview if available *) 88 (match Jmap_email.Email.preview email with 89 | Some preview when String.length preview > 0 -> 90 let preview_str = if String.length preview > 100 then 91 String.sub preview 0 97 ^ "..." else preview in 92 printf " Preview: %s\n" preview_str 93 | _ -> ()); 94 ) emails; 95 96 printf "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"; 97 98 (* Show connection statistics *) 99 let stats = Jmap_unix.Client.stats client in 100 printf "Connection Statistics:\n"; 101 printf " • Requests sent: %d (successful: %d, failed: %d)\n" 102 stats.requests_sent stats.requests_successful stats.requests_failed; 103 printf " • Data transferred: %Ld bytes sent, %Ld bytes received\n" 104 stats.bytes_sent stats.bytes_received; 105 printf " • Average response time: %.2f ms\n" (stats.average_response_time *. 1000.0); 106 107 (* Cleanup *) 108 Jmap_unix.Client.close client; 109 printf "Client closed and resources cleaned up\n"; 110 111 Ok () 112 113let () = 114 match main () with 115 | Ok () -> 116 printf "\nExample completed successfully\n"; 117 exit 0 118 | Error error -> 119 printf "\n"; 120 show_error error; 121 printf "\nCheck error details above for troubleshooting\n"; 122 exit 1