tweety_rs/api/
mentions.rs

1use crate::api::error::TweetyError;
2use crate::{api::client::TweetyClient, types::types::ResponseWithHeaders};
3use reqwest::Method;
4use serde::{Deserialize, Serialize};
5use serde_qs::to_string as convert_query_to_string;
6
7#[derive(Debug, Serialize, Deserialize)]
8#[serde(rename_all = "snake_case")]
9pub struct QueryParams {
10    pub end_time: Option<String>,               // ISO 8601 date string
11    pub expansions: Option<Vec<ExpansionType>>, // List of enum values
12    pub max_results: Option<u32>,               // Integer for max results, min 5, max 100
13    pub media_fields: Option<Vec<MediaField>>,  // List of enum values
14    pub pagination_token: Option<String>,       // String for pagination token
15    pub place_fields: Option<Vec<PlaceField>>,  // List of enum values
16    pub poll_fields: Option<Vec<PollField>>,    // List of enum values
17    pub since_id: Option<String>,               // String for since_id (Tweet ID)
18    pub start_time: Option<String>,             // ISO 8601 date string
19    pub tweet_fields: Option<Vec<TweetField>>,  // List of enum values
20    pub until_id: Option<String>,               // String for until_id (Tweet ID)
21    pub user_fields: Option<Vec<UserField>>,    // List of enum values
22}
23
24// Enum for the `expansions` parameter
25#[derive(Debug, Serialize, Deserialize)]
26#[serde(rename_all = "snake_case")]
27pub enum ExpansionType {
28    AttachmentsPollIds,
29    AttachmentsMediaKeys,
30    AuthorId,
31    EditHistoryTweetIds,
32    EntitiesMentionsUsername,
33    GeoPlaceId,
34    InReplyToUserId,
35    ReferencedTweetsId,
36    ReferencedTweetsIdAuthorId,
37}
38
39// Enum for the `media_fields` parameter
40#[derive(Debug, Serialize, Deserialize)]
41#[serde(rename_all = "snake_case")]
42pub enum MediaField {
43    DurationMs,
44    Height,
45    MediaKey,
46    PreviewImageUrl,
47    Type,
48    Url,
49    Width,
50    PublicMetrics,
51    NonPublicMetrics,
52    OrganicMetrics,
53    PromotedMetrics,
54    AltText,
55    Variants,
56}
57
58// Enum for the `place_fields` parameter
59#[derive(Debug, Serialize, Deserialize)]
60#[serde(rename_all = "snake_case")]
61pub enum PlaceField {
62    ContainedWithin,
63    Country,
64    CountryCode,
65    FullName,
66    Geo,
67    Id,
68    Name,
69    PlaceType,
70}
71
72// Enum for the `poll_fields` parameter
73#[derive(Debug, Serialize, Deserialize)]
74#[serde(rename_all = "snake_case")]
75pub enum PollField {
76    DurationMinutes,
77    EndDatetime,
78    Id,
79    Options,
80    VotingStatus,
81}
82
83// Enum for the `tweet_fields` parameter
84#[derive(Debug, Serialize, Deserialize)]
85#[serde(rename_all = "snake_case")]
86pub enum TweetField {
87    Attachments,
88    AuthorId,
89    ContextAnnotations,
90    ConversationId,
91    CreatedAt,
92    EditControls,
93    Entities,
94    Geo,
95    Id,
96    InReplyToUserId,
97    Lang,
98    NonPublicMetrics,
99    PublicMetrics,
100    OrganicMetrics,
101    PromotedMetrics,
102    PossiblySensitive,
103    ReferencedTweets,
104    ReplySettings,
105    Source,
106    Text,
107    Withheld,
108}
109
110// Enum for the `user_fields` parameter
111#[derive(Debug, Serialize, Deserialize)]
112#[serde(rename_all = "snake_case")]
113pub enum UserField {
114    CreatedAt,
115    Description,
116    Entities,
117    Id,
118    Location,
119    MostRecentTweetId,
120    Name,
121    PinnedTweetId,
122    ProfileImageUrl,
123    Protected,
124    PublicMetrics,
125    Url,
126    Username,
127    Verified,
128    VerifiedType,
129    Withheld,
130}
131
132// Root Response Struct
133#[derive(Debug, Serialize, Deserialize)]
134pub struct MentionsResponse {
135    pub data: Vec<TweetData>,       // Required field for tweet data
136    pub includes: Option<Includes>, // Optional field for included related data
137    pub meta: MetaData,             // Required field for metadata
138}
139
140// Struct for each Tweet in "data"
141#[derive(Debug, Serialize, Deserialize)]
142pub struct TweetData {
143    pub author_id: String,                   // Required field for author ID
144    pub text: String,                        // Required field for tweet text
145    pub lang: String,                        // Required field for language
146    pub conversation_id: String,             // Required field for conversation ID
147    pub edit_history_tweet_ids: Vec<String>, // Required field for edit history tweet IDs
148    pub id: String,                          // Required field for tweet ID
149}
150
151// Struct for "includes"
152#[derive(Debug, Serialize, Deserialize)]
153pub struct Includes {
154    pub users: Vec<UserData>, // Optional field for included users data
155}
156
157// Struct for each User in "includes.users"
158#[derive(Debug, Serialize, Deserialize)]
159pub struct UserData {
160    pub name: String,                   // Required field for user name
161    pub id: String,                     // Required field for user ID
162    pub entities: Option<UserEntities>, // Optional field for user entities
163    pub username: String,               // Required field for user username
164    pub created_at: Option<String>,     // Optional field for user creation time (ISO 8601)
165}
166
167// Struct for "entities" in UserData
168#[derive(Debug, Serialize, Deserialize)]
169pub struct UserEntities {
170    pub url: Option<UrlEntity>, // Optional field for URL entities
171    pub description: Option<DescriptionEntity>, // Optional field for description entities
172}
173
174// Struct for "url" in UserEntities
175#[derive(Debug, Serialize, Deserialize)]
176pub struct UrlEntity {
177    pub urls: Vec<UrlDetail>, // Required field for URLs
178}
179
180// Struct for each URL in "url.urls"
181#[derive(Debug, Serialize, Deserialize)]
182pub struct UrlDetail {
183    pub start: u32,           // Required field for start position
184    pub end: u32,             // Required field for end position
185    pub url: String,          // Required field for URL
186    pub expanded_url: String, // Required field for expanded URL
187    pub display_url: String,  // Required field for display URL
188}
189
190// Struct for "description" in UserEntities
191#[derive(Debug, Serialize, Deserialize)]
192pub struct DescriptionEntity {
193    pub urls: Option<Vec<UrlDetail>>, // Optional field for URLs in description
194    pub hashtags: Option<Vec<Hashtag>>, // Optional field for hashtags in description
195    pub mentions: Option<Vec<Mention>>, // Optional field for mentions in description
196    pub cashtags: Option<Vec<Cashtag>>, // Optional field for cashtags in description
197}
198
199// Struct for each hashtag in DescriptionEntity
200#[derive(Debug, Serialize, Deserialize)]
201pub struct Hashtag {
202    pub start: u32,  // Required field for start position
203    pub end: u32,    // Required field for end position
204    pub tag: String, // Required field for hashtag
205}
206
207// Struct for each mention in DescriptionEntity
208#[derive(Debug, Serialize, Deserialize)]
209pub struct Mention {
210    pub start: u32,       // Required field for start position
211    pub end: u32,         // Required field for end position
212    pub username: String, // Required field for username
213}
214
215// Struct for each cashtag in DescriptionEntity
216#[derive(Debug, Serialize, Deserialize)]
217pub struct Cashtag {
218    pub start: u32,  // Required field for start position
219    pub end: u32,    // Required field for end position
220    pub tag: String, // Required field for cashtag
221}
222
223// Struct for "meta" in the response
224#[derive(Debug, Serialize, Deserialize)]
225pub struct MetaData {
226    pub oldest_id: String,          // Required field for oldest tweet ID
227    pub newest_id: String,          // Required field for newest tweet ID
228    pub result_count: u32,          // Required field for result count
229    pub next_token: Option<String>, // Optional field for pagination token
230}
231
232impl TweetyClient {
233    /// Authentication methods
234    /// supported by this endpoint
235    /// OAuth 1.0a is also available for this endpoint.
236    /// OAuth 2.0 Authorization Code with PKCE
237    /// OAuth 2.0 App-only
238    /// [Docs](https://developer.x.com/en/docs/x-api/tweets/timelines/api-reference/get-users-id-mentions)
239    pub async fn get_users_mentions(
240        &self,
241        user_id: &str,
242        query_params: Option<QueryParams>,
243    ) -> Result<ResponseWithHeaders, TweetyError> {
244        let mut base_url = format!("https://api.x.com/2/users/{}/mentions", user_id);
245        if let Some(queries) = query_params {
246            let query_params = convert_query_to_string(&queries).unwrap();
247            base_url = format!("{}?{}", base_url, query_params);
248        }
249        match self.send_request::<()>(&base_url, Method::GET, None).await {
250            Ok(value) => Ok(value),
251            Err(err) => Err(TweetyError::ApiError(err.to_string())),
252        }
253    }
254}