this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

more

+45 -102
+45 -102
jmap/bin/fastmail_connect.ml
··· 6 6 let fetch_recent_emails env ctx session = 7 7 try 8 8 let account_id = Jmap_unix.Session_utils.get_primary_mail_account session in 9 - printf "Using account: %s\n" account_id; 10 - printf "Building JMAP request using type-safe capabilities...\n"; 9 + printf "Using account: %s\nBuilding JMAP request using type-safe capabilities...\n" account_id; 11 10 12 - (* Build Email/query request using jmap-email builders *) 13 - let query_builder = Jmap_email.Jmap_email_query.query () 14 - |> Jmap_email.Jmap_email_query.with_account account_id 15 - |> Jmap_email.Jmap_email_query.order_by Jmap_email.Jmap_email_query.Sort.by_date_desc 16 - |> Jmap_email.Jmap_email_query.limit 5 in 11 + let query_json = 12 + Jmap_email.Jmap_email_query.(query () |> with_account account_id |> order_by Sort.by_date_desc |> limit 5 |> build_email_query) in 17 13 18 - (* Build Email/query JSON using jmap-email *) 19 - let query_json = Jmap_email.Jmap_email_query.build_email_query query_builder in 14 + let properties = [`Id; `ThreadId; `From; `Subject; `ReceivedAt; `Preview; `Keywords; `HasAttachment] in 15 + let get_json = 16 + Jmap_email.Jmap_email_query.(build_email_get_with_ref ~account_id ~properties:(properties_to_strings properties) 17 + ~result_of:"q1" ~method_name:"Email/query" ~path:"/ids") in 20 18 21 19 let builder = Jmap_unix.build ctx in 22 20 let builder = Jmap_unix.using builder [`Core; `Mail] in 23 21 let builder = Jmap_unix.add_method_call builder "Email/query" query_json "q1" in 24 - 25 - (* Add Email/get using jmap-email builders *) 26 - let properties = [`Id; `ThreadId; `From; `Subject; `ReceivedAt; `Preview; `Keywords; `HasAttachment] in 27 - let property_strings = Jmap_email.Jmap_email_query.properties_to_strings properties in 28 - let get_json = Jmap_email.Jmap_email_query.build_email_get_with_ref 29 - ~account_id 30 - ~properties:property_strings 31 - ~result_of:"q1" 32 - ~method_name:"Email/query" 33 - ~path:"/ids" in 34 22 let builder = Jmap_unix.add_method_call builder "Email/get" get_json "g1" in 35 23 36 - (* Execute the request *) 37 24 let+ response = Jmap_unix.execute env builder in 38 25 printf "✓ Got JMAP response\n"; 39 26 40 27 let+ query_response_json = Jmap_unix.Response.extract_method ~method_name:"Email/query" ~method_call_id:"q1" response in 41 28 let+ query_response = Jmap.Methods.Query_response.of_json query_response_json in 42 - let ids = Jmap.Methods.Query_response.ids query_response in 43 - printf "✓ Found %d emails\n\n" (List.length ids); 29 + printf "✓ Found %d emails\n\n" (Jmap.Methods.Query_response.ids query_response |> List.length); 44 30 45 31 let+ get_response_json = Jmap_unix.Response.extract_method ~method_name:"Email/get" ~method_call_id:"g1" response in 46 32 47 - (* Parse emails using jmap-email instead of manual JSON parsing *) 48 - let open Yojson.Safe.Util in 49 - let list_json = get_response_json |> member "list" in 50 - let emails_json = to_list list_json in 51 - let emails = List.map (fun email_json -> 52 - match Jmap_email.of_json email_json with 53 - | Ok email -> email 54 - | Error err -> failwith ("Email parse error: " ^ err) 55 - ) emails_json in 33 + let emails = 34 + Yojson.Safe.Util.(get_response_json |> member "list" |> to_list) 35 + |> List.map (fun email_json -> match Jmap_email.of_json email_json with 36 + | Ok email -> email | Error err -> failwith ("Email parse error: " ^ err)) in 37 + 38 + let print_sender email = 39 + Jmap_email.(match from email with 40 + | Some (sender :: _) -> 41 + Jmap_email.Email_address.(printf " From: %s\n" 42 + (match name sender with | Some n -> n ^ " <" ^ email sender ^ ">" | None -> email sender)) 43 + | _ -> printf " From: (Unknown)\n") in 44 + 45 + let print_preview email = 46 + Jmap_email.(match preview email with 47 + | Some p when String.length p > 0 -> 48 + let preview = if String.length p > 100 then String.sub p 0 97 ^ "..." else p in 49 + printf " Preview: %s\n" preview 50 + | _ -> ()) in 56 51 57 52 List.iteri (fun i email -> 58 - printf "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"; 59 - printf "Email #%d:\n" (i + 1); 60 - 61 - let subject = match Jmap_email.subject email with 62 - | Some s -> s 63 - | None -> "(No Subject)" 64 - in 65 - printf " Subject: %s\n" subject; 66 - 67 - (match Jmap_email.from email with 68 - | Some from_list when from_list <> [] -> 69 - let sender = List.hd from_list in 70 - let email_addr = Jmap_email.Email_address.email sender in 71 - (match Jmap_email.Email_address.name sender with 72 - | Some name -> printf " From: %s <%s>\n" name email_addr 73 - | None -> printf " From: %s\n" email_addr) 74 - | _ -> printf " From: (Unknown)\n"); 75 - 76 - (match Jmap_email.received_at email with 77 - | Some timestamp -> 78 - let date = Jmap.Date.of_timestamp timestamp in 79 - let date_str = Jmap.Date.to_rfc3339 date in 80 - printf " Date: %s\n" date_str 81 - | None -> printf " Date: (Unknown)\n"); 82 - 83 - (match Jmap_email.preview email with 84 - | Some preview when String.length preview > 0 -> 85 - let short_preview = if String.length preview > 100 86 - then (String.sub preview 0 97) ^ "..." 87 - else preview in 88 - printf " Preview: %s\n" short_preview 89 - | _ -> ()) 53 + printf "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nEmail #%d:\n" (i + 1); 54 + printf " Subject: %s\n" Jmap_email.(subject email |> Option.value ~default:"(No Subject)"); 55 + print_sender email; 56 + Jmap_email.(received_at email |> Option.iter (fun t -> 57 + printf " Date: %s\n" Jmap.Date.(of_timestamp t |> to_rfc3339))); 58 + print_preview email 90 59 ) emails; 91 60 printf "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"; 92 61 Ok () ··· 105 74 (* Test basic JMAP types first *) 106 75 printf "Testing core JMAP modules...\n"; 107 76 108 - let test_id = match Jmap.Id.of_string "test-id-123" with 109 - | Ok id -> 110 - Format.printf "✓ Jmap.Id creation: %a\n" Jmap.Id.pp id; 111 - true 112 - | Error e -> 113 - printf "✗ Jmap.Id creation failed: %s\n" e; 114 - false 115 - in 77 + let test_modules = [ 78 + ("Jmap.Id", Jmap.Id.(of_string "test-id-123" |> Result.map (Format.asprintf "%a" pp))); 79 + ("Jmap.Date", Ok (Jmap.Date.(Unix.time () |> of_timestamp |> to_timestamp |> Printf.sprintf "%.0f"))); 80 + ("Jmap.UInt", Jmap.UInt.(of_int 42 |> Result.map (Format.asprintf "%a" pp))); 81 + ] in 116 82 117 - let test_date = 118 - let now = Unix.time () in 119 - let date = Jmap.Date.of_timestamp now in 120 - printf "✓ Jmap.Date creation: %.0f\n" (Jmap.Date.to_timestamp date); 121 - true 122 - in 123 - 124 - let test_uint = match Jmap.UInt.of_int 42 with 125 - | Ok uint -> 126 - Format.printf "✓ Jmap.UInt creation: %a\n" Jmap.UInt.pp uint; 127 - true 128 - | Error e -> 129 - printf "✗ Jmap.UInt creation failed: %s\n" e; 130 - false 131 - in 83 + let test_results = List.map (fun (name, result) -> match result with 84 + | Ok value -> printf "✓ %s creation: %s\n" name value; true 85 + | Error e -> printf "✗ %s creation failed: %s\n" name e; false 86 + ) test_modules in 132 87 133 - if not (test_id && test_date && test_uint) then ( 88 + if not (List.for_all (fun x -> x) test_results) then ( 134 89 printf "\nCore module tests failed - aborting\n"; 135 90 exit 1 136 91 ); ··· 160 115 let session_url = Uri.of_string "https://api.fastmail.com/jmap/session" in 161 116 let auth_method = Jmap_unix.Bearer api_key in 162 117 163 - match Jmap_unix.connect env client 164 - ~session_url 165 - ~host:"api.fastmail.com" 166 - ~port:443 167 - ~use_tls:true 168 - ~auth_method 169 - () with 118 + match Jmap_unix.(connect env client ~session_url ~host:"api.fastmail.com" ~port:443 ~use_tls:true ~auth_method ()) with 170 119 | Ok (ctx, session) -> 171 120 printf "✓ Connected successfully\n\n"; 172 121 Jmap_unix.Session_utils.print_session_info session; 173 122 174 - (* Test email fetching *) 175 123 printf "\n📧 Fetching recent emails...\n"; 176 124 (match fetch_recent_emails env ctx session with 177 125 | Ok () -> printf "✓ Email fetch completed successfully\n" 178 - | Error error -> 179 - Format.printf "⚠ Email fetch failed: %a\n" 180 - Jmap.Protocol.Error.pp error); 126 + | Error error -> Format.printf "⚠ Email fetch failed: %a\n" Jmap.Protocol.Error.pp error); 181 127 182 - (* Close connection *) 183 128 printf "\nClosing connection...\n"; 184 129 (match Jmap_unix.close ctx with 185 130 | Ok () -> printf "✓ Connection closed successfully\n" 186 - | Error error -> 187 - Format.printf "⚠ Error closing connection: %a\n" 188 - Jmap.Protocol.Error.pp error); 131 + | Error error -> Format.printf "⚠ Error closing connection: %a\n" Jmap.Protocol.Error.pp error); 189 132 190 133 printf "\nOverall: ALL TESTS PASSED\n" 191 134