Skip to main content

threads_rs/
constants.rs

1use std::time::Duration;
2
3// --- Text limits ---
4
5/// Maximum characters for post text.
6pub const MAX_TEXT_LENGTH: usize = 500;
7
8/// Maximum characters for text attachment plaintext.
9pub const MAX_TEXT_ATTACHMENT_LENGTH: usize = 10_000;
10
11/// Maximum text spoiler entities per post.
12pub const MAX_TEXT_ENTITIES: usize = 10;
13
14/// Maximum number of links in a post.
15pub const MAX_LINKS: usize = 5;
16
17// --- Pagination limits ---
18
19/// Maximum posts per API request.
20pub const MAX_POSTS_PER_REQUEST: usize = 100;
21
22/// Default number of posts if not specified.
23pub const DEFAULT_POSTS_LIMIT: usize = 25;
24
25// --- Carousel limits ---
26
27/// Minimum items in a carousel.
28pub const MIN_CAROUSEL_ITEMS: usize = 2;
29
30/// Maximum items in a carousel.
31pub const MAX_CAROUSEL_ITEMS: usize = 20;
32
33// --- Reply processing ---
34
35/// Recommended delay before publishing reply.
36pub const REPLY_PUBLISH_DELAY: Duration = Duration::from_secs(10);
37
38// --- Poll limits ---
39
40/// Minimum number of poll options.
41pub const MIN_POLL_OPTIONS: usize = 2;
42
43/// Maximum number of poll options.
44pub const MAX_POLL_OPTIONS: usize = 4;
45
46/// Maximum characters per poll option.
47pub const MAX_POLL_OPTION_LENGTH: usize = 25;
48
49// --- Topic tag limits ---
50
51/// Maximum characters for a topic tag.
52pub const MAX_TOPIC_TAG_LENGTH: usize = 50;
53
54// --- Alt text limits ---
55
56/// Maximum characters for alt text on media.
57pub const MAX_ALT_TEXT_LENGTH: usize = 1000;
58
59// --- Search constraints ---
60
61/// Minimum timestamp for search queries (July 5, 2023).
62pub const MIN_SEARCH_TIMESTAMP: i64 = 1_688_540_400;
63
64// --- Library version ---
65
66/// Library version string from Cargo.toml.
67pub const VERSION: &str = env!("CARGO_PKG_VERSION");
68
69// --- HTTP client defaults ---
70
71/// Default HTTP request timeout.
72pub const DEFAULT_HTTP_TIMEOUT: Duration = Duration::from_secs(30);
73
74// --- API Endpoints ---
75
76/// Base URL for the Threads Graph API.
77pub const BASE_API_URL: &str = "https://graph.threads.net";
78
79// --- Field sets for API requests ---
80
81/// Default field set for post queries.
82pub const POST_EXTENDED_FIELDS: &str = "id,media_product_type,media_type,media_url,permalink,owner,username,text,timestamp,shortcode,thumbnail_url,children,is_quote_post,alt_text,link_attachment_url,has_replies,reply_audience,quoted_post,reposted_post,gif_url,is_verified,profile_picture_url,poll_attachment,topic_tag,is_spoiler_media,text_entities,text_attachment,location_id,location,allowlisted_country_codes,ghost_post_status,ghost_post_expiration_timestamp,is_reply,root_post,replied_to,is_reply_owned_by_me,hide_status,reply_approval_status";
83
84/// Field set for ghost/ephemeral post queries.
85pub const GHOST_POST_FIELDS: &str = "id,media_product_type,media_type,media_url,permalink,owner,username,text,timestamp,shortcode,thumbnail_url,ghost_post_status,ghost_post_expiration_timestamp";
86
87/// Field set for user profile queries.
88pub const USER_PROFILE_FIELDS: &str = "id,username,name,threads_profile_picture_url,threads_biography,is_verified,is_eligible_for_geo_gating,recently_searched_keywords";
89
90/// Field set for reply queries (`/{media-id}/replies` and `/{media-id}/conversation`).
91pub const REPLY_FIELDS: &str = "id,media_product_type,media_type,media_url,permalink,username,text,timestamp,shortcode,thumbnail_url,children,is_quote_post,has_replies,root_post,replied_to,is_reply,is_reply_owned_by_me,reply_audience,quoted_post,reposted_post,gif_url,hide_status,topic_tag,is_verified,profile_picture_url";
92
93/// Field set for pending reply queries (`/{media-id}/pending_replies`).
94/// Includes `reply_approval_status` and `alt_text` which are only valid for pending replies.
95pub const PENDING_REPLY_FIELDS: &str = "id,media_product_type,media_type,media_url,permalink,username,text,timestamp,shortcode,thumbnail_url,children,is_quote_post,has_replies,root_post,replied_to,is_reply,is_reply_owned_by_me,reply_audience,quoted_post,reposted_post,gif_url,alt_text,hide_status,topic_tag,is_verified,profile_picture_url,reply_approval_status";
96
97/// Field set for public user profile queries.
98pub const PUBLIC_USER_FIELDS: &str = "username,name,profile_picture_url,biography,is_verified,follower_count,likes_count,quotes_count,replies_count,reposts_count,views_count";
99
100/// Field set for container status queries.
101pub const CONTAINER_STATUS_FIELDS: &str = "id,status,error_message";
102
103/// Field set for location queries.
104pub const LOCATION_FIELDS: &str = "id,address,name,city,country,latitude,longitude,postal_code";
105
106/// Field set for publishing limit queries.
107pub const PUBLISHING_LIMIT_FIELDS: &str = "quota_usage,config,reply_quota_usage,reply_config,delete_quota_usage,delete_config,location_search_quota_usage,location_search_config";
108
109// --- Container status values ---
110
111/// Container status: upload in progress.
112pub const CONTAINER_STATUS_IN_PROGRESS: &str = "IN_PROGRESS";
113/// Container status: upload finished, ready to publish.
114pub const CONTAINER_STATUS_FINISHED: &str = "FINISHED";
115/// Container status: published.
116pub const CONTAINER_STATUS_PUBLISHED: &str = "PUBLISHED";
117/// Container status: error occurred.
118pub const CONTAINER_STATUS_ERROR: &str = "ERROR";
119/// Container status: expired.
120pub const CONTAINER_STATUS_EXPIRED: &str = "EXPIRED";
121
122/// Maximum number of polling attempts for container status.
123/// Documentation recommends querying once per minute for no more than 5 minutes.
124pub const DEFAULT_CONTAINER_POLL_MAX_ATTEMPTS: u32 = 5;
125
126/// Interval between polling attempts.
127/// Documentation recommends querying once per minute.
128pub const DEFAULT_CONTAINER_POLL_INTERVAL: Duration = Duration::from_secs(60);
129
130// --- Media types ---
131
132/// Media type constant for text posts.
133pub const MEDIA_TYPE_TEXT: &str = "TEXT";
134/// Media type constant for image posts.
135pub const MEDIA_TYPE_IMAGE: &str = "IMAGE";
136/// Media type constant for video posts.
137pub const MEDIA_TYPE_VIDEO: &str = "VIDEO";
138/// Media type constant for carousel posts.
139pub const MEDIA_TYPE_CAROUSEL: &str = "CAROUSEL";
140/// Media type constant for audio posts.
141pub const MEDIA_TYPE_AUDIO: &str = "AUDIO";
142/// Media type constant for repost facade.
143pub const MEDIA_TYPE_REPOST_FACADE: &str = "REPOST_FACADE";
144/// Media type constant for text post responses.
145pub const MEDIA_TYPE_RESPONSE_TEXT: &str = "TEXT_POST";
146/// Media type constant for carousel album responses.
147pub const MEDIA_TYPE_RESPONSE_CAROUSEL: &str = "CAROUSEL_ALBUM";
148
149// --- Error messages ---
150
151/// Validation error message: post ID required.
152pub const ERR_EMPTY_POST_ID: &str = "Post ID is required";
153/// Validation error message: user ID required.
154pub const ERR_EMPTY_USER_ID: &str = "User ID is required";
155/// Validation error message: container ID required.
156pub const ERR_EMPTY_CONTAINER_ID: &str = "Container ID is required";
157/// Validation error message: search query required.
158pub const ERR_EMPTY_SEARCH_QUERY: &str = "Search query is required";
159
160// --- API Error Codes ---
161
162/// Returned when a post contains more than 5 unique links.
163pub const ERR_CODE_LINK_LIMIT_EXCEEDED: &str = "THREADS_API__LINK_LIMIT_EXCEEDED";
164/// Returned when a feature is not available.
165pub const ERR_CODE_FEATURE_NOT_AVAILABLE: &str = "THREADS_API__FEATURE_NOT_AVAILABLE";
166/// Returned when geo-gating country codes are invalid.
167pub const ERR_CODE_GEO_GATING_INVALID_COUNTRY_CODES: &str =
168    "THREADS_API__GEO_GATING_INVALID_COUNTRY_CODES";
169
170// --- Container error messages ---
171
172/// Container error: failed downloading video.
173pub const CONTAINER_ERR_FAILED_DOWNLOADING_VIDEO: &str = "FAILED_DOWNLOADING_VIDEO";
174/// Container error: failed processing audio.
175pub const CONTAINER_ERR_FAILED_PROCESSING_AUDIO: &str = "FAILED_PROCESSING_AUDIO";
176/// Container error: failed processing video.
177pub const CONTAINER_ERR_FAILED_PROCESSING_VIDEO: &str = "FAILED_PROCESSING_VIDEO";
178/// Container error: invalid aspect ratio.
179pub const CONTAINER_ERR_INVALID_ASPECT_RATIO: &str = "INVALID_ASPEC_RATIO";
180/// Container error: invalid bit rate.
181pub const CONTAINER_ERR_INVALID_BIT_RATE: &str = "INVALID_BIT_RATE";
182/// Container error: invalid duration.
183pub const CONTAINER_ERR_INVALID_DURATION: &str = "INVALID_DURATION";
184/// Container error: invalid frame rate.
185pub const CONTAINER_ERR_INVALID_FRAME_RATE: &str = "INVALID_FRAME_RATE";
186/// Container error: invalid audio channels.
187pub const CONTAINER_ERR_INVALID_AUDIO_CHANNELS: &str = "INVALID_AUDIO_CHANNELS";
188/// Container error: invalid audio channel layout.
189pub const CONTAINER_ERR_INVALID_AUDIO_CHANNEL_LAYOUT: &str = "INVALID_AUDIO_CHANNEL_LAYOUT";
190/// Container error: unknown error.
191pub const CONTAINER_ERR_UNKNOWN: &str = "UNKNOWN";