@@ -321,6 +321,175 @@ def from_dict(cls, d: Dict[str, Any]) -> RenderResult:
321321 )
322322
323323
324+ # --------------------------------------------------------------------------- #
325+ # Inbound — receiving addresses and received mail (``inbound`` scope)
326+ # --------------------------------------------------------------------------- #
327+ @dataclass
328+ class InboundAddress :
329+ """An address provisioned on the workspace's shared receiving domain."""
330+
331+ id : str
332+ address : str
333+ description : Optional [str ]
334+ forward_to : Optional [str ]
335+ active : bool
336+ livemode : bool
337+ created_at : str
338+
339+ @classmethod
340+ def from_dict (cls , d : Dict [str , Any ]) -> InboundAddress :
341+ return cls (
342+ id = str (d .get ("id" , "" )),
343+ address = str (d .get ("address" , "" )),
344+ description = d .get ("description" ),
345+ forward_to = d .get ("forwardTo" ),
346+ active = bool (d .get ("active" , False )),
347+ livemode = bool (d .get ("livemode" , False )),
348+ created_at = str (d .get ("createdAt" , "" )),
349+ )
350+
351+
352+ @dataclass
353+ class InboundMessageSummary :
354+ """A received-message summary, as returned by ``inbound.messages.list``."""
355+
356+ id : str
357+ status : str
358+ from_ : Optional [str ]
359+ subject : Optional [str ]
360+ plus_tag : Optional [str ]
361+ size_bytes : int
362+ received_at : str
363+
364+ @classmethod
365+ def from_dict (cls , d : Dict [str , Any ]) -> InboundMessageSummary :
366+ return cls (
367+ id = str (d .get ("id" , "" )),
368+ status = str (d .get ("status" , "" )),
369+ from_ = d .get ("from" ),
370+ subject = d .get ("subject" ),
371+ plus_tag = d .get ("plusTag" ),
372+ size_bytes = int (d .get ("sizeBytes" , 0 )),
373+ received_at = str (d .get ("receivedAt" , "" )),
374+ )
375+
376+
377+ @dataclass
378+ class InboundAttachment :
379+ """One attachment on a received message. Fetch bytes via ``.attachment(id, index)``."""
380+
381+ index : int
382+ filename : Optional [str ]
383+ content_type : str
384+ size : int
385+ #: Authenticated API URL (requires an ``inbound``-scoped key), not a signed link.
386+ url : str
387+
388+ @classmethod
389+ def from_dict (cls , d : Dict [str , Any ]) -> InboundAttachment :
390+ return cls (
391+ index = int (d .get ("index" , 0 )),
392+ filename = d .get ("filename" ),
393+ content_type = str (d .get ("contentType" , "" )),
394+ size = int (d .get ("size" , 0 )),
395+ url = str (d .get ("url" , "" )),
396+ )
397+
398+
399+ @dataclass
400+ class InboundMessage :
401+ """A received message. Common fields are typed; ``.raw`` holds the full body."""
402+
403+ id : str
404+ status : str
405+ channel : str
406+ address : Optional [str ]
407+ subject : Optional [str ]
408+ text : Optional [str ]
409+ html : Optional [str ]
410+ stripped_reply : Optional [str ]
411+ size_bytes : int
412+ received_at : str
413+ raw_url : str
414+ attachments : List [InboundAttachment ] = field (default_factory = list )
415+ raw : Dict [str , Any ] = field (default_factory = dict )
416+
417+ @classmethod
418+ def from_dict (cls , d : Dict [str , Any ]) -> InboundMessage :
419+ atts = d .get ("attachments" ) or []
420+ return cls (
421+ id = str (d .get ("id" , "" )),
422+ status = str (d .get ("status" , "" )),
423+ channel = str (d .get ("channel" , "" )),
424+ address = d .get ("address" ),
425+ subject = d .get ("subject" ),
426+ text = d .get ("text" ),
427+ html = d .get ("html" ),
428+ stripped_reply = d .get ("strippedReply" ),
429+ size_bytes = int (d .get ("sizeBytes" , 0 )),
430+ received_at = str (d .get ("receivedAt" , "" )),
431+ raw_url = str (d .get ("rawUrl" , "" )),
432+ attachments = [InboundAttachment .from_dict (a ) for a in atts if isinstance (a , dict )],
433+ raw = d ,
434+ )
435+
436+
437+ @dataclass
438+ class InboundBytes :
439+ """Raw bytes fetched from an inbound message (raw MIME source or attachment)."""
440+
441+ content : bytes
442+ content_type : str
443+ filename : Optional [str ] = None
444+
445+
446+ @dataclass
447+ class InboundDnsRecord :
448+ """A DNS record a custom inbound domain must publish before it can receive."""
449+
450+ type : str
451+ name : str
452+ value : str
453+ purpose : str
454+ priority : Optional [int ] = None
455+
456+ @classmethod
457+ def from_dict (cls , d : Dict [str , Any ]) -> InboundDnsRecord :
458+ return cls (
459+ type = str (d .get ("type" , "" )),
460+ name = str (d .get ("name" , "" )),
461+ value = str (d .get ("value" , "" )),
462+ purpose = str (d .get ("purpose" , "" )),
463+ priority = d .get ("priority" ),
464+ )
465+
466+
467+ @dataclass
468+ class InboundDomain :
469+ """A custom inbound domain the workspace receives mail on (or the shared one)."""
470+
471+ id : str
472+ domain : str
473+ kind : str
474+ status : str
475+ verified_at : Optional [str ]
476+ created_at : str
477+ records : List [InboundDnsRecord ] = field (default_factory = list )
478+
479+ @classmethod
480+ def from_dict (cls , d : Dict [str , Any ]) -> InboundDomain :
481+ recs = d .get ("records" ) or []
482+ return cls (
483+ id = str (d .get ("id" , "" )),
484+ domain = str (d .get ("domain" , "" )),
485+ kind = str (d .get ("kind" , "" )),
486+ status = str (d .get ("status" , "" )),
487+ verified_at = d .get ("verifiedAt" ),
488+ created_at = str (d .get ("createdAt" , "" )),
489+ records = [InboundDnsRecord .from_dict (r ) for r in recs if isinstance (r , dict )],
490+ )
491+
492+
324493@dataclass
325494class Workspace :
326495 id : str
0 commit comments