Skip to main content

greentic_types/
messaging.rs

1//! Generic channel messaging envelope shared across providers.
2
3use alloc::{collections::BTreeMap, string::String, vec::Vec};
4
5#[cfg(feature = "schemars")]
6use schemars::JsonSchema;
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10use crate::{ReplyScope, TenantCtx};
11
12/// Message actor (sender/initiator).
13#[derive(Clone, Debug, PartialEq, Eq)]
14#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
15#[cfg_attr(feature = "schemars", derive(JsonSchema))]
16pub struct Actor {
17    /// Actor identifier in provider space (e.g., slack user id, webex person id).
18    pub id: String,
19    /// Optional actor kind (e.g. "user", "bot", "system").
20    #[cfg_attr(
21        feature = "serde",
22        serde(default, skip_serializing_if = "Option::is_none")
23    )]
24    pub kind: Option<String>,
25}
26
27/// Outbound destination for egress providers.
28#[derive(Clone, Debug, PartialEq, Eq)]
29#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
30#[cfg_attr(feature = "schemars", derive(JsonSchema))]
31pub struct Destination {
32    /// Destination identifier (provider specific; may be composite e.g. "teamId:channelId").
33    pub id: String,
34    /// Optional destination kind (e.g. "chat", "room", "user", "channel", "email", "phone").
35    #[cfg_attr(
36        feature = "serde",
37        serde(default, skip_serializing_if = "Option::is_none")
38    )]
39    pub kind: Option<String>,
40}
41
42/// Collection of metadata entries associated with a channel message.
43pub type MessageMetadata = BTreeMap<String, String>;
44
45/// Generic attachment referenced by a channel message.
46#[derive(Clone, Debug, PartialEq, Eq)]
47#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
48#[cfg_attr(feature = "schemars", derive(JsonSchema))]
49pub struct Attachment {
50    /// MIME type of the attachment (for example `image/png`).
51    pub mime_type: String,
52    /// URL pointing at the attachment payload.
53    pub url: String,
54    /// Optional display name for the attachment.
55    #[cfg_attr(
56        feature = "serde",
57        serde(default, skip_serializing_if = "Option::is_none")
58    )]
59    pub name: Option<String>,
60    /// Optional attachment size in bytes.
61    #[cfg_attr(
62        feature = "serde",
63        serde(default, skip_serializing_if = "Option::is_none")
64    )]
65    pub size_bytes: Option<u64>,
66}
67
68/// Envelope for channel messages exchanged with adapters.
69#[derive(Clone, Debug, PartialEq, Eq)]
70#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
71#[cfg_attr(feature = "schemars", derive(JsonSchema))]
72pub struct ChannelMessageEnvelope {
73    /// Stable identifier for the message.
74    pub id: String,
75    /// Tenant context propagated with the message.
76    pub tenant: TenantCtx,
77    /// Abstract channel identifier or type.
78    pub channel: String,
79    /// Conversation or thread identifier.
80    pub session_id: String,
81    /// Optional reply scope that can be used for resumption.
82    #[cfg_attr(
83        feature = "serde",
84        serde(default, skip_serializing_if = "Option::is_none")
85    )]
86    pub reply_scope: Option<ReplyScope>,
87    /// Optional actor (sender/initiator) associated with the message (primarily ingress).
88    #[cfg_attr(
89        feature = "serde",
90        serde(default, skip_serializing_if = "Option::is_none")
91    )]
92    pub from: Option<Actor>,
93    /// Outbound destinations for egress. Empty means “unspecified” and may be satisfied by provider config defaults.
94    #[cfg_attr(
95        feature = "serde",
96        serde(default, skip_serializing_if = "Vec::is_empty")
97    )]
98    pub to: Vec<Destination>,
99    /// Optional correlation identifier used by outbound adapters.
100    #[cfg_attr(
101        feature = "serde",
102        serde(default, skip_serializing_if = "Option::is_none")
103    )]
104    pub correlation_id: Option<String>,
105    /// Optional text content.
106    #[cfg_attr(
107        feature = "serde",
108        serde(default, skip_serializing_if = "Option::is_none")
109    )]
110    pub text: Option<String>,
111    /// Attachments included with the message.
112    #[cfg_attr(
113        feature = "serde",
114        serde(default, skip_serializing_if = "Vec::is_empty")
115    )]
116    pub attachments: Vec<Attachment>,
117    /// Free-form metadata for adapters and flows.
118    #[cfg_attr(feature = "serde", serde(default))]
119    pub metadata: MessageMetadata,
120}