tgbot/types/definitions/suggested_post.rs
1use std::{error, fmt};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 api::{Method, Payload},
7 types::{Integer, Message, StarAmount},
8};
9
10/// Approves a suggested post in a direct messages chat.
11///
12/// The bot must have the 'can_post_messages' administrator right in the corresponding channel chat.
13#[serde_with::skip_serializing_none]
14#[derive(Clone, Debug, Serialize)]
15pub struct ApproveSuggestedPost {
16 chat_id: Integer,
17 message_id: Integer,
18 send_date: Option<Integer>,
19}
20
21impl ApproveSuggestedPost {
22 /// Creates a new `ApproveSuggestedPost`.
23 ///
24 /// # Arguments
25 ///
26 /// * `chat_id` - Unique identifier for the target direct messages chat
27 /// * `message_id` - Identifier of a suggested post message to approve
28 pub fn new(chat_id: Integer, message_id: Integer) -> Self {
29 Self {
30 chat_id,
31 message_id,
32 send_date: None,
33 }
34 }
35
36 /// Sets a new send date.
37 ///
38 /// # Arguments
39 ///
40 /// * `value` - Point in time (Unix timestamp) when the post is expected to be published.
41 ///
42 /// Omit if the date has already been specified when the suggested post was created.
43 ///
44 /// If specified, then the date must be not more than 2678400 seconds (30 days) in the future.
45 pub fn with_send_date(mut self, value: Integer) -> Self {
46 self.send_date = Some(value);
47 self
48 }
49}
50
51impl Method for ApproveSuggestedPost {
52 type Response = bool;
53
54 fn into_payload(self) -> Payload {
55 Payload::json("approveSuggestedPost", self)
56 }
57}
58
59/// Declines a suggested post in a direct messages chat.
60///
61/// The bot must have the 'can_manage_direct_messages' administrator right in the corresponding channel chat.
62#[serde_with::skip_serializing_none]
63#[derive(Clone, Debug, Serialize)]
64pub struct DeclineSuggestedPost {
65 chat_id: Integer,
66 message_id: Integer,
67 comment: Option<String>,
68}
69
70impl DeclineSuggestedPost {
71 /// Creates a new `DeclineSuggestedPost`.
72 ///
73 /// # Arguments
74 ///
75 /// * `chat_id` - Unique identifier for the target direct messages chat
76 /// * `message_id` - Identifier of a suggested post message to decline
77 pub fn new(chat_id: Integer, message_id: Integer) -> Self {
78 Self {
79 chat_id,
80 message_id,
81 comment: None,
82 }
83 }
84
85 /// Sets a new comment.
86 ///
87 /// # Arguments
88 ///
89 /// * `value` - Comment for the creator of the suggested post; 0-128 characters.
90 pub fn with_comment<T>(mut self, value: T) -> Self
91 where
92 T: Into<String>,
93 {
94 self.comment = Some(value.into());
95 self
96 }
97}
98
99impl Method for DeclineSuggestedPost {
100 type Response = bool;
101
102 fn into_payload(self) -> Payload {
103 Payload::json("declineSuggestedPost", self)
104 }
105}
106
107/// Describes a service message about the approval of a suggested post.
108#[serde_with::skip_serializing_none]
109#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
110pub struct SuggestedPostApproved {
111 /// Date when the post will be published.
112 pub send_date: Integer,
113 /// Amount paid for the post.
114 pub price: Option<SuggestedPostPrice>,
115 /// Message containing the suggested post.
116 ///
117 /// Note that the Message object in this field will not contain the reply_to_message field
118 /// even if it itself is a reply.
119 pub suggested_post_message: Option<Box<Message>>,
120}
121
122impl SuggestedPostApproved {
123 /// Creates a new `SuggestedPostApproved`.
124 ///
125 /// # Arguments
126 ///
127 /// * `send_date` - Date when the post will be published.
128 pub fn new(send_date: Integer) -> Self {
129 Self {
130 send_date,
131 price: None,
132 suggested_post_message: None,
133 }
134 }
135
136 /// Sets a new price.
137 ///
138 /// # Arguments
139 ///
140 /// * `value` - Amount paid for the post.
141 pub fn with_price(mut self, value: SuggestedPostPrice) -> Self {
142 self.price = Some(value);
143 self
144 }
145
146 /// Sets a new suggested post message.
147 ///
148 /// # Arguments
149 ///
150 /// * `value` - Message containing the suggested post.
151 pub fn with_suggested_post_message(mut self, value: Message) -> Self {
152 self.suggested_post_message = Some(Box::new(value));
153 self
154 }
155}
156
157/// Describes a service message about the failed approval of a suggested post.
158///
159/// Currently, only caused by insufficient user funds at the time of approval.
160#[serde_with::skip_serializing_none]
161#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
162pub struct SuggestedPostApprovalFailed {
163 /// Expected price of the post.
164 pub price: SuggestedPostPrice,
165 /// Message containing the suggested post whose approval has failed.
166 ///
167 /// Note that the Message object in this field will not contain the reply_to_message field
168 /// even if it itself is a reply.
169 pub suggested_post_message: Option<Box<Message>>,
170}
171
172impl SuggestedPostApprovalFailed {
173 /// Creates a new `SuggestedPostApprovalFailed`.
174 ///
175 /// # Arguments
176 ///
177 /// * `price` - Expected price of the post.
178 pub fn new(price: SuggestedPostPrice) -> Self {
179 Self {
180 price,
181 suggested_post_message: None,
182 }
183 }
184
185 /// Sets a new suggested post message.
186 ///
187 /// # Arguments
188 ///
189 /// * `value` - Message containing the suggested post.
190 pub fn with_suggested_post_message(mut self, value: Message) -> Self {
191 self.suggested_post_message = Some(Box::new(value));
192 self
193 }
194}
195
196/// Describes a service message about the rejection of a suggested post.
197#[serde_with::skip_serializing_none]
198#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
199pub struct SuggestedPostDeclined {
200 /// Comment with which the post was declined.
201 pub comment: Option<String>,
202 /// Message containing the suggested post.
203 ///
204 /// Note that the Message object in this field will not contain the reply_to_message field
205 /// even if it itself is a reply.
206 pub suggested_post_message: Option<Box<Message>>,
207}
208
209impl SuggestedPostDeclined {
210 /// Sets a new comment.
211 ///
212 /// # Arguments
213 ///
214 /// * `value` - Comment with which the post was declined.
215 pub fn with_comment<T>(mut self, value: T) -> Self
216 where
217 T: Into<String>,
218 {
219 self.comment = Some(value.into());
220 self
221 }
222
223 /// Sets a new suggested post message.
224 ///
225 /// # Arguments
226 ///
227 /// * `value` - Message containing the suggested post.
228 pub fn with_suggested_post_message(mut self, value: Message) -> Self {
229 self.suggested_post_message = Some(Box::new(value));
230 self
231 }
232}
233
234/// Contains information about a suggested post.
235#[serde_with::skip_serializing_none]
236#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
237pub struct SuggestedPostInfo {
238 /// State of the suggested post.
239 pub state: SuggestedPostState,
240 /// Proposed price of the post.
241 ///
242 /// If the field is omitted, then the post is unpaid.
243 pub price: Option<SuggestedPostPrice>,
244 /// Proposed send date of the post.
245 ///
246 /// If the field is omitted, then the post can be published at any time within 30 days
247 /// at the sole discretion of the user or administrator who approves it.
248 pub send_date: Option<Integer>,
249}
250
251impl SuggestedPostInfo {
252 /// Creates a new `SuggestedPostInfo`.
253 ///
254 /// # Arguments
255 ///
256 /// * `state` - State of the suggested post.
257 pub fn new(state: SuggestedPostState) -> Self {
258 Self {
259 state,
260 price: None,
261 send_date: None,
262 }
263 }
264
265 /// Sets a new price.
266 ///
267 /// # Arguments
268 ///
269 /// * `value` - Proposed price of the post.
270 pub fn with_price(mut self, value: SuggestedPostPrice) -> Self {
271 self.price = Some(value);
272 self
273 }
274
275 /// Sets a new send date.
276 ///
277 /// # Arguments
278 ///
279 /// * `value` - Proposed send date of the post.
280 pub fn with_send_date(mut self, value: Integer) -> Self {
281 self.send_date = Some(value);
282 self
283 }
284}
285
286/// Describes a service message about a successful payment for a suggested post.
287#[serde_with::skip_serializing_none]
288#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
289pub struct SuggestedPostPaid {
290 /// Currency in which the payment was made.
291 ///
292 /// Currently, one of “XTR” for Telegram Stars or “TON” for toncoins
293 pub currency: String,
294 /// The amount of the currency that was received by the channel in nanotoncoins; for payments in toncoins only.
295 pub amount: Option<Integer>,
296 /// The amount of Telegram Stars that was received by the channel; for payments in Telegram Stars only.
297 pub star_amount: Option<StarAmount>,
298 /// Message containing the suggested post.
299 ///
300 /// Note that the Message object in this field will not contain the reply_to_message field even if it itself is a reply.
301 pub suggested_post_message: Option<Box<Message>>,
302}
303
304impl SuggestedPostPaid {
305 /// Creates a new `SuggestedPostPaid`.
306 ///
307 /// # Arguments
308 ///
309 /// * `currency` - Currency in which the payment was made.
310 pub fn new<T>(currency: T) -> Self
311 where
312 T: Into<String>,
313 {
314 Self {
315 currency: currency.into(),
316 amount: None,
317 star_amount: None,
318 suggested_post_message: None,
319 }
320 }
321
322 /// Sets a new amount.
323 ///
324 /// # Arguments
325 ///
326 /// * `value` - The amount of the currency that was received by the channel in nanotoncoins.
327 pub fn with_amount(mut self, value: Integer) -> Self {
328 self.amount = Some(value);
329 self
330 }
331
332 /// Sets a new star amount.
333 ///
334 /// # Arguments
335 ///
336 /// * `value` - The amount of Telegram Stars that was received by the channel.
337 pub fn with_star_amount<T>(mut self, value: T) -> Self
338 where
339 T: Into<StarAmount>,
340 {
341 self.star_amount = Some(value.into());
342 self
343 }
344
345 /// Sets a new suggested post message.
346 ///
347 /// # Arguments
348 ///
349 /// * `value` - Message containing the suggested post.
350 pub fn with_suggested_post_message(mut self, value: Message) -> Self {
351 self.suggested_post_message = Some(Box::new(value));
352 self
353 }
354}
355
356/// Contains parameters of a post that is being suggested by the bot.
357#[serde_with::skip_serializing_none]
358#[derive(Clone, Debug, Default, Deserialize, PartialEq, PartialOrd, Serialize)]
359pub struct SuggestedPostParameters {
360 /// Proposed price for the post.
361 ///
362 /// If the field is omitted, then the post is unpaid.
363 pub price: Option<SuggestedPostPrice>,
364 /// Proposed send date of the post.
365 ///
366 /// If specified, then the date must be between 300 second and 2678400 seconds (30 days) in the future.
367 ///
368 /// If the field is omitted, then the post can be published at any time within 30 days
369 /// at the sole discretion of the user who approves it.
370 pub send_date: Option<Integer>,
371}
372
373impl SuggestedPostParameters {
374 /// Sets a new price.
375 ///
376 /// # Arguments
377 ///
378 /// * `value` - Proposed price for the post.
379 pub fn with_price(mut self, value: SuggestedPostPrice) -> Self {
380 self.price = Some(value);
381 self
382 }
383
384 /// Sets a new send date.
385 ///
386 /// # Arguments
387 ///
388 /// * `value` - Proposed send date of the post.
389 pub fn with_send_date(mut self, value: Integer) -> Self {
390 self.send_date = Some(value);
391 self
392 }
393}
394
395/// An error for suggested post parameters.
396#[derive(Debug)]
397pub enum SuggestedPostParametersError {
398 /// Can not serialize the parameters.
399 Serialize(serde_json::Error),
400}
401
402impl fmt::Display for SuggestedPostParametersError {
403 fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
404 match self {
405 Self::Serialize(err) => write!(out, "can not serialize parameters: {err}"),
406 }
407 }
408}
409
410impl error::Error for SuggestedPostParametersError {
411 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
412 Some(match self {
413 Self::Serialize(err) => err,
414 })
415 }
416}
417
418/// Desribes price of a suggested post.
419#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
420pub struct SuggestedPostPrice {
421 /// The amount of the currency that will be paid for the post in the smallest units of the currency
422 /// i.e. Telegram Stars or nanotoncoins.
423 ///
424 /// Currently, price in Telegram Stars must be between 5 and 100000,
425 /// and price in nanotoncoins must be between 10000000 and 10000000000000.
426 pub amount: Integer,
427 /// Currency in which the post will be paid.
428 ///
429 /// Currently, must be one of “XTR” for Telegram Stars or “TON” for toncoins.
430 pub currency: String,
431}
432
433impl SuggestedPostPrice {
434 /// Creates a new `SuggestedPostPrice`.
435 ///
436 /// # Arguments
437 ///
438 /// * `amount` - The amount of the currency that will be paid for the post in the smallest units of the currency.
439 /// * `currency` - Currency in which the post will be paid.
440 pub fn new<T>(amount: Integer, currency: T) -> Self
441 where
442 T: Into<String>,
443 {
444 Self {
445 amount,
446 currency: currency.into(),
447 }
448 }
449}
450
451/// Describes a service message about a payment refund for a suggested post.
452#[serde_with::skip_serializing_none]
453#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
454pub struct SuggestedPostRefunded {
455 /// Reason for the refund.
456 pub reason: SuggestedPostRefundReason,
457 /// Message containing the suggested post.
458 ///
459 /// Note that the Message object in this field will not contain the reply_to_message field
460 /// even if it itself is a reply.
461 pub suggested_post_message: Option<Box<Message>>,
462}
463
464impl SuggestedPostRefunded {
465 /// Creates a new `SuggestedPostRefunded`.
466 ///
467 /// # Arguments
468 ///
469 /// * `reason` - Reason for the refund.
470 pub fn new(reason: SuggestedPostRefundReason) -> Self {
471 Self {
472 reason,
473 suggested_post_message: None,
474 }
475 }
476
477 /// Sets a new suggested post message.
478 ///
479 /// # Arguments
480 ///
481 /// * `value` - Message containing the suggested post.
482 pub fn with_suggested_post_message(mut self, value: Message) -> Self {
483 self.suggested_post_message = Some(Box::new(value));
484 self
485 }
486}
487
488/// Reason for the refund.
489#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
490#[serde(rename_all = "snake_case")]
491pub enum SuggestedPostRefundReason {
492 /// The post was deleted within 24 hours of being posted
493 /// or removed from scheduled messages without being posted.
494 PostDeleted,
495 /// The payer refunded their payment.
496 PaymentRefunded,
497}
498
499/// State of a suggested post.
500#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
501#[serde(rename_all = "snake_case")]
502pub enum SuggestedPostState {
503 /// The post is approved.
504 Approved,
505 /// The post is declined.
506 Declined,
507 /// The post is waiting for approval.
508 Pending,
509}