Skip to main content

rustigram_types/
story.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4/// A Telegram Story posted by a user or channel.
5pub struct Story {
6    /// The chat that posted the story.
7    pub chat: crate::chat::Chat,
8    /// Unique identifier of the story in that chat.
9    pub id: i64,
10}
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
13/// The position and size of a story area overlay.
14pub struct StoryAreaPosition {
15    /// Horizontal position as a percentage of the story width (0–100).
16    pub x_percentage: f64,
17    /// Vertical position as a percentage of the story height (0–100).
18    pub y_percentage: f64,
19    /// Width of the area as a percentage of the story width (0–100).
20    pub width_percentage: f64,
21    /// Height of the area as a percentage of the story height (0–100).
22    pub height_percentage: f64,
23    /// Rotation angle of the area in degrees (0–360).
24    pub rotation_angle: f64,
25    /// Corner radius of the area as a percentage of the shorter side (0–100).
26    pub corner_radius_percentage: f64,
27}
28
29/// The type of interactive area overlaid on a story.
30#[derive(Debug, Clone, Serialize, Deserialize)]
31#[serde(tag = "type", rename_all = "snake_case")]
32pub enum StoryAreaType {
33    /// An area pointing to a geographic location.
34    Location {
35        /// The geographic location.
36        location: crate::chat::Location,
37        /// Optional human-readable address.
38        address: Option<LocationAddress>,
39    },
40    /// An area for a suggested emoji reaction.
41    SuggestedReaction {
42        /// The reaction type.
43        reaction_type: crate::message::ReactionType,
44        /// `true` to display a dark background for the reaction.
45        is_dark: Option<bool>,
46        /// `true` to mirror the reaction emoji.
47        is_flipped: Option<bool>,
48    },
49    /// An area that links to a URL.
50    Link {
51        /// The URL to open.
52        url: String,
53    },
54    /// An area showing weather information.
55    Weather {
56        /// Temperature in Celsius.
57        temperature: f64,
58        /// Weather emoji.
59        emoji: String,
60        /// Background color as an ARGB integer.
61        background_color: i32,
62    },
63    /// An area highlighting a unique gift.
64    UniqueGift {
65        /// Name of the unique gift.
66        name: String,
67    },
68}
69
70/// A human-readable address associated with a location.
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct LocationAddress {
73    /// Two-letter ISO 3166-1 alpha-2 country code.
74    pub country_code: String,
75    /// State or region name.
76    pub state: Option<String>,
77    /// City name.
78    pub city: Option<String>,
79    /// Street name and number.
80    pub street: Option<String>,
81}
82
83#[derive(Debug, Clone, Serialize, Deserialize)]
84/// An interactive area overlaid on a story frame.
85///
86/// Areas can represent locations, reactions, links, weather widgets, or
87/// unique gift labels. Used when posting stories via the Business API.
88pub struct StoryArea {
89    /// Position and size of the area.
90    pub position: StoryAreaPosition,
91    /// Type and content of the area.
92    #[serde(rename = "type")]
93    pub kind: StoryAreaType,
94}
95
96// ─── InputStoryContent ────────────────────────────────────────────────────────
97
98/// A photo to post as a story.
99#[derive(Debug, Clone, Serialize, Deserialize)]
100pub struct InputStoryContentPhoto {
101    /// The photo to post.
102    ///
103    /// Must be 1080×1920 pixels, ≤10 MB.
104    /// Pass a `file_id`, HTTP URL, or `"attach://<name>"` for a multipart upload.
105    pub photo: String,
106}
107
108/// A video to post as a story.
109#[derive(Debug, Clone, Serialize, Deserialize)]
110pub struct InputStoryContentVideo {
111    /// The video to post.
112    ///
113    /// Must be 720×1280, streamable H.265, with key frames every second, ≤30 MB.
114    /// Pass a `file_id`, HTTP URL, or `"attach://<name>"` for a multipart upload.
115    pub video: String,
116    /// Precise duration of the video in seconds (0–60).
117    #[serde(skip_serializing_if = "Option::is_none")]
118    pub duration: Option<f64>,
119    /// Timestamp in seconds of the frame to use as the static cover. Defaults to `0.0`.
120    #[serde(skip_serializing_if = "Option::is_none")]
121    pub cover_frame_timestamp: Option<f64>,
122    /// Pass `true` if the video has no sound.
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub is_animation: Option<bool>,
125}
126
127/// The content of a story to post or edit.
128///
129/// Pass to [`postStory`](https://core.telegram.org/bots/api#poststory) and
130/// [`editStory`](https://core.telegram.org/bots/api#editstory) as a
131/// `serde_json::Value` — use `serde_json::to_value(&content)`.
132#[derive(Debug, Clone, Serialize, Deserialize)]
133#[serde(tag = "type", rename_all = "snake_case")]
134pub enum InputStoryContent {
135    /// A photo story.
136    Photo(InputStoryContentPhoto),
137    /// A video story.
138    Video(InputStoryContentVideo),
139}