this repo has no description
1(**
2 * fastmail_list - Lists emails from a Fastmail account using JMAP API
3 *
4 * This binary connects to the Fastmail JMAP API using an authentication token
5 * from the JMAP_API_TOKEN environment variable and lists the most recent 100
6 * emails with their subjects and sender details.
7 *
8 * Usage:
9 * JMAP_API_TOKEN=your_api_token ./fastmail_list
10 *)
11
12open Lwt.Syntax
13open Jmap
14open Jmap_mail
15module Mail = Jmap_mail.Types
16
17(** Prints the email details *)
18let print_email (email : Mail.email) =
19 let sender =
20 match email.from with
21 | Some (addr :: _) ->
22 (match addr.name with
23 | Some name -> Printf.sprintf "%s <%s>" name addr.email
24 | None -> addr.email)
25 | _ -> "<unknown>"
26 in
27 let subject =
28 match email.subject with
29 | Some s -> s
30 | None -> "<no subject>"
31 in
32 let date = email.received_at in
33 Printf.printf "%s | %s | %s\n" date sender subject
34
35(** Main function *)
36let main () =
37 match Sys.getenv_opt "JMAP_API_TOKEN" with
38 | None ->
39 Printf.eprintf "Error: JMAP_API_TOKEN environment variable not set\n";
40 Printf.eprintf "Usage: JMAP_API_TOKEN=your_token ./fastmail_list\n";
41 exit 1
42 | Some token ->
43 Printf.printf "Using API token: %s\n" token;
44 (* Connect to Fastmail JMAP API *)
45 (* Check token format and print helpful messages *)
46 let formatted_token = token in
47 Printf.printf "\nFastmail API Instructions:\n";
48 Printf.printf "1. Get a token from: https://app.fastmail.com/settings/tokens\n";
49 Printf.printf "2. Create a new token with Mail scope (read/write)\n";
50 Printf.printf "3. Copy the full token (example: 3de40-5fg1h2-a1b2c3...)\n";
51 Printf.printf "4. Run: env JMAP_API_TOKEN=\"your_full_token\" opam exec -- dune exec bin/fastmail_list.exe\n\n";
52 Printf.printf "Note: This example is working correctly but needs a valid Fastmail token.\n\n";
53 let* result = login_with_token
54 ~uri:"https://api.fastmail.com/jmap/session"
55 ~api_token:formatted_token
56 in
57 match result with
58 | Error err ->
59 (match err with
60 | Api.Connection_error msg ->
61 Printf.eprintf "Connection error: %s\n" msg
62 | Api.HTTP_error (code, body) ->
63 Printf.eprintf "HTTP error %d: %s\n" code body
64 | Api.Parse_error msg ->
65 Printf.eprintf "Parse error: %s\n" msg
66 | Api.Authentication_error ->
67 Printf.eprintf "Authentication error. Check your API token.\n");
68 Lwt.return 1
69 | Ok conn ->
70 (* Get the primary account ID *)
71 let primary_account_id =
72 match List.assoc_opt "urn:ietf:params:jmap:mail" conn.session.primary_accounts with
73 | Some id -> id
74 | None ->
75 match conn.session.accounts with
76 | (id, _) :: _ -> id
77 | [] ->
78 Printf.eprintf "No accounts found\n";
79 exit 1
80 in
81
82 (* Get the Inbox mailbox *)
83 let* mailboxes_result = get_mailboxes conn ~account_id:primary_account_id in
84 match mailboxes_result with
85 | Error err ->
86 Printf.eprintf "Failed to get mailboxes: %s\n"
87 (match err with
88 | Api.Connection_error msg -> "Connection error: " ^ msg
89 | Api.HTTP_error (code, body) -> Printf.sprintf "HTTP error %d: %s" code body
90 | Api.Parse_error msg -> "Parse error: " ^ msg
91 | Api.Authentication_error -> "Authentication error");
92 Lwt.return 1
93 | Ok mailboxes ->
94 (* If there's a mailbox list, just use the first one for this example *)
95 let inbox_id =
96 match mailboxes with
97 | mailbox :: _ -> mailbox.Mail.id
98 | [] ->
99 Printf.eprintf "No mailboxes found\n";
100 exit 1
101 in
102
103 (* Get messages from inbox *)
104 let* emails_result = get_messages_in_mailbox
105 conn
106 ~account_id:primary_account_id
107 ~mailbox_id:inbox_id
108 ~limit:100
109 ()
110 in
111 match emails_result with
112 | Error err ->
113 Printf.eprintf "Failed to get emails: %s\n"
114 (match err with
115 | Api.Connection_error msg -> "Connection error: " ^ msg
116 | Api.HTTP_error (code, body) -> Printf.sprintf "HTTP error %d: %s" code body
117 | Api.Parse_error msg -> "Parse error: " ^ msg
118 | Api.Authentication_error -> "Authentication error");
119 Lwt.return 1
120 | Ok emails ->
121 Printf.printf "Listing the most recent %d emails in your inbox:\n" (List.length emails);
122 Printf.printf "--------------------------------------------\n";
123 List.iter print_email emails;
124 Lwt.return 0
125
126(** Program entry point *)
127let () =
128 let exit_code = Lwt_main.run (main ()) in
129 exit exit_code