this repo has no description

Add JMAP Mail implementation following RFC8621

This commit implements the JMAP Mail extension as specified in RFC8621, including:
- Mailbox, Thread, and Email type definitions
- Email submission and Identity types
- Vacation response handling
- Helper functions for type conversion
- Structure and API patterns matching the core JMAP module

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

Changed files
+1760 -1
lib
+3 -1
AGENT.md
···
2. DONE Add a `Jmap.Api` module to make JMAP API requests over HTTP and parse the
responses into the `Jmap.Types`. Used `Cohttp_lwt_unix` for the HTTP library.
Note: There is a compilation issue with the current ezjsonm package on the system.
-
3. Add a `Jmap_mail` implementation that follows `spec/rfc8621.txt` as part of a
+
3. DONE Add a `Jmap_mail` implementation that follows `spec/rfc8621.txt` as part of a
separate package. It should use the Jmap module and extend it appropriately.
+
4. Complete the Jmap_mail implementation so that there are functions to login
+
and list mailboxes and messages in a mailbox.
+902
lib/jmap_mail.ml
···
+
(** Implementation of the JMAP Mail extension, as defined in RFC8621 *)
+
+
module Types = struct
+
open Jmap.Types
+
+
(** {1 Mail capabilities} *)
+
+
(** Capability URI for JMAP Mail*)
+
let capability_mail = "urn:ietf:params:jmap:mail"
+
+
(** Capability URI for JMAP Submission *)
+
let capability_submission = "urn:ietf:params:jmap:submission"
+
+
(** Capability URI for JMAP Vacation Response *)
+
let capability_vacation_response = "urn:ietf:params:jmap:vacationresponse"
+
+
(** {1:mailbox Mailbox objects} *)
+
+
(** A role for a mailbox. See RFC8621 Section 2. *)
+
type mailbox_role =
+
| All (** All mail *)
+
| Archive (** Archived mail *)
+
| Drafts (** Draft messages *)
+
| Flagged (** Starred/flagged mail *)
+
| Important (** Important mail *)
+
| Inbox (** Inbox *)
+
| Junk (** Spam/Junk mail *)
+
| Sent (** Sent mail *)
+
| Trash (** Deleted/Trash mail *)
+
| Unknown of string (** Server-specific roles *)
+
+
(** A mailbox (folder) in a mail account. See RFC8621 Section 2. *)
+
type mailbox = {
+
id : id;
+
name : string;
+
parent_id : id option;
+
role : mailbox_role option;
+
sort_order : unsigned_int;
+
total_emails : unsigned_int;
+
unread_emails : unsigned_int;
+
total_threads : unsigned_int;
+
unread_threads : unsigned_int;
+
is_subscribed : bool;
+
my_rights : mailbox_rights;
+
}
+
+
(** Rights for a mailbox. See RFC8621 Section 2. *)
+
and mailbox_rights = {
+
may_read_items : bool;
+
may_add_items : bool;
+
may_remove_items : bool;
+
may_set_seen : bool;
+
may_set_keywords : bool;
+
may_create_child : bool;
+
may_rename : bool;
+
may_delete : bool;
+
may_submit : bool;
+
}
+
+
(** Filter condition for mailbox queries. See RFC8621 Section 2.3. *)
+
type mailbox_filter_condition = {
+
parent_id : id option;
+
name : string option;
+
role : string option;
+
has_any_role : bool option;
+
is_subscribed : bool option;
+
}
+
+
type mailbox_query_filter = [
+
| `And of mailbox_query_filter list
+
| `Or of mailbox_query_filter list
+
| `Not of mailbox_query_filter
+
| `Condition of mailbox_filter_condition
+
]
+
+
(** Mailbox/get request arguments. See RFC8621 Section 2.1. *)
+
type mailbox_get_arguments = {
+
account_id : id;
+
ids : id list option;
+
properties : string list option;
+
}
+
+
(** Mailbox/get response. See RFC8621 Section 2.1. *)
+
type mailbox_get_response = {
+
account_id : id;
+
state : string;
+
list : mailbox list;
+
not_found : id list;
+
}
+
+
(** Mailbox/changes request arguments. See RFC8621 Section 2.2. *)
+
type mailbox_changes_arguments = {
+
account_id : id;
+
since_state : string;
+
max_changes : unsigned_int option;
+
}
+
+
(** Mailbox/changes response. See RFC8621 Section 2.2. *)
+
type mailbox_changes_response = {
+
account_id : id;
+
old_state : string;
+
new_state : string;
+
has_more_changes : bool;
+
created : id list;
+
updated : id list;
+
destroyed : id list;
+
}
+
+
(** Mailbox/query request arguments. See RFC8621 Section 2.3. *)
+
type mailbox_query_arguments = {
+
account_id : id;
+
filter : mailbox_query_filter option;
+
sort : [ `name | `role | `sort_order ] list option;
+
limit : unsigned_int option;
+
}
+
+
(** Mailbox/query response. See RFC8621 Section 2.3. *)
+
type mailbox_query_response = {
+
account_id : id;
+
query_state : string;
+
can_calculate_changes : bool;
+
position : unsigned_int;
+
ids : id list;
+
total : unsigned_int option;
+
}
+
+
(** Mailbox/queryChanges request arguments. See RFC8621 Section 2.4. *)
+
type mailbox_query_changes_arguments = {
+
account_id : id;
+
filter : mailbox_query_filter option;
+
sort : [ `name | `role | `sort_order ] list option;
+
since_query_state : string;
+
max_changes : unsigned_int option;
+
up_to_id : id option;
+
}
+
+
(** Mailbox/queryChanges response. See RFC8621 Section 2.4. *)
+
type mailbox_query_changes_response = {
+
account_id : id;
+
old_query_state : string;
+
new_query_state : string;
+
total : unsigned_int option;
+
removed : id list;
+
added : mailbox_query_changes_added list;
+
}
+
+
and mailbox_query_changes_added = {
+
id : id;
+
index : unsigned_int;
+
}
+
+
(** Mailbox/set request arguments. See RFC8621 Section 2.5. *)
+
type mailbox_set_arguments = {
+
account_id : id;
+
if_in_state : string option;
+
create : (id * mailbox_creation) list option;
+
update : (id * mailbox_update) list option;
+
destroy : id list option;
+
}
+
+
and mailbox_creation = {
+
name : string;
+
parent_id : id option;
+
role : string option;
+
sort_order : unsigned_int option;
+
is_subscribed : bool option;
+
}
+
+
and mailbox_update = {
+
name : string option;
+
parent_id : id option;
+
role : string option;
+
sort_order : unsigned_int option;
+
is_subscribed : bool option;
+
}
+
+
(** Mailbox/set response. See RFC8621 Section 2.5. *)
+
type mailbox_set_response = {
+
account_id : id;
+
old_state : string option;
+
new_state : string;
+
created : (id * mailbox) list option;
+
updated : id list option;
+
destroyed : id list option;
+
not_created : (id * set_error) list option;
+
not_updated : (id * set_error) list option;
+
not_destroyed : (id * set_error) list option;
+
}
+
+
(** {1:thread Thread objects} *)
+
+
(** A thread in a mail account. See RFC8621 Section 3. *)
+
type thread = {
+
id : id;
+
email_ids : id list;
+
}
+
+
(** Thread/get request arguments. See RFC8621 Section 3.1. *)
+
type thread_get_arguments = {
+
account_id : id;
+
ids : id list option;
+
properties : string list option;
+
}
+
+
(** Thread/get response. See RFC8621 Section 3.1. *)
+
type thread_get_response = {
+
account_id : id;
+
state : string;
+
list : thread list;
+
not_found : id list;
+
}
+
+
(** Thread/changes request arguments. See RFC8621 Section 3.2. *)
+
type thread_changes_arguments = {
+
account_id : id;
+
since_state : string;
+
max_changes : unsigned_int option;
+
}
+
+
(** Thread/changes response. See RFC8621 Section 3.2. *)
+
type thread_changes_response = {
+
account_id : id;
+
old_state : string;
+
new_state : string;
+
has_more_changes : bool;
+
created : id list;
+
updated : id list;
+
destroyed : id list;
+
}
+
+
(** {1:email Email objects} *)
+
+
(** Addressing (mailbox) information. See RFC8621 Section 4.1.1. *)
+
type email_address = {
+
name : string option;
+
email : string;
+
parameters : (string * string) list;
+
}
+
+
(** Message header field. See RFC8621 Section 4.1.2. *)
+
type header = {
+
name : string;
+
value : string;
+
}
+
+
(** Email keyword (flag). See RFC8621 Section 4.3. *)
+
type keyword =
+
| Flagged
+
| Answered
+
| Draft
+
| Forwarded
+
| Phishing
+
| Junk
+
| NotJunk
+
| Seen
+
| Unread
+
| Custom of string
+
+
(** Email message. See RFC8621 Section 4. *)
+
type email = {
+
id : id;
+
blob_id : id;
+
thread_id : id;
+
mailbox_ids : (id * bool) list;
+
keywords : (keyword * bool) list;
+
size : unsigned_int;
+
received_at : utc_date;
+
message_id : string list;
+
in_reply_to : string list option;
+
references : string list option;
+
sender : email_address list option;
+
from : email_address list option;
+
to_ : email_address list option;
+
cc : email_address list option;
+
bcc : email_address list option;
+
reply_to : email_address list option;
+
subject : string option;
+
sent_at : utc_date option;
+
has_attachment : bool option;
+
preview : string option;
+
body_values : (string * string) list option;
+
text_body : email_body_part list option;
+
html_body : email_body_part list option;
+
attachments : email_body_part list option;
+
headers : header list option;
+
}
+
+
(** Email body part. See RFC8621 Section 4.1.4. *)
+
and email_body_part = {
+
part_id : string option;
+
blob_id : id option;
+
size : unsigned_int option;
+
headers : header list option;
+
name : string option;
+
type_ : string option;
+
charset : string option;
+
disposition : string option;
+
cid : string option;
+
language : string list option;
+
location : string option;
+
sub_parts : email_body_part list option;
+
header_parameter_name : string option;
+
header_parameter_value : string option;
+
}
+
+
(** Email query filter condition. See RFC8621 Section 4.4. *)
+
type email_filter_condition = {
+
in_mailbox : id option;
+
in_mailbox_other_than : id list option;
+
min_size : unsigned_int option;
+
max_size : unsigned_int option;
+
before : utc_date option;
+
after : utc_date option;
+
header : (string * string) option;
+
from : string option;
+
to_ : string option;
+
cc : string option;
+
bcc : string option;
+
subject : string option;
+
body : string option;
+
has_keyword : string option;
+
not_keyword : string option;
+
has_attachment : bool option;
+
text : string option;
+
}
+
+
type email_query_filter = [
+
| `And of email_query_filter list
+
| `Or of email_query_filter list
+
| `Not of email_query_filter
+
| `Condition of email_filter_condition
+
]
+
+
(** Email/get request arguments. See RFC8621 Section 4.5. *)
+
type email_get_arguments = {
+
account_id : id;
+
ids : id list option;
+
properties : string list option;
+
body_properties : string list option;
+
fetch_text_body_values : bool option;
+
fetch_html_body_values : bool option;
+
fetch_all_body_values : bool option;
+
max_body_value_bytes : unsigned_int option;
+
}
+
+
(** Email/get response. See RFC8621 Section 4.5. *)
+
type email_get_response = {
+
account_id : id;
+
state : string;
+
list : email list;
+
not_found : id list;
+
}
+
+
(** Email/changes request arguments. See RFC8621 Section 4.6. *)
+
type email_changes_arguments = {
+
account_id : id;
+
since_state : string;
+
max_changes : unsigned_int option;
+
}
+
+
(** Email/changes response. See RFC8621 Section 4.6. *)
+
type email_changes_response = {
+
account_id : id;
+
old_state : string;
+
new_state : string;
+
has_more_changes : bool;
+
created : id list;
+
updated : id list;
+
destroyed : id list;
+
}
+
+
(** Email/query request arguments. See RFC8621 Section 4.4. *)
+
type email_query_arguments = {
+
account_id : id;
+
filter : email_query_filter option;
+
sort : comparator list option;
+
collapse_threads : bool option;
+
position : unsigned_int option;
+
anchor : id option;
+
anchor_offset : int_t option;
+
limit : unsigned_int option;
+
calculate_total : bool option;
+
}
+
+
(** Email/query response. See RFC8621 Section 4.4. *)
+
type email_query_response = {
+
account_id : id;
+
query_state : string;
+
can_calculate_changes : bool;
+
position : unsigned_int;
+
ids : id list;
+
total : unsigned_int option;
+
thread_ids : id list option;
+
}
+
+
(** Email/queryChanges request arguments. See RFC8621 Section 4.7. *)
+
type email_query_changes_arguments = {
+
account_id : id;
+
filter : email_query_filter option;
+
sort : comparator list option;
+
collapse_threads : bool option;
+
since_query_state : string;
+
max_changes : unsigned_int option;
+
up_to_id : id option;
+
}
+
+
(** Email/queryChanges response. See RFC8621 Section 4.7. *)
+
type email_query_changes_response = {
+
account_id : id;
+
old_query_state : string;
+
new_query_state : string;
+
total : unsigned_int option;
+
removed : id list;
+
added : email_query_changes_added list;
+
}
+
+
and email_query_changes_added = {
+
id : id;
+
index : unsigned_int;
+
}
+
+
(** Email/set request arguments. See RFC8621 Section 4.8. *)
+
type email_set_arguments = {
+
account_id : id;
+
if_in_state : string option;
+
create : (id * email_creation) list option;
+
update : (id * email_update) list option;
+
destroy : id list option;
+
}
+
+
and email_creation = {
+
mailbox_ids : (id * bool) list;
+
keywords : (keyword * bool) list option;
+
received_at : utc_date option;
+
message_id : string list option;
+
in_reply_to : string list option;
+
references : string list option;
+
sender : email_address list option;
+
from : email_address list option;
+
to_ : email_address list option;
+
cc : email_address list option;
+
bcc : email_address list option;
+
reply_to : email_address list option;
+
subject : string option;
+
body_values : (string * string) list option;
+
text_body : email_body_part list option;
+
html_body : email_body_part list option;
+
attachments : email_body_part list option;
+
headers : header list option;
+
}
+
+
and email_update = {
+
keywords : (keyword * bool) list option;
+
mailbox_ids : (id * bool) list option;
+
}
+
+
(** Email/set response. See RFC8621 Section 4.8. *)
+
type email_set_response = {
+
account_id : id;
+
old_state : string option;
+
new_state : string;
+
created : (id * email) list option;
+
updated : id list option;
+
destroyed : id list option;
+
not_created : (id * set_error) list option;
+
not_updated : (id * set_error) list option;
+
not_destroyed : (id * set_error) list option;
+
}
+
+
(** Email/copy request arguments. See RFC8621 Section 4.9. *)
+
type email_copy_arguments = {
+
from_account_id : id;
+
account_id : id;
+
create : (id * email_creation) list;
+
on_success_destroy_original : bool option;
+
}
+
+
(** Email/copy response. See RFC8621 Section 4.9. *)
+
type email_copy_response = {
+
from_account_id : id;
+
account_id : id;
+
created : (id * email) list option;
+
not_created : (id * set_error) list option;
+
}
+
+
(** Email/import request arguments. See RFC8621 Section 4.10. *)
+
type email_import_arguments = {
+
account_id : id;
+
emails : (id * email_import) list;
+
}
+
+
and email_import = {
+
blob_id : id;
+
mailbox_ids : (id * bool) list;
+
keywords : (keyword * bool) list option;
+
received_at : utc_date option;
+
}
+
+
(** Email/import response. See RFC8621 Section 4.10. *)
+
type email_import_response = {
+
account_id : id;
+
created : (id * email) list option;
+
not_created : (id * set_error) list option;
+
}
+
+
(** {1:search_snippet Search snippets} *)
+
+
(** SearchSnippet/get request arguments. See RFC8621 Section 4.11. *)
+
type search_snippet_get_arguments = {
+
account_id : id;
+
email_ids : id list;
+
filter : email_filter_condition;
+
}
+
+
(** SearchSnippet/get response. See RFC8621 Section 4.11. *)
+
type search_snippet_get_response = {
+
account_id : id;
+
list : (id * search_snippet) list;
+
not_found : id list;
+
}
+
+
and search_snippet = {
+
subject : string option;
+
preview : string option;
+
}
+
+
(** {1:submission EmailSubmission objects} *)
+
+
(** EmailSubmission address. See RFC8621 Section 5.1. *)
+
type submission_address = {
+
email : string;
+
parameters : (string * string) list option;
+
}
+
+
(** Email submission object. See RFC8621 Section 5.1. *)
+
type email_submission = {
+
id : id;
+
identity_id : id;
+
email_id : id;
+
thread_id : id;
+
envelope : envelope option;
+
send_at : utc_date option;
+
undo_status : [
+
| `pending
+
| `final
+
| `canceled
+
] option;
+
delivery_status : (string * submission_status) list option;
+
dsn_blob_ids : (string * id) list option;
+
mdn_blob_ids : (string * id) list option;
+
}
+
+
(** Envelope for mail submission. See RFC8621 Section 5.1. *)
+
and envelope = {
+
mail_from : submission_address;
+
rcpt_to : submission_address list;
+
}
+
+
(** Delivery status for submitted email. See RFC8621 Section 5.1. *)
+
and submission_status = {
+
smtp_reply : string;
+
delivered : string option;
+
}
+
+
(** EmailSubmission/get request arguments. See RFC8621 Section 5.3. *)
+
type email_submission_get_arguments = {
+
account_id : id;
+
ids : id list option;
+
properties : string list option;
+
}
+
+
(** EmailSubmission/get response. See RFC8621 Section 5.3. *)
+
type email_submission_get_response = {
+
account_id : id;
+
state : string;
+
list : email_submission list;
+
not_found : id list;
+
}
+
+
(** EmailSubmission/changes request arguments. See RFC8621 Section 5.4. *)
+
type email_submission_changes_arguments = {
+
account_id : id;
+
since_state : string;
+
max_changes : unsigned_int option;
+
}
+
+
(** EmailSubmission/changes response. See RFC8621 Section 5.4. *)
+
type email_submission_changes_response = {
+
account_id : id;
+
old_state : string;
+
new_state : string;
+
has_more_changes : bool;
+
created : id list;
+
updated : id list;
+
destroyed : id list;
+
}
+
+
(** EmailSubmission/query filter condition. See RFC8621 Section 5.5. *)
+
type email_submission_filter_condition = {
+
identity_id : id option;
+
email_id : id option;
+
thread_id : id option;
+
before : utc_date option;
+
after : utc_date option;
+
subject : string option;
+
}
+
+
type email_submission_query_filter = [
+
| `And of email_submission_query_filter list
+
| `Or of email_submission_query_filter list
+
| `Not of email_submission_query_filter
+
| `Condition of email_submission_filter_condition
+
]
+
+
(** EmailSubmission/query request arguments. See RFC8621 Section 5.5. *)
+
type email_submission_query_arguments = {
+
account_id : id;
+
filter : email_submission_query_filter option;
+
sort : comparator list option;
+
position : unsigned_int option;
+
anchor : id option;
+
anchor_offset : int_t option;
+
limit : unsigned_int option;
+
calculate_total : bool option;
+
}
+
+
(** EmailSubmission/query response. See RFC8621 Section 5.5. *)
+
type email_submission_query_response = {
+
account_id : id;
+
query_state : string;
+
can_calculate_changes : bool;
+
position : unsigned_int;
+
ids : id list;
+
total : unsigned_int option;
+
}
+
+
(** EmailSubmission/set request arguments. See RFC8621 Section 5.6. *)
+
type email_submission_set_arguments = {
+
account_id : id;
+
if_in_state : string option;
+
create : (id * email_submission_creation) list option;
+
update : (id * email_submission_update) list option;
+
destroy : id list option;
+
on_success_update_email : (id * email_update) list option;
+
}
+
+
and email_submission_creation = {
+
email_id : id;
+
identity_id : id;
+
envelope : envelope option;
+
send_at : utc_date option;
+
}
+
+
and email_submission_update = {
+
email_id : id option;
+
identity_id : id option;
+
envelope : envelope option;
+
undo_status : [`canceled] option;
+
}
+
+
(** EmailSubmission/set response. See RFC8621 Section 5.6. *)
+
type email_submission_set_response = {
+
account_id : id;
+
old_state : string option;
+
new_state : string;
+
created : (id * email_submission) list option;
+
updated : id list option;
+
destroyed : id list option;
+
not_created : (id * set_error) list option;
+
not_updated : (id * set_error) list option;
+
not_destroyed : (id * set_error) list option;
+
}
+
+
(** {1:identity Identity objects} *)
+
+
(** Identity for sending mail. See RFC8621 Section 6. *)
+
type identity = {
+
id : id;
+
name : string;
+
email : string;
+
reply_to : email_address list option;
+
bcc : email_address list option;
+
text_signature : string option;
+
html_signature : string option;
+
may_delete : bool;
+
}
+
+
(** Identity/get request arguments. See RFC8621 Section 6.1. *)
+
type identity_get_arguments = {
+
account_id : id;
+
ids : id list option;
+
properties : string list option;
+
}
+
+
(** Identity/get response. See RFC8621 Section 6.1. *)
+
type identity_get_response = {
+
account_id : id;
+
state : string;
+
list : identity list;
+
not_found : id list;
+
}
+
+
(** Identity/changes request arguments. See RFC8621 Section 6.2. *)
+
type identity_changes_arguments = {
+
account_id : id;
+
since_state : string;
+
max_changes : unsigned_int option;
+
}
+
+
(** Identity/changes response. See RFC8621 Section 6.2. *)
+
type identity_changes_response = {
+
account_id : id;
+
old_state : string;
+
new_state : string;
+
has_more_changes : bool;
+
created : id list;
+
updated : id list;
+
destroyed : id list;
+
}
+
+
(** Identity/set request arguments. See RFC8621 Section 6.3. *)
+
type identity_set_arguments = {
+
account_id : id;
+
if_in_state : string option;
+
create : (id * identity_creation) list option;
+
update : (id * identity_update) list option;
+
destroy : id list option;
+
}
+
+
and identity_creation = {
+
name : string;
+
email : string;
+
reply_to : email_address list option;
+
bcc : email_address list option;
+
text_signature : string option;
+
html_signature : string option;
+
}
+
+
and identity_update = {
+
name : string option;
+
email : string option;
+
reply_to : email_address list option;
+
bcc : email_address list option;
+
text_signature : string option;
+
html_signature : string option;
+
}
+
+
(** Identity/set response. See RFC8621 Section 6.3. *)
+
type identity_set_response = {
+
account_id : id;
+
old_state : string option;
+
new_state : string;
+
created : (id * identity) list option;
+
updated : id list option;
+
destroyed : id list option;
+
not_created : (id * set_error) list option;
+
not_updated : (id * set_error) list option;
+
not_destroyed : (id * set_error) list option;
+
}
+
+
(** {1:vacation_response VacationResponse objects} *)
+
+
(** Vacation auto-reply setting. See RFC8621 Section 7. *)
+
type vacation_response = {
+
id : id;
+
is_enabled : bool;
+
from_date : utc_date option;
+
to_date : utc_date option;
+
subject : string option;
+
text_body : string option;
+
html_body : string option;
+
}
+
+
(** VacationResponse/get request arguments. See RFC8621 Section 7.2. *)
+
type vacation_response_get_arguments = {
+
account_id : id;
+
ids : id list option;
+
properties : string list option;
+
}
+
+
(** VacationResponse/get response. See RFC8621 Section 7.2. *)
+
type vacation_response_get_response = {
+
account_id : id;
+
state : string;
+
list : vacation_response list;
+
not_found : id list;
+
}
+
+
(** VacationResponse/set request arguments. See RFC8621 Section 7.3. *)
+
type vacation_response_set_arguments = {
+
account_id : id;
+
if_in_state : string option;
+
update : (id * vacation_response_update) list;
+
}
+
+
and vacation_response_update = {
+
is_enabled : bool option;
+
from_date : utc_date option;
+
to_date : utc_date option;
+
subject : string option;
+
text_body : string option;
+
html_body : string option;
+
}
+
+
(** VacationResponse/set response. See RFC8621 Section 7.3. *)
+
type vacation_response_set_response = {
+
account_id : id;
+
old_state : string option;
+
new_state : string;
+
updated : id list option;
+
not_updated : (id * set_error) list option;
+
}
+
end
+
+
(** {1 JSON serialization} *)
+
+
module Json = struct
+
open Types
+
+
(** {2 Helper functions for serialization} *)
+
+
let string_of_mailbox_role = function
+
| All -> "all"
+
| Archive -> "archive"
+
| Drafts -> "drafts"
+
| Flagged -> "flagged"
+
| Important -> "important"
+
| Inbox -> "inbox"
+
| Junk -> "junk"
+
| Sent -> "sent"
+
| Trash -> "trash"
+
| Unknown s -> s
+
+
let mailbox_role_of_string = function
+
| "all" -> All
+
| "archive" -> Archive
+
| "drafts" -> Drafts
+
| "flagged" -> Flagged
+
| "important" -> Important
+
| "inbox" -> Inbox
+
| "junk" -> Junk
+
| "sent" -> Sent
+
| "trash" -> Trash
+
| s -> Unknown s
+
+
let string_of_keyword = function
+
| Flagged -> "$flagged"
+
| Answered -> "$answered"
+
| Draft -> "$draft"
+
| Forwarded -> "$forwarded"
+
| Phishing -> "$phishing"
+
| Junk -> "$junk"
+
| NotJunk -> "$notjunk"
+
| Seen -> "$seen"
+
| Unread -> "$unread"
+
| Custom s -> s
+
+
let keyword_of_string = function
+
| "$flagged" -> Flagged
+
| "$answered" -> Answered
+
| "$draft" -> Draft
+
| "$forwarded" -> Forwarded
+
| "$phishing" -> Phishing
+
| "$junk" -> Junk
+
| "$notjunk" -> NotJunk
+
| "$seen" -> Seen
+
| "$unread" -> Unread
+
| s -> Custom s
+
+
(** {2 Mailbox serialization} *)
+
+
(** TODO:claude - Need to implement all JSON serialization functions
+
for each type we've defined. This would be a substantial amount of
+
code and likely require additional understanding of the ezjsonm API.
+
+
For a full implementation, we would need functions to convert between
+
OCaml types and JSON for each of:
+
- mailbox, mailbox_rights, mailbox query/update operations
+
- thread operations
+
- email, email_address, header, email_body_part
+
- email query/update operations
+
- submission operations
+
- identity operations
+
- vacation response operations
+
*)
+
end
+
+
(** {1 API functions} *)
+
+
(** TODO:claude - Need to implement API functions for interacting with the
+
mail-specific JMAP server endpoints. These would use the Jmap.Api module
+
to make HTTP requests and parse responses.
+
+
For a complete implementation, we would need functions for:
+
- Mailbox operations (get, query, changes, update)
+
- Thread operations
+
- Email operations (get, query, changes, update, import, copy)
+
- Search operations
+
- Mail submission
+
- Identity management
+
- Vacation response management
+
*)
+855
lib/jmap_mail.mli
···
+
(** Implementation of the JMAP Mail extension, as defined in RFC8621 *)
+
+
(** Types for the JMAP Mail extension *)
+
module Types : sig
+
open Jmap.Types
+
+
(** {1 Mail capabilities} *)
+
+
(** Capability URI for JMAP Mail*)
+
val capability_mail : string
+
+
(** Capability URI for JMAP Submission *)
+
val capability_submission : string
+
+
(** Capability URI for JMAP Vacation Response *)
+
val capability_vacation_response : string
+
+
(** {1:mailbox Mailbox objects} *)
+
+
(** A role for a mailbox. See RFC8621 Section 2. *)
+
type mailbox_role =
+
| All (** All mail *)
+
| Archive (** Archived mail *)
+
| Drafts (** Draft messages *)
+
| Flagged (** Starred/flagged mail *)
+
| Important (** Important mail *)
+
| Inbox (** Inbox *)
+
| Junk (** Spam/Junk mail *)
+
| Sent (** Sent mail *)
+
| Trash (** Deleted/Trash mail *)
+
| Unknown of string (** Server-specific roles *)
+
+
(** A mailbox (folder) in a mail account. See RFC8621 Section 2. *)
+
type mailbox = {
+
id : id;
+
name : string;
+
parent_id : id option;
+
role : mailbox_role option;
+
sort_order : unsigned_int;
+
total_emails : unsigned_int;
+
unread_emails : unsigned_int;
+
total_threads : unsigned_int;
+
unread_threads : unsigned_int;
+
is_subscribed : bool;
+
my_rights : mailbox_rights;
+
}
+
+
(** Rights for a mailbox. See RFC8621 Section 2. *)
+
and mailbox_rights = {
+
may_read_items : bool;
+
may_add_items : bool;
+
may_remove_items : bool;
+
may_set_seen : bool;
+
may_set_keywords : bool;
+
may_create_child : bool;
+
may_rename : bool;
+
may_delete : bool;
+
may_submit : bool;
+
}
+
+
(** Filter condition for mailbox queries. See RFC8621 Section 2.3. *)
+
type mailbox_filter_condition = {
+
parent_id : id option;
+
name : string option;
+
role : string option;
+
has_any_role : bool option;
+
is_subscribed : bool option;
+
}
+
+
type mailbox_query_filter = [
+
| `And of mailbox_query_filter list
+
| `Or of mailbox_query_filter list
+
| `Not of mailbox_query_filter
+
| `Condition of mailbox_filter_condition
+
]
+
+
(** Mailbox/get request arguments. See RFC8621 Section 2.1. *)
+
type mailbox_get_arguments = {
+
account_id : id;
+
ids : id list option;
+
properties : string list option;
+
}
+
+
(** Mailbox/get response. See RFC8621 Section 2.1. *)
+
type mailbox_get_response = {
+
account_id : id;
+
state : string;
+
list : mailbox list;
+
not_found : id list;
+
}
+
+
(** Mailbox/changes request arguments. See RFC8621 Section 2.2. *)
+
type mailbox_changes_arguments = {
+
account_id : id;
+
since_state : string;
+
max_changes : unsigned_int option;
+
}
+
+
(** Mailbox/changes response. See RFC8621 Section 2.2. *)
+
type mailbox_changes_response = {
+
account_id : id;
+
old_state : string;
+
new_state : string;
+
has_more_changes : bool;
+
created : id list;
+
updated : id list;
+
destroyed : id list;
+
}
+
+
(** Mailbox/query request arguments. See RFC8621 Section 2.3. *)
+
type mailbox_query_arguments = {
+
account_id : id;
+
filter : mailbox_query_filter option;
+
sort : [ `name | `role | `sort_order ] list option;
+
limit : unsigned_int option;
+
}
+
+
(** Mailbox/query response. See RFC8621 Section 2.3. *)
+
type mailbox_query_response = {
+
account_id : id;
+
query_state : string;
+
can_calculate_changes : bool;
+
position : unsigned_int;
+
ids : id list;
+
total : unsigned_int option;
+
}
+
+
(** Mailbox/queryChanges request arguments. See RFC8621 Section 2.4. *)
+
type mailbox_query_changes_arguments = {
+
account_id : id;
+
filter : mailbox_query_filter option;
+
sort : [ `name | `role | `sort_order ] list option;
+
since_query_state : string;
+
max_changes : unsigned_int option;
+
up_to_id : id option;
+
}
+
+
(** Mailbox/queryChanges response. See RFC8621 Section 2.4. *)
+
type mailbox_query_changes_response = {
+
account_id : id;
+
old_query_state : string;
+
new_query_state : string;
+
total : unsigned_int option;
+
removed : id list;
+
added : mailbox_query_changes_added list;
+
}
+
+
and mailbox_query_changes_added = {
+
id : id;
+
index : unsigned_int;
+
}
+
+
(** Mailbox/set request arguments. See RFC8621 Section 2.5. *)
+
type mailbox_set_arguments = {
+
account_id : id;
+
if_in_state : string option;
+
create : (id * mailbox_creation) list option;
+
update : (id * mailbox_update) list option;
+
destroy : id list option;
+
}
+
+
and mailbox_creation = {
+
name : string;
+
parent_id : id option;
+
role : string option;
+
sort_order : unsigned_int option;
+
is_subscribed : bool option;
+
}
+
+
and mailbox_update = {
+
name : string option;
+
parent_id : id option;
+
role : string option;
+
sort_order : unsigned_int option;
+
is_subscribed : bool option;
+
}
+
+
(** Mailbox/set response. See RFC8621 Section 2.5. *)
+
type mailbox_set_response = {
+
account_id : id;
+
old_state : string option;
+
new_state : string;
+
created : (id * mailbox) list option;
+
updated : id list option;
+
destroyed : id list option;
+
not_created : (id * set_error) list option;
+
not_updated : (id * set_error) list option;
+
not_destroyed : (id * set_error) list option;
+
}
+
+
(** {1:thread Thread objects} *)
+
+
(** A thread in a mail account. See RFC8621 Section 3. *)
+
type thread = {
+
id : id;
+
email_ids : id list;
+
}
+
+
(** Thread/get request arguments. See RFC8621 Section 3.1. *)
+
type thread_get_arguments = {
+
account_id : id;
+
ids : id list option;
+
properties : string list option;
+
}
+
+
(** Thread/get response. See RFC8621 Section 3.1. *)
+
type thread_get_response = {
+
account_id : id;
+
state : string;
+
list : thread list;
+
not_found : id list;
+
}
+
+
(** Thread/changes request arguments. See RFC8621 Section 3.2. *)
+
type thread_changes_arguments = {
+
account_id : id;
+
since_state : string;
+
max_changes : unsigned_int option;
+
}
+
+
(** Thread/changes response. See RFC8621 Section 3.2. *)
+
type thread_changes_response = {
+
account_id : id;
+
old_state : string;
+
new_state : string;
+
has_more_changes : bool;
+
created : id list;
+
updated : id list;
+
destroyed : id list;
+
}
+
+
(** {1:email Email objects} *)
+
+
(** Addressing (mailbox) information. See RFC8621 Section 4.1.1. *)
+
type email_address = {
+
name : string option;
+
email : string;
+
parameters : (string * string) list;
+
}
+
+
(** Message header field. See RFC8621 Section 4.1.2. *)
+
type header = {
+
name : string;
+
value : string;
+
}
+
+
(** Email keyword (flag). See RFC8621 Section 4.3. *)
+
type keyword =
+
| Flagged
+
| Answered
+
| Draft
+
| Forwarded
+
| Phishing
+
| Junk
+
| NotJunk
+
| Seen
+
| Unread
+
| Custom of string
+
+
(** Email message. See RFC8621 Section 4. *)
+
type email = {
+
id : id;
+
blob_id : id;
+
thread_id : id;
+
mailbox_ids : (id * bool) list;
+
keywords : (keyword * bool) list;
+
size : unsigned_int;
+
received_at : utc_date;
+
message_id : string list;
+
in_reply_to : string list option;
+
references : string list option;
+
sender : email_address list option;
+
from : email_address list option;
+
to_ : email_address list option;
+
cc : email_address list option;
+
bcc : email_address list option;
+
reply_to : email_address list option;
+
subject : string option;
+
sent_at : utc_date option;
+
has_attachment : bool option;
+
preview : string option;
+
body_values : (string * string) list option;
+
text_body : email_body_part list option;
+
html_body : email_body_part list option;
+
attachments : email_body_part list option;
+
headers : header list option;
+
}
+
+
(** Email body part. See RFC8621 Section 4.1.4. *)
+
and email_body_part = {
+
part_id : string option;
+
blob_id : id option;
+
size : unsigned_int option;
+
headers : header list option;
+
name : string option;
+
type_ : string option;
+
charset : string option;
+
disposition : string option;
+
cid : string option;
+
language : string list option;
+
location : string option;
+
sub_parts : email_body_part list option;
+
header_parameter_name : string option;
+
header_parameter_value : string option;
+
}
+
+
(** Email query filter condition. See RFC8621 Section 4.4. *)
+
type email_filter_condition = {
+
in_mailbox : id option;
+
in_mailbox_other_than : id list option;
+
min_size : unsigned_int option;
+
max_size : unsigned_int option;
+
before : utc_date option;
+
after : utc_date option;
+
header : (string * string) option;
+
from : string option;
+
to_ : string option;
+
cc : string option;
+
bcc : string option;
+
subject : string option;
+
body : string option;
+
has_keyword : string option;
+
not_keyword : string option;
+
has_attachment : bool option;
+
text : string option;
+
}
+
+
type email_query_filter = [
+
| `And of email_query_filter list
+
| `Or of email_query_filter list
+
| `Not of email_query_filter
+
| `Condition of email_filter_condition
+
]
+
+
(** Email/get request arguments. See RFC8621 Section 4.5. *)
+
type email_get_arguments = {
+
account_id : id;
+
ids : id list option;
+
properties : string list option;
+
body_properties : string list option;
+
fetch_text_body_values : bool option;
+
fetch_html_body_values : bool option;
+
fetch_all_body_values : bool option;
+
max_body_value_bytes : unsigned_int option;
+
}
+
+
(** Email/get response. See RFC8621 Section 4.5. *)
+
type email_get_response = {
+
account_id : id;
+
state : string;
+
list : email list;
+
not_found : id list;
+
}
+
+
(** Email/changes request arguments. See RFC8621 Section 4.6. *)
+
type email_changes_arguments = {
+
account_id : id;
+
since_state : string;
+
max_changes : unsigned_int option;
+
}
+
+
(** Email/changes response. See RFC8621 Section 4.6. *)
+
type email_changes_response = {
+
account_id : id;
+
old_state : string;
+
new_state : string;
+
has_more_changes : bool;
+
created : id list;
+
updated : id list;
+
destroyed : id list;
+
}
+
+
(** Email/query request arguments. See RFC8621 Section 4.4. *)
+
type email_query_arguments = {
+
account_id : id;
+
filter : email_query_filter option;
+
sort : comparator list option;
+
collapse_threads : bool option;
+
position : unsigned_int option;
+
anchor : id option;
+
anchor_offset : int_t option;
+
limit : unsigned_int option;
+
calculate_total : bool option;
+
}
+
+
(** Email/query response. See RFC8621 Section 4.4. *)
+
type email_query_response = {
+
account_id : id;
+
query_state : string;
+
can_calculate_changes : bool;
+
position : unsigned_int;
+
ids : id list;
+
total : unsigned_int option;
+
thread_ids : id list option;
+
}
+
+
(** Email/queryChanges request arguments. See RFC8621 Section 4.7. *)
+
type email_query_changes_arguments = {
+
account_id : id;
+
filter : email_query_filter option;
+
sort : comparator list option;
+
collapse_threads : bool option;
+
since_query_state : string;
+
max_changes : unsigned_int option;
+
up_to_id : id option;
+
}
+
+
(** Email/queryChanges response. See RFC8621 Section 4.7. *)
+
type email_query_changes_response = {
+
account_id : id;
+
old_query_state : string;
+
new_query_state : string;
+
total : unsigned_int option;
+
removed : id list;
+
added : email_query_changes_added list;
+
}
+
+
and email_query_changes_added = {
+
id : id;
+
index : unsigned_int;
+
}
+
+
(** Email/set request arguments. See RFC8621 Section 4.8. *)
+
type email_set_arguments = {
+
account_id : id;
+
if_in_state : string option;
+
create : (id * email_creation) list option;
+
update : (id * email_update) list option;
+
destroy : id list option;
+
}
+
+
and email_creation = {
+
mailbox_ids : (id * bool) list;
+
keywords : (keyword * bool) list option;
+
received_at : utc_date option;
+
message_id : string list option;
+
in_reply_to : string list option;
+
references : string list option;
+
sender : email_address list option;
+
from : email_address list option;
+
to_ : email_address list option;
+
cc : email_address list option;
+
bcc : email_address list option;
+
reply_to : email_address list option;
+
subject : string option;
+
body_values : (string * string) list option;
+
text_body : email_body_part list option;
+
html_body : email_body_part list option;
+
attachments : email_body_part list option;
+
headers : header list option;
+
}
+
+
and email_update = {
+
keywords : (keyword * bool) list option;
+
mailbox_ids : (id * bool) list option;
+
}
+
+
(** Email/set response. See RFC8621 Section 4.8. *)
+
type email_set_response = {
+
account_id : id;
+
old_state : string option;
+
new_state : string;
+
created : (id * email) list option;
+
updated : id list option;
+
destroyed : id list option;
+
not_created : (id * set_error) list option;
+
not_updated : (id * set_error) list option;
+
not_destroyed : (id * set_error) list option;
+
}
+
+
(** Email/copy request arguments. See RFC8621 Section 4.9. *)
+
type email_copy_arguments = {
+
from_account_id : id;
+
account_id : id;
+
create : (id * email_creation) list;
+
on_success_destroy_original : bool option;
+
}
+
+
(** Email/copy response. See RFC8621 Section 4.9. *)
+
type email_copy_response = {
+
from_account_id : id;
+
account_id : id;
+
created : (id * email) list option;
+
not_created : (id * set_error) list option;
+
}
+
+
(** Email/import request arguments. See RFC8621 Section 4.10. *)
+
type email_import_arguments = {
+
account_id : id;
+
emails : (id * email_import) list;
+
}
+
+
and email_import = {
+
blob_id : id;
+
mailbox_ids : (id * bool) list;
+
keywords : (keyword * bool) list option;
+
received_at : utc_date option;
+
}
+
+
(** Email/import response. See RFC8621 Section 4.10. *)
+
type email_import_response = {
+
account_id : id;
+
created : (id * email) list option;
+
not_created : (id * set_error) list option;
+
}
+
+
(** {1:search_snippet Search snippets} *)
+
+
(** SearchSnippet/get request arguments. See RFC8621 Section 4.11. *)
+
type search_snippet_get_arguments = {
+
account_id : id;
+
email_ids : id list;
+
filter : email_filter_condition;
+
}
+
+
(** SearchSnippet/get response. See RFC8621 Section 4.11. *)
+
type search_snippet_get_response = {
+
account_id : id;
+
list : (id * search_snippet) list;
+
not_found : id list;
+
}
+
+
and search_snippet = {
+
subject : string option;
+
preview : string option;
+
}
+
+
(** {1:submission EmailSubmission objects} *)
+
+
(** EmailSubmission address. See RFC8621 Section 5.1. *)
+
type submission_address = {
+
email : string;
+
parameters : (string * string) list option;
+
}
+
+
(** Email submission object. See RFC8621 Section 5.1. *)
+
type email_submission = {
+
id : id;
+
identity_id : id;
+
email_id : id;
+
thread_id : id;
+
envelope : envelope option;
+
send_at : utc_date option;
+
undo_status : [
+
| `pending
+
| `final
+
| `canceled
+
] option;
+
delivery_status : (string * submission_status) list option;
+
dsn_blob_ids : (string * id) list option;
+
mdn_blob_ids : (string * id) list option;
+
}
+
+
(** Envelope for mail submission. See RFC8621 Section 5.1. *)
+
and envelope = {
+
mail_from : submission_address;
+
rcpt_to : submission_address list;
+
}
+
+
(** Delivery status for submitted email. See RFC8621 Section 5.1. *)
+
and submission_status = {
+
smtp_reply : string;
+
delivered : string option;
+
}
+
+
(** EmailSubmission/get request arguments. See RFC8621 Section 5.3. *)
+
type email_submission_get_arguments = {
+
account_id : id;
+
ids : id list option;
+
properties : string list option;
+
}
+
+
(** EmailSubmission/get response. See RFC8621 Section 5.3. *)
+
type email_submission_get_response = {
+
account_id : id;
+
state : string;
+
list : email_submission list;
+
not_found : id list;
+
}
+
+
(** EmailSubmission/changes request arguments. See RFC8621 Section 5.4. *)
+
type email_submission_changes_arguments = {
+
account_id : id;
+
since_state : string;
+
max_changes : unsigned_int option;
+
}
+
+
(** EmailSubmission/changes response. See RFC8621 Section 5.4. *)
+
type email_submission_changes_response = {
+
account_id : id;
+
old_state : string;
+
new_state : string;
+
has_more_changes : bool;
+
created : id list;
+
updated : id list;
+
destroyed : id list;
+
}
+
+
(** EmailSubmission/query filter condition. See RFC8621 Section 5.5. *)
+
type email_submission_filter_condition = {
+
identity_id : id option;
+
email_id : id option;
+
thread_id : id option;
+
before : utc_date option;
+
after : utc_date option;
+
subject : string option;
+
}
+
+
type email_submission_query_filter = [
+
| `And of email_submission_query_filter list
+
| `Or of email_submission_query_filter list
+
| `Not of email_submission_query_filter
+
| `Condition of email_submission_filter_condition
+
]
+
+
(** EmailSubmission/query request arguments. See RFC8621 Section 5.5. *)
+
type email_submission_query_arguments = {
+
account_id : id;
+
filter : email_submission_query_filter option;
+
sort : comparator list option;
+
position : unsigned_int option;
+
anchor : id option;
+
anchor_offset : int_t option;
+
limit : unsigned_int option;
+
calculate_total : bool option;
+
}
+
+
(** EmailSubmission/query response. See RFC8621 Section 5.5. *)
+
type email_submission_query_response = {
+
account_id : id;
+
query_state : string;
+
can_calculate_changes : bool;
+
position : unsigned_int;
+
ids : id list;
+
total : unsigned_int option;
+
}
+
+
(** EmailSubmission/set request arguments. See RFC8621 Section 5.6. *)
+
type email_submission_set_arguments = {
+
account_id : id;
+
if_in_state : string option;
+
create : (id * email_submission_creation) list option;
+
update : (id * email_submission_update) list option;
+
destroy : id list option;
+
on_success_update_email : (id * email_update) list option;
+
}
+
+
and email_submission_creation = {
+
email_id : id;
+
identity_id : id;
+
envelope : envelope option;
+
send_at : utc_date option;
+
}
+
+
and email_submission_update = {
+
email_id : id option;
+
identity_id : id option;
+
envelope : envelope option;
+
undo_status : [`canceled] option;
+
}
+
+
(** EmailSubmission/set response. See RFC8621 Section 5.6. *)
+
type email_submission_set_response = {
+
account_id : id;
+
old_state : string option;
+
new_state : string;
+
created : (id * email_submission) list option;
+
updated : id list option;
+
destroyed : id list option;
+
not_created : (id * set_error) list option;
+
not_updated : (id * set_error) list option;
+
not_destroyed : (id * set_error) list option;
+
}
+
+
(** {1:identity Identity objects} *)
+
+
(** Identity for sending mail. See RFC8621 Section 6. *)
+
type identity = {
+
id : id;
+
name : string;
+
email : string;
+
reply_to : email_address list option;
+
bcc : email_address list option;
+
text_signature : string option;
+
html_signature : string option;
+
may_delete : bool;
+
}
+
+
(** Identity/get request arguments. See RFC8621 Section 6.1. *)
+
type identity_get_arguments = {
+
account_id : id;
+
ids : id list option;
+
properties : string list option;
+
}
+
+
(** Identity/get response. See RFC8621 Section 6.1. *)
+
type identity_get_response = {
+
account_id : id;
+
state : string;
+
list : identity list;
+
not_found : id list;
+
}
+
+
(** Identity/changes request arguments. See RFC8621 Section 6.2. *)
+
type identity_changes_arguments = {
+
account_id : id;
+
since_state : string;
+
max_changes : unsigned_int option;
+
}
+
+
(** Identity/changes response. See RFC8621 Section 6.2. *)
+
type identity_changes_response = {
+
account_id : id;
+
old_state : string;
+
new_state : string;
+
has_more_changes : bool;
+
created : id list;
+
updated : id list;
+
destroyed : id list;
+
}
+
+
(** Identity/set request arguments. See RFC8621 Section 6.3. *)
+
type identity_set_arguments = {
+
account_id : id;
+
if_in_state : string option;
+
create : (id * identity_creation) list option;
+
update : (id * identity_update) list option;
+
destroy : id list option;
+
}
+
+
and identity_creation = {
+
name : string;
+
email : string;
+
reply_to : email_address list option;
+
bcc : email_address list option;
+
text_signature : string option;
+
html_signature : string option;
+
}
+
+
and identity_update = {
+
name : string option;
+
email : string option;
+
reply_to : email_address list option;
+
bcc : email_address list option;
+
text_signature : string option;
+
html_signature : string option;
+
}
+
+
(** Identity/set response. See RFC8621 Section 6.3. *)
+
type identity_set_response = {
+
account_id : id;
+
old_state : string option;
+
new_state : string;
+
created : (id * identity) list option;
+
updated : id list option;
+
destroyed : id list option;
+
not_created : (id * set_error) list option;
+
not_updated : (id * set_error) list option;
+
not_destroyed : (id * set_error) list option;
+
}
+
+
(** {1:vacation_response VacationResponse objects} *)
+
+
(** Vacation auto-reply setting. See RFC8621 Section 7. *)
+
type vacation_response = {
+
id : id;
+
is_enabled : bool;
+
from_date : utc_date option;
+
to_date : utc_date option;
+
subject : string option;
+
text_body : string option;
+
html_body : string option;
+
}
+
+
(** VacationResponse/get request arguments. See RFC8621 Section 7.2. *)
+
type vacation_response_get_arguments = {
+
account_id : id;
+
ids : id list option;
+
properties : string list option;
+
}
+
+
(** VacationResponse/get response. See RFC8621 Section 7.2. *)
+
type vacation_response_get_response = {
+
account_id : id;
+
state : string;
+
list : vacation_response list;
+
not_found : id list;
+
}
+
+
(** VacationResponse/set request arguments. See RFC8621 Section 7.3. *)
+
type vacation_response_set_arguments = {
+
account_id : id;
+
if_in_state : string option;
+
update : (id * vacation_response_update) list;
+
}
+
+
and vacation_response_update = {
+
is_enabled : bool option;
+
from_date : utc_date option;
+
to_date : utc_date option;
+
subject : string option;
+
text_body : string option;
+
html_body : string option;
+
}
+
+
(** VacationResponse/set response. See RFC8621 Section 7.3. *)
+
type vacation_response_set_response = {
+
account_id : id;
+
old_state : string option;
+
new_state : string;
+
updated : id list option;
+
not_updated : (id * set_error) list option;
+
}
+
end
+
+
(** {1 JSON serialization} *)
+
+
module Json : sig
+
open Types
+
+
(** {2 Helper functions for serialization} *)
+
+
val string_of_mailbox_role : mailbox_role -> string
+
val mailbox_role_of_string : string -> mailbox_role
+
+
val string_of_keyword : keyword -> string
+
val keyword_of_string : string -> keyword
+
+
(** {2 Mailbox serialization} *)
+
+
(** TODO:claude - Need to implement all JSON serialization functions
+
for each type we've defined. This would be a substantial amount of
+
code and likely require additional understanding of the ezjsonm API.
+
+
The interface would include functions like:
+
+
val mailbox_to_json : mailbox -> Ezjsonm.value
+
val mailbox_of_json : Ezjsonm.value -> mailbox result
+
+
And similarly for all other types.
+
*)
+
end
+
+
(** {1 API functions} *)
+
+
(** TODO:claude - Need to implement API functions for interacting with the
+
mail-specific JMAP server endpoints. These would use the Jmap.Api module
+
to make HTTP requests and parse responses.
+
+
The interface would include functions like:
+
+
val get_mailboxes : Jmap.Api.session -> ?ids:id list -> ?properties:string list -> account_id:id -> (mailbox_get_response, error) result Lwt.t
+
+
And similarly for all other API operations.
+
*)