chat_system/message.rs
1//! Core message types.
2
3use serde::{Deserialize, Serialize};
4
5/// The kind of a message, allowing callers to distinguish between regular
6/// text messages and system events.
7#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
8#[serde(rename_all = "snake_case")]
9pub enum MessageType {
10 /// A regular text message.
11 #[default]
12 Text,
13 /// A system/service message (join, leave, topic change, etc.).
14 System,
15 /// The message was edited (content reflects the latest version).
16 Edit,
17 /// The message was deleted (content may be empty).
18 Delete,
19 /// The message contains a media attachment (image, file, etc.).
20 Media,
21 /// An action / `/me` message (IRC ACTION, Slack `/me`).
22 Action,
23}
24
25/// A single emoji reaction attached to a message, with an aggregate count and
26/// the list of user IDs who reacted.
27///
28/// `user_ids` may be empty on platforms that only expose aggregate counts.
29#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
30pub struct Reaction {
31 /// The emoji (Unicode character or platform-specific shortcode).
32 pub emoji: String,
33 /// Number of users who added this reaction.
34 pub count: u32,
35 /// IDs of the users who reacted (may be empty if the platform does not expose them).
36 #[serde(default)]
37 pub user_ids: Vec<String>,
38}
39
40/// A message received from or sent to a chat platform.
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct Message {
43 pub id: String,
44 pub sender: String,
45 pub content: String,
46 pub timestamp: i64,
47 #[serde(default)]
48 pub channel: Option<String>,
49 /// ID of the message this is replying to, if any.
50 #[serde(default)]
51 pub reply_to: Option<String>,
52 /// Thread / conversation ID, when the platform distinguishes threads from
53 /// the main channel timeline (e.g. Slack, Discord, Matrix).
54 #[serde(default)]
55 pub thread_id: Option<String>,
56 #[serde(default)]
57 pub media: Option<Vec<MediaAttachment>>,
58 #[serde(default)]
59 pub is_direct: bool,
60 /// The kind of this message.
61 #[serde(default)]
62 pub message_type: MessageType,
63 /// When the message was last edited (Unix timestamp), if applicable.
64 #[serde(default)]
65 pub edited_timestamp: Option<i64>,
66 /// Reactions attached to this message (populated when receiving messages on
67 /// platforms that expose them; `None` means unknown / not fetched).
68 #[serde(default)]
69 pub reactions: Option<Vec<Reaction>>,
70}
71
72/// A media attachment in a message.
73#[derive(Debug, Clone, Serialize, Deserialize)]
74pub struct MediaAttachment {
75 pub url: Option<String>,
76 pub path: Option<String>,
77 pub mime_type: Option<String>,
78 pub filename: Option<String>,
79 /// File size in bytes, when known.
80 #[serde(default)]
81 pub size: Option<u64>,
82}
83
84/// Options for sending a message with additional metadata.
85#[derive(Debug, Default)]
86pub struct SendOptions<'a> {
87 pub recipient: &'a str,
88 pub content: &'a str,
89 pub reply_to: Option<&'a str>,
90 /// Thread ID to send into (platforms that support threading).
91 pub thread_id: Option<&'a str>,
92 pub silent: bool,
93 pub media: Option<&'a str>,
94}