1use itertools::Itertools;
2use serde::ser::{SerializeMap, Serializer};
3use serde::{Deserialize, Serialize};
4use thiserror::Error;
5
6#[derive(Debug, Deserialize)]
7pub struct MessageResponse {
8 errcode: u64,
9 errmsg: String,
10 pub invaliduser: Option<String>,
11 pub invalidparty: Option<String>,
12 pub invalidtag: Option<String>,
13}
14
15#[derive(Error, Debug)]
16pub enum MessageBuildError {
17 #[error("receiver can not be empty")]
18 EmptyReceiver,
19}
20
21pub struct MessageBuilder {
22 to_users: Vec<String>,
23 to_parties: Vec<String>,
24 to_tags: Vec<String>,
25 data: MessageType,
26 agent_id: u64,
27 safe: Option<bool>,
28 enable_id_trans: Option<bool>,
29 enable_duplicate_check: Option<bool>,
30 duplicate_check_interval: Option<u32>,
31}
32
33#[derive(Debug)]
34pub struct Message {
35 to_users: Vec<String>, to_parties: Vec<String>, to_tags: Vec<String>, data: MessageType, agent_id: u64, safe: Option<bool>, enable_id_trans: Option<bool>, enable_duplicate_check: Option<bool>, duplicate_check_interval: Option<u32>, }
45
46#[derive(Debug)]
47enum MessageType {
48 Text(Text),
49 File(File),
50 Image(Image),
51}
52
53#[derive(Debug, Serialize)]
54struct Text {
55 content: String,
56}
57
58#[derive(Debug, Serialize)]
59struct File {
60 media_id: String,
61}
62
63#[derive(Debug, Serialize)]
64struct Image {
65 media_id: String,
66}
67
68impl MessageBuilder {
69 fn new(agent_id: u64, ty: MessageType) -> Self {
70 MessageBuilder {
71 agent_id,
72 to_users: vec![],
73 to_parties: vec![],
74 to_tags: vec![],
75 data: ty,
76 safe: None,
77 enable_id_trans: None,
78 enable_duplicate_check: None,
79 duplicate_check_interval: None,
80 }
81 }
82 pub fn new_text(agent_id: u64, content: String) -> Self {
83 let data = MessageType::Text(Text { content });
84 Self::new(agent_id, data)
85 }
86
87 pub fn new_file(agent_id: u64, media_id: String) -> Self {
88 let data = MessageType::File(File { media_id });
89 Self::new(agent_id, data)
90 }
91
92 pub fn new_image(agent_id: u64, media_id: String) -> Self {
93 let data = MessageType::Image(Image { media_id });
94 Self::new(agent_id, data)
95 }
96
97 pub fn with_user(mut self, user: String) -> Self {
98 self.to_users.push(user);
99 self
100 }
101
102 pub fn with_party(mut self, party: String) -> Self {
103 self.to_parties.push(party);
104 self
105 }
106
107 pub fn with_tag(mut self, tag: String) -> Self {
108 self.to_tags.push(tag);
109 self
110 }
111
112 pub fn safe(mut self, flag: bool) -> Self {
113 self.safe = Some(flag);
114 self
115 }
116
117 pub fn enable_id_trans(mut self, flag: bool) -> Self {
118 self.enable_id_trans = Some(flag);
119 self
120 }
121
122 pub fn enable_duplicate_check(mut self, flag: bool) -> Self {
123 self.enable_duplicate_check = Some(flag);
124 self
125 }
126
127 pub fn duplicate_check_interval(mut self, duration: u32) -> Self {
128 self.duplicate_check_interval = Some(duration);
129 self
130 }
131
132 pub fn build(self) -> Result<Message, MessageBuildError> {
133 if self.to_users.is_empty() && self.to_parties.is_empty() && self.to_tags.is_empty() {
134 return Err(MessageBuildError::EmptyReceiver);
135 }
136
137 let ret = Message {
139 to_users: self.to_users,
140 to_parties: self.to_parties,
141 to_tags: self.to_tags,
142 data: self.data,
143 agent_id: self.agent_id,
144 safe: self.safe,
145 enable_id_trans: self.enable_id_trans,
146 enable_duplicate_check: self.enable_duplicate_check,
147 duplicate_check_interval: self.duplicate_check_interval,
148 };
149 Ok(ret)
150 }
151}
152
153impl Serialize for Message {
154 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
155 where
156 S: Serializer,
157 {
158 use MessageType::*;
159
160 let mut map = serializer.serialize_map(None)?;
161
162 map.serialize_entry("touser", &self.to_users.iter().join("|"))?;
163 map.serialize_entry("toparty", &self.to_parties.iter().join("|"))?;
164 map.serialize_entry("totag", &self.to_tags.iter().join("|"))?;
165 map.serialize_entry("agentid", &self.agent_id)?;
166
167 if let Some(d) = self.safe {
168 map.serialize_entry("safe", &(d as u8))?;
169 }
170 if let Some(d) = self.enable_id_trans {
171 map.serialize_entry("enable_id_trans", &(d as u8))?;
172 }
173 if let Some(d) = self.enable_duplicate_check {
174 map.serialize_entry("enable_duplicate_check", &(d as u8))?;
175 }
176 if let Some(d) = self.duplicate_check_interval {
177 map.serialize_entry("duplicate_check_interval", &d)?;
178 }
179
180 match &self.data {
181 Text(t) => {
182 map.serialize_entry("msgtype", "text")?;
183 map.serialize_entry("text", t)?;
184 }
185 File(t) => {
186 map.serialize_entry("msgtype", "file")?;
187 map.serialize_entry("file", t)?;
188 }
189 Image(t) => {
190 map.serialize_entry("msgtype", "image")?;
191 map.serialize_entry("image", t)?;
192 }
193 }
194
195 map.end()
196 }
197}