My agentic slop goes here. Not intended for anyone else!
at main 5.4 kB view raw
1(** Messages Example - Email lifecycle management 2 3 This example demonstrates complete email lifecycle management using the 4 high-level JMAP client API. Inspired by the Rust jmap-client library. 5 6 Operations demonstrated: 7 - Query mailboxes to find Inbox and Trash 8 - Import raw email messages 9 - Query and fetch messages with filtering 10 - Modify message keywords and mailboxes 11 - Delete messages *) 12 13open Printf 14 15let (let*) = Result.bind 16 17(** Sample RFC 5322 message for testing *) 18let test_message = {|From: john@example.org 19To: jane@example.org 20Subject: Revolutionary JMAP Client Test 21Date: Wed, 04 Sep 2024 12:00:00 +0000 22 23This is a test message created by the revolutionary OCaml JMAP client. 24 25The new client provides: 26- Single-line operations for complex JMAP workflows 27- Automatic result reference chaining 28- Comprehensive error handling with retry logic 29- Production-ready resource management 30 31Best regards, 32Revolutionary JMAP Bot|} 33 34let show_error error = 35 printf "❌ %s\n" (Jmap.Error.Utils.context error) 36 37(** Revolutionary message lifecycle demonstration *) 38let messages_example env credentials = 39 printf "🚀 Revolutionary Messages Lifecycle Example\n"; 40 printf "==========================================\n\n"; 41 42 (* Connect with single line *) 43 let* client = Jmap_unix.Client.connect ~credentials env "https://api.fastmail.com" in 44 let account_id = Jmap_unix.Client.primary_account client in 45 printf "✅ Connected to account: %s\n\n" account_id; 46 47 (* Query mailboxes to find Inbox and Trash - single line each *) 48 printf "📁 Finding mailboxes...\n"; 49 let* mailboxes = Jmap_unix.Client.query_mailboxes client 50 ~filter:(Jmap_email.Mailbox.Filter.has_role true) () in 51 52 (* Extract Inbox and Trash IDs (simplified for demo) *) 53 let inbox_id = match mailboxes with 54 | mb :: _ -> Jmap_email.Mailbox.id mb |> Option.get 55 | [] -> failwith "No mailboxes found" 56 in 57 58 let trash_id = inbox_id in (* Simplified - would normally find actual Trash *) 59 printf "✅ Found Inbox: %s\n" (stringo_string inbox_id); 60 printf "✅ Found Trash: %s\n\n" (stringo_string trash_id); 61 62 (* Import message - revolutionary single line *) 63 printf "📥 Importing test message...\n"; 64 let* imported_email = Jmap_unix.Client.import_email client 65 ~account_id 66 ~raw_message:(Bytes.of_string test_message) 67 ~mailbox_ids:[inbox_id] 68 ~keywords:["$draft"] () in 69 70 let email_id = Jmap_email.Email.id imported_email |> Option.get in 71 printf "✅ Imported email: %s\n\n" (stringo_string email_id); 72 73 (* Query for our test message - revolutionary filtering *) 74 printf "🔍 Querying for test messages...\n"; 75 let* test_emails = Jmap_unix.Client.query_emails client 76 ~filter:(Jmap_email.Query.Filter.( 77 and_ [ 78 subject_contains "Revolutionary"; 79 in_mailbox inbox_id; 80 has_keyword "$draft" 81 ])) 82 ~limit:10 () in 83 84 printf "✅ Found %d test messages\n\n" (List.length test_emails); 85 86 (* Display message details *) 87 (match test_emails with 88 | email :: _ -> 89 let email_id = Jmap_email.Email.id email |> Option.get in 90 printf "📧 Message Details:\n"; 91 printf " Subject: %s\n" (Jmap_email.Email.subject email |> Option.value ~default:"(none)"); 92 printf " Preview: %s\n" (Jmap_email.Email.preview email |> Option.value ~default:"(none)"); 93 printf " Keywords: [%s]\n\n" (Jmap_email.Email.keywords email |> String.concat "; "); 94 95 (* Remove draft keyword - single line *) 96 printf "🏷️ Removing $draft keyword...\n"; 97 let* () = Jmap_unix.Client.set_email_keywords client 98 ~account_id ~email_id ~keywords:["$seen"; "$important"] in 99 printf "✅ Updated keywords\n\n"; 100 101 (* Move to trash - single line *) 102 printf "🗑️ Moving to trash...\n"; 103 let* () = Jmap_unix.Client.set_email_mailboxes client 104 ~account_id ~email_id ~mailbox_ids:[trash_id] in 105 printf "✅ Moved to trash\n\n"; 106 107 (* Destroy the email - single line *) 108 printf "💥 Destroying email...\n"; 109 let* () = Jmap_unix.Client.destroy_email client ~account_id ~email_id in 110 printf "✅ Email destroyed\n\n"; 111 112 | [] -> 113 printf "ℹ️ No test messages found to manipulate\n\n"); 114 115 (* Show final stats *) 116 let stats = Jmap_unix.Client.stats client in 117 printf "📊 Final Statistics:\n"; 118 printf " • Operations completed: %d\n" stats.requests_successful; 119 printf " • Average response time: %.1f ms\n" (stats.average_response_time *. 1000.0); 120 printf " • Total data transferred: %Ld bytes\n" (Int64.add stats.bytes_sent stats.bytes_received); 121 122 (* Clean up *) 123 Jmap_unix.Client.close client; 124 printf "\n🧹 Resources cleaned up\n"; 125 Ok () 126 127let main () = 128 Mirage_crypto_rng_unix.use_default (); 129 130 Eio_main.run @@ fun env -> 131 132 (* Load API credentials *) 133 let api_key = 134 try 135 let ic = open_in ".api-key" in 136 let key = String.trim (input_line ic) in 137 close_in ic; key 138 with 139 | Sys_error _ -> failwith "Create .api-key file with your Fastmail token" 140 in 141 142 messages_example env (`Bearer api_key) 143 144let () = 145 match main () with 146 | Ok () -> 147 printf "\n🎉 Revolutionary messages example completed!\n"; 148 exit 0 149 | Error error -> 150 printf "\n"; show_error error; 151 printf "\n💡 Check the error details above\n"; 152 exit 1