My agentic slop goes here. Not intended for anyone else!
1(** Email object representation and operations.
2
3 This module provides the main Email object type and operations as defined in
4 RFC 8621 Section 4.1. The Email object represents a single email message with
5 access to message metadata, headers, body structure, and content through a
6 property-based API that supports partial object loading.
7
8 Email objects are immutable and server-controlled. All modifications must be
9 performed through the Email/set method using patch objects.
10
11 @see <https://www.rfc-editor.org/rfc/rfc8621.html#section-4.1> RFC 8621, Section 4.1 - Email Object
12*)
13
14(** Email object type.
15
16 Represents a complete email message as defined in RFC 8621 Section 4.1.
17 Properties are optional to support partial object loading where only
18 requested properties are included in responses.
19*)
20type t
21
22(** JSON serialization interface *)
23include Jmap_sigs.JSONABLE with type t := t
24
25(** Pretty printing interface *)
26include Jmap_sigs.PRINTABLE with type t := t
27
28(** JMAP object interface with property selection support - implemented manually *)
29
30(** Get the server-assigned email identifier.
31 @param t The email object
32 @return Email ID if present in the object *)
33val id : t -> Jmap.Id.t option
34
35(** Get the blob ID for downloading the complete raw message.
36 @param t The email object
37 @return Blob identifier for RFC 5322 message access *)
38val blob_id : t -> Jmap.Id.t option
39
40(** Get the thread identifier linking related messages.
41 @param t The email object
42 @return Thread ID for conversation grouping *)
43val thread_id : t -> Jmap.Id.t option
44
45(** Get the set of mailboxes containing this email.
46 @param t The email object
47 @return Map of mailbox IDs to boolean values (always true when present) *)
48val mailbox_ids : t -> (Jmap.Id.t, bool) Hashtbl.t option
49
50(** Get the keywords/flags applied to this email.
51 @param t The email object
52 @return Set of keywords if included in the retrieved properties *)
53val keywords : t -> Keywords.t option
54
55(** Get the total size of the raw message.
56 @param t The email object
57 @return Message size in octets *)
58val size : t -> Jmap.UInt.t option
59
60(** Get the server timestamp when the message was received.
61 @param t The email object
62 @return Reception timestamp *)
63val received_at : t -> Jmap.Date.t option
64
65(** Get the Message-ID header values.
66 @param t The email object
67 @return List of message identifiers if the MessageId property was requested *)
68val message_id : t -> string list option
69
70(** Get the In-Reply-To header values for threading.
71 @param t The email object
72 @return List of message IDs this email replies to *)
73val in_reply_to : t -> string list option
74
75(** Get the References header values for threading.
76 @param t The email object
77 @return List of referenced message IDs for conversation threading *)
78val references : t -> string list option
79
80(** Get the Sender header address.
81 @param t The email object
82 @return Single sender address if the Sender property was requested *)
83val sender : t -> Address.t option
84
85(** Get the From header addresses.
86 @param t The email object
87 @return List of sender addresses if the From property was requested *)
88val from : t -> Address.t list option
89
90(** Get the To header addresses.
91 @param t The email object
92 @return List of primary recipient addresses if the To property was requested *)
93val to_ : t -> Address.t list option
94
95(** Get the Cc header addresses.
96 @param t The email object
97 @return List of carbon copy addresses if the Cc property was requested *)
98val cc : t -> Address.t list option
99
100(** Get the Bcc header addresses.
101 @param t The email object
102 @return List of blind carbon copy addresses if the Bcc property was requested *)
103val bcc : t -> Address.t list option
104
105(** Get the Reply-To header addresses.
106 @param t The email object
107 @return List of reply-to addresses if the ReplyTo property was requested *)
108val reply_to : t -> Address.t list option
109
110(** Get the email subject line.
111 @param t The email object
112 @return Subject text if the Subject property was requested *)
113val subject : t -> string option
114
115(** Get the Date header timestamp (when message was sent).
116 @param t The email object
117 @return Send timestamp if the SentAt property was requested *)
118val sent_at : t -> Jmap.Date.t option
119
120(** Check if the email has non-inline attachments.
121 @param t The email object
122 @return true if attachments are present, if the HasAttachment property was requested *)
123val has_attachment : t -> bool option
124
125(** Get the server-generated preview text for display.
126 @param t The email object
127 @return Preview text if the Preview property was requested *)
128val preview : t -> string option
129
130(** Get the complete MIME structure tree of the message.
131 @param t The email object
132 @return Body structure if the BodyStructure property was requested *)
133val body_structure : t -> Body.t option
134
135(** Get decoded content of requested text body parts.
136 @param t The email object
137 @return Map of part IDs to decoded content if BodyValues was requested *)
138val body_values : t -> (string, Body.Value.t) Hashtbl.t option
139
140(** Get text/plain body parts suitable for display.
141 @param t The email object
142 @return List of text body parts if the TextBody property was requested *)
143val text_body : t -> Body.t list option
144
145(** Get text/html body parts suitable for display.
146 @param t The email object
147 @return List of HTML body parts if the HtmlBody property was requested *)
148val html_body : t -> Body.t list option
149
150(** Get attachment body parts.
151 @param t The email object
152 @return List of attachment parts if the Attachments property was requested *)
153val attachments : t -> Body.t list option
154
155(** Get the value of a specific header field.
156
157 Retrieves raw header values for headers requested via the Header:[name]
158 property in Email/get requests.
159
160 @param t The email object
161 @param name The header field name
162 @return Raw header value if the Header property was requested for this name *)
163val header : t -> string -> string option
164
165(** Get all custom/extended properties.
166
167 Retrieves any server-specific extension properties that were requested
168 but are not part of the standard Email object specification.
169
170 @param t The email object
171 @return Map of property names to JSON values for extended properties *)
172val other_properties : t -> (string, Yojson.Safe.t) Hashtbl.t
173
174(** Create a detailed Email object with all properties.
175
176 This is an extended version of the JMAP_OBJECT create function that allows
177 setting all email properties at once. Used primarily for constructing Email
178 objects from server responses or for testing purposes.
179
180 @param Jmap.Id.t Server-assigned unique identifier
181 @param blob_id Blob ID for raw message access
182 @param thread_id Thread identifier for conversation grouping
183 @param mailbox_ids Set of mailboxes containing this email
184 @param keywords Set of keywords/flags applied
185 @param size Total size of raw message in octets
186 @param received_at Server timestamp when message was received
187 @param message_id Message-ID header values
188 @param in_reply_to In-Reply-To header values
189 @param references References header values
190 @param sender Sender header address
191 @param from From header addresses
192 @param to_ To header addresses
193 @param cc Cc header addresses
194 @param bcc Bcc header addresses
195 @param reply_to Reply-To header addresses
196 @param subject Subject header text
197 @param sent_at Date header timestamp
198 @param has_attachment Whether email has attachments
199 @param preview Server-generated preview text
200 @param body_structure Complete MIME structure
201 @param body_values Decoded text content
202 @param text_body Text/plain body parts
203 @param html_body Text/html body parts
204 @param attachments Attachment body parts
205 @param headers Map of custom header values
206 @param other_properties Extended/custom properties
207 @return New email object *)
208val create_full :
209 ?id:Jmap.Id.t ->
210 ?blob_id:Jmap.Id.t ->
211 ?thread_id:Jmap.Id.t ->
212 ?mailbox_ids:(Jmap.Id.t, bool) Hashtbl.t ->
213 ?keywords:Keywords.t ->
214 ?size:Jmap.UInt.t ->
215 ?received_at:Jmap.Date.t ->
216 ?message_id:string list ->
217 ?in_reply_to:string list ->
218 ?references:string list ->
219 ?sender:Address.t ->
220 ?from:Address.t list ->
221 ?to_:Address.t list ->
222 ?cc:Address.t list ->
223 ?bcc:Address.t list ->
224 ?reply_to:Address.t list ->
225 ?subject:string ->
226 ?sent_at:Jmap.Date.t ->
227 ?has_attachment:bool ->
228 ?preview:string ->
229 ?body_structure:Body.t ->
230 ?body_values:(string, Body.Value.t) Hashtbl.t ->
231 ?text_body:Body.t list ->
232 ?html_body:Body.t list ->
233 ?attachments:Body.t list ->
234 ?headers:(string, string) Hashtbl.t ->
235 ?other_properties:(string, Yojson.Safe.t) Hashtbl.t ->
236 unit -> t
237
238(** Safely extract the email ID.
239 @param t The email object
240 @return Ok with the ID, or Error with message if not present *)
241val get_id : t -> (Jmap.Id.t, string) result
242
243(** Extract the email ID, raising an exception if not present.
244 @param t The email object
245 @return The email ID *)
246val take_id : t -> Jmap.Id.t
247
248(** Check if the email is unread.
249
250 An email is considered unread if it's not a draft and doesn't have
251 the $seen keyword applied.
252
253 @param t The email object
254 @return true if email appears to be unread based on available keywords *)
255val is_unread : t -> bool
256
257(** Check if the email is a draft.
258
259 @param t The email object
260 @return true if email has the $draft keyword *)
261val is_draft : t -> bool
262
263(** Check if the email is flagged for attention.
264
265 @param t The email object
266 @return true if email has the $flagged keyword *)
267val is_flagged : t -> bool
268
269(** Get the primary sender address.
270
271 Returns the first address from the From field, or the Sender field
272 if From is not available.
273
274 @param t The email object
275 @return Primary sender address if available *)
276val primary_sender : t -> Address.t option
277
278(** Get all recipient addresses (To, Cc, Bcc combined).
279
280 @param t The email object
281 @return List of all recipient addresses from To, Cc, and Bcc fields *)
282val all_recipients : t -> Address.t list
283
284(** Get a short display summary of the email.
285
286 Creates a brief text summary suitable for email list display,
287 including sender, subject, and timestamp information.
288
289 @param t The email object
290 @return String summary of email for list display *)
291val display_summary : t -> string
292
293
294
295(** Email patch operations for Email/set method.
296
297 Provides utilities for creating patch objects used in Email/set operations
298 to modify email properties. Only keywords and mailbox membership can be
299 modified after email creation.
300*)
301module Patch : sig
302 (** Create a patch object for Email/set operations.
303
304 Generates JSON Patch operations for modifying email properties.
305 Only keywords and mailbox membership can be modified after creation.
306
307 @param add_keywords Keywords to add to the email
308 @param remove_keywords Keywords to remove from the email
309 @param add_mailboxes Mailboxes to add the email to
310 @param remove_mailboxes Mailboxes to remove the email from
311 @return JSON Patch operations for Email/set *)
312 val create :
313 ?add_keywords:Keywords.t ->
314 ?remove_keywords:Keywords.t ->
315 ?add_mailboxes:Jmap.Id.t list ->
316 ?remove_mailboxes:Jmap.Id.t list ->
317 unit -> Yojson.Safe.t
318
319 (** Mark email as read by adding $seen keyword.
320 @return Patch object to mark email as read *)
321 val mark_read : unit -> Yojson.Safe.t
322
323 (** Mark email as unread by removing $seen keyword.
324 @return Patch object to mark email as unread *)
325 val mark_unread : unit -> Yojson.Safe.t
326
327 (** Flag email for attention by adding $flagged keyword.
328 @return Patch object to flag email *)
329 val flag : unit -> Yojson.Safe.t
330
331 (** Remove flag from email by removing $flagged keyword.
332 @return Patch object to unflag email *)
333 val unflag : unit -> Yojson.Safe.t
334
335 (** Move email to specific mailboxes.
336
337 @param mailbox_ids List of target mailbox IDs
338 @return Patch object to set email mailbox membership *)
339 val move_to_mailboxes : Jmap.Id.t list -> Yojson.Safe.t
340end
341
342(** Module aliases for external access *)
343
344(** Email address types and operations *)
345module Email_address = Address
346
347(** Email keywords and flags *)
348module Email_keywords = Keywords
349
350(** Email header fields *)
351module Email_header = Header
352
353(** Email body parts and content *)
354module Email_body = Body
355
356(** Apple Mail extensions *)
357module Apple_mail = Apple
358
359(** Thread operations and data types *)
360module Thread = Thread
361
362(** Identity operations and data types *)
363module Identity = Identity
364
365(** Email query builder and operations *)
366module Query = Query
367
368(** Email response parsing using core JMAP parsers *)
369module Email_response = Response
370
371(** Email set operations using core JMAP Set_args *)
372module Email_set = Set
373
374(** Email changes operations using core JMAP Changes_args *)
375module Email_changes = Changes
376
377(** Legacy aliases for backward compatibility *)
378module Types : sig
379 module Keywords = Keywords
380 module Email_address = Address
381 module Email : sig
382 type nonrec t = t
383 val id : t -> Jmap.Id.t option
384 val received_at : t -> Jmap.Date.t option
385 val subject : t -> string option
386 val from : t -> Address.t list option
387 val keywords : t -> Keywords.t option
388 end
389end