mutiny_rs/model/
message.rs

1//! Model relating to Stoat channels
2
3use crate::builders::create_embed::SendableEmbed;
4use crate::builders::edit_message::EditMessageBuilder;
5use crate::context::Context;
6use crate::http::HttpError;
7use crate::model::channel::{ChannelId};
8use crate::model::ready::Member;
9use crate::model::user::User;
10use serde::{Deserialize, Serialize};
11use crate::builders::create_message::CreateMessage;
12
13#[derive(Serialize, Default, Debug, Clone)]
14pub struct SendMessageBody {
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub content: Option<String>,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub nonce: Option<String>,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub attachments: Option<Vec<String>>,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub replies: Option<Vec<Replies>>,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub embeds: Option<Vec<SendableEmbed>>,
25}
26#[derive(Debug, Serialize, Clone, PartialEq)]
27pub enum Sort {
28    Relevance,
29    Latest,
30    Oldest,
31}
32
33#[derive(Debug, Serialize, Default, Clone)]
34pub struct FetchMessagesQuery {
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub limit: Option<usize>,
37
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub before: Option<String>,
40
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub after: Option<String>,
43
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub sort: Option<Sort>,
46
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub nearby: Option<String>,
49
50    #[serde(skip_serializing_if = "Option::is_none")]
51    pub include_users: Option<bool>,
52}
53#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
54pub enum MessageSort {
55    Relevance,
56    Latest,
57    Oldest,
58}
59
60#[derive(Debug, Serialize, Default, Clone)]
61pub struct SearchMessagesBody {
62    #[serde(skip_serializing_if = "Option::is_none")]
63    pub query: Option<String>,
64
65    #[serde(skip_serializing_if = "Option::is_none")]
66    pub limit: Option<usize>,
67
68    #[serde(skip_serializing_if = "Option::is_none")]
69    pub before: Option<String>,
70
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub after: Option<String>,
73
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub sort: Option<MessageSort>,
76
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub include_users: Option<bool>,
79
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub pinned: Option<bool>,
82}
83
84#[derive(Debug, Deserialize)]
85pub struct SearchResponse {
86    pub messages: Vec<Message>,
87    #[serde(default)]
88    pub users: Vec<User>,
89    #[serde(default)]
90    pub members: Vec<Member>,
91}
92
93#[derive(Debug, Serialize, Deserialize, Clone)]
94pub struct Message {
95    #[serde(rename = "_id")]
96    pub id: String,
97    pub nonce: Option<String>,
98    pub channel: ChannelId,
99    pub author: String,
100    pub user: Option<User>,
101    pub member: Option<Member>,
102    pub content: Option<String>,
103    pub mentions: Option<Vec<String>>,
104    pub attachments: Option<Vec<MessageAttachments>>,
105    pub edited: Option<String>
106}
107
108#[derive(Debug, Serialize, Deserialize, Clone)]
109pub struct MessageAttachments {
110    #[serde(rename = "_id")]
111    pub id: String,
112    pub tag: String,
113    pub filename: String,
114    pub metadata: MessageMetadata,
115    pub content_type: String,
116    pub size: usize
117}
118
119#[derive(Debug, Serialize, Deserialize, Clone)]
120pub struct MessageMetadata {
121    #[serde(rename = "type")]
122    pub _type: String,
123    pub width: usize,
124    pub height: usize,
125}
126
127#[derive(Debug, Serialize, Deserialize, Clone, Default)]
128pub struct Replies {
129    pub id: String,
130    pub mention: bool,
131    pub fail_if_not_exists: Option<bool>,
132}
133impl Replies {
134    pub fn new(message_id: String) -> Self {
135        Self {
136            id: message_id,
137            mention: true, // Default to true
138            fail_if_not_exists: Some(false),
139        }
140    }
141}
142impl Message {
143    /// Reply to the message object
144    pub async fn reply(&self, ctx: &Context, builder: CreateMessage) -> Result<Message, HttpError> {
145        let builder = builder.replies(Replies::new(self.id.clone()));
146        self.channel.send_message(ctx, builder).await
147    }
148    pub async fn pin(&self, ctx: &Context) -> Result<(), HttpError> {
149        let url = format!("/channels/{}/messages/{}/pin", self.channel.0, self.id);
150        ctx.http.post_empty(&url).await
151    }
152    pub async fn unpin(&self, ctx: &Context) -> Result<(), HttpError> {
153        let url = format!("/channels/{}/messages/{}/pin", self.channel.0, self.id);
154        ctx.http.delete(&url).await
155    }
156    pub async fn delete(&self, ctx: &Context) -> Result<(), HttpError> {
157        let url = format!("/channels/{}/messages/{}", self.channel.0, self.id);
158        ctx.cache.messages.remove(&self.id).await;
159        ctx.http.delete(&url).await
160    }
161    pub fn edit<'a>(&'a self, ctx: &'a Context) -> EditMessageBuilder<'a> {
162        EditMessageBuilder {
163            message: self,
164            ctx,
165            content: None,
166            embeds: None,
167        }
168    }
169}