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        /// Location latitude in degrees.
36        latitude: f64,
37        /// Location longitude in degrees.
38        longitude: f64,
39        /// Optional human-readable address.
40        #[serde(skip_serializing_if = "Option::is_none")]
41        address: Option<LocationAddress>,
42    },
43    /// An area for a suggested emoji reaction.
44    SuggestedReaction {
45        /// The reaction type.
46        reaction_type: crate::message::ReactionType,
47        /// `true` to display a dark background for the reaction.
48        #[serde(skip_serializing_if = "Option::is_none")]
49        is_dark: Option<bool>,
50        /// `true` to mirror the reaction emoji.
51        #[serde(skip_serializing_if = "Option::is_none")]
52        is_flipped: Option<bool>,
53    },
54    /// An area that links to a URL.
55    Link {
56        /// The URL to open.
57        url: String,
58    },
59    /// An area showing weather information.
60    Weather {
61        /// Temperature in Celsius.
62        temperature: f64,
63        /// Weather emoji.
64        emoji: String,
65        /// Background color as an ARGB integer.
66        background_color: i32,
67    },
68    /// An area highlighting a unique gift.
69    UniqueGift {
70        /// Name of the unique gift.
71        name: String,
72    },
73}
74
75/// A human-readable address associated with a location.
76#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct LocationAddress {
78    /// Two-letter ISO 3166-1 alpha-2 country code.
79    pub country_code: String,
80    /// State or region name.
81    #[serde(skip_serializing_if = "Option::is_none")]
82    pub state: Option<String>,
83    /// City name.
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub city: Option<String>,
86    /// Street name and number.
87    #[serde(skip_serializing_if = "Option::is_none")]
88    pub street: Option<String>,
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize)]
92/// An interactive area overlaid on a story frame.
93///
94/// Areas can represent locations, reactions, links, weather widgets, or
95/// unique gift labels. Used when posting stories via the Business API.
96pub struct StoryArea {
97    /// Position and size of the area.
98    pub position: StoryAreaPosition,
99    /// Type and content of the area.
100    #[serde(rename = "type")]
101    pub kind: StoryAreaType,
102}
103
104// ─── InputStoryContent ────────────────────────────────────────────────────────
105
106/// A photo to post as a story.
107#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct InputStoryContentPhoto {
109    /// The photo to post.
110    ///
111    /// Must be 1080×1920 pixels, ≤10 MB.
112    /// Pass a `file_id`, HTTP URL, or `"attach://<name>"` for a multipart upload.
113    pub photo: String,
114}
115
116/// A video to post as a story.
117#[derive(Debug, Clone, Serialize, Deserialize)]
118pub struct InputStoryContentVideo {
119    /// The video to post.
120    ///
121    /// Must be 720×1280, streamable H.265, with key frames every second, ≤30 MB.
122    /// Pass a `file_id`, HTTP URL, or `"attach://<name>"` for a multipart upload.
123    pub video: String,
124    /// Precise duration of the video in seconds (0–60).
125    #[serde(skip_serializing_if = "Option::is_none")]
126    pub duration: Option<f64>,
127    /// Timestamp in seconds of the frame to use as the static cover. Defaults to `0.0`.
128    #[serde(skip_serializing_if = "Option::is_none")]
129    pub cover_frame_timestamp: Option<f64>,
130    /// Pass `true` if the video has no sound.
131    #[serde(skip_serializing_if = "Option::is_none")]
132    pub is_animation: Option<bool>,
133}
134
135/// The content of a story to post or edit.
136///
137/// Pass to [`postStory`](https://core.telegram.org/bots/api#poststory) and
138/// [`editStory`](https://core.telegram.org/bots/api#editstory) as a
139/// `serde_json::Value` — use `serde_json::to_value(&content)`.
140#[derive(Debug, Clone, Serialize, Deserialize)]
141#[serde(tag = "type", rename_all = "snake_case")]
142pub enum InputStoryContent {
143    /// A photo story.
144    Photo(InputStoryContentPhoto),
145    /// A video story.
146    Video(InputStoryContentVideo),
147}