diff --git a/README.md b/README.md index c0206055a..9c6602147 100644 --- a/README.md +++ b/README.md @@ -40,12 +40,12 @@ http://open.igpapi.com/ It uses OpenAPI specification, so you can generate SDK for any programming language in several minutes. -You can use it right in the browser without need to have a server. +You can use it right in the browser without need to have a server. You can even use it in React Native. Yes, without bridges. It's free for a while, until it's stable. The function set is poor now, because, to be honest i'm not sure if there's a demand for it. -So if you would like to use it, have feature-requests or bug reports - please [contact me](https://t.me/bowzee) - i'll implement things you need very fast. +So if you would like to use it, have feature-requests or bug reports - please [contact me](https://t.me/bowzee) - i'll implement things you need very fast. # Table of Contents diff --git a/src/core/feed.factory.ts b/src/core/feed.factory.ts index 7d9f30d74..52cf0880a 100644 --- a/src/core/feed.factory.ts +++ b/src/core/feed.factory.ts @@ -3,12 +3,16 @@ import { AccountFollowersFeed, AccountFollowingFeed, BestiesFeed, + ArchivedStoriesFeed, + ArchivedPostsFeed, BlockedUsersFeed, DirectInboxFeed, DirectPendingInboxFeed, DirectThreadFeed, DiscoverFeed, - PostsInsightsFeed, + IgtvBrowseFeed, + IgtvChannelFeed, + LikedFeed, LocationFeed, MediaCommentsFeed, MusicGenreFeed, @@ -17,6 +21,7 @@ import { MusicTrendingFeed, NewsFeed, PendingFriendshipsFeed, + PostsInsightsFeed, ReelsMediaFeed, ReelsTrayFeed, SavedFeed, @@ -26,28 +31,25 @@ import { TimelineFeed, UserFeed, UsertagsFeed, - IgtvBrowseFeed, - IgtvChannelFeed, - LikedFeed, } from '../feeds'; -import { DirectInboxFeedResponseThreadsItem } from '../responses'; -import { plainToClassFromExist } from 'class-transformer'; -import * as Chance from 'chance'; -import { PostsInsightsFeedOptions, TimelineFeedReason, IgAppModule } from '../types'; -import { UserStoryFeed } from '../feeds/user-story.feed'; -import { ListReelMediaViewerFeed } from '../feeds/list-reel-media-viewer.feed'; -import { MediaInlineChildCommentsFeed } from '../feeds/media.inline-child-comments.feed'; -import { MediaStickerResponsesFeed } from '../feeds/media.sticker-responses.feed'; import { - StorySliderVotersFeedResponseResponseRootObject, - StorySliderVotersFeedResponseResponseVotersItem, + DirectInboxFeedResponseThreadsItem, + StoryPollVotersFeedResponseRootObject, + StoryPollVotersFeedResponseVotersItem, StoryQuestionResponsesFeedResponseRespondersItem, StoryQuestionResponsesFeedResponseRootObject, StoryQuizParticipantsFeedResponseParticipantsItem, StoryQuizParticipantsFeedResponseRootObject, - StoryPollVotersFeedResponseRootObject, - StoryPollVotersFeedResponseVotersItem, + StorySliderVotersFeedResponseResponseRootObject, + StorySliderVotersFeedResponseResponseVotersItem, } from '../responses'; +import { plainToClassFromExist } from 'class-transformer'; +import * as Chance from 'chance'; +import { IgAppModule, PostsInsightsFeedOptions, TimelineFeedReason } from '../types'; +import { UserStoryFeed } from '../feeds/user-story.feed'; +import { ListReelMediaViewerFeed } from '../feeds/list-reel-media-viewer.feed'; +import { MediaInlineChildCommentsFeed } from '../feeds/media.inline-child-comments.feed'; +import { MediaStickerResponsesFeed } from '../feeds/media.sticker-responses.feed'; export class FeedFactory { constructor(private client: IgApiClient) {} @@ -109,6 +111,14 @@ export class FeedFactory { return feed; } + public archivedStories(): any { + return new ArchivedStoriesFeed(this.client); + } + + public archivedPosts(): any { + return new ArchivedPostsFeed(this.client); + } + public tag(tag: string): TagFeed { const feed = new TagFeed(this.client); feed.tag = tag; diff --git a/src/core/request.ts b/src/core/request.ts index 66326dbec..af6e2fb7c 100644 --- a/src/core/request.ts +++ b/src/core/request.ts @@ -176,6 +176,7 @@ export class Request { try { return await retry(async () => request(options), this.attemptOptions); } catch (err) { + this.error$.next(err); throw new IgNetworkError(err); } } diff --git a/src/feeds/archived-posts.feed.ts b/src/feeds/archived-posts.feed.ts new file mode 100644 index 000000000..24c96f11f --- /dev/null +++ b/src/feeds/archived-posts.feed.ts @@ -0,0 +1,30 @@ +import { Expose } from 'class-transformer'; +import { Feed } from '../core/feed'; +//import { ArchivedFeedResponseRootObject, ArchivedFeedResponseMedia } from '../responses'; // new +//import { SavedFeedResponseRootObject, SavedFeedResponseMedia } from '../responses'; + +export class ArchivedPostsFeed extends Feed { + @Expose() + private nextMaxId: string; + + set state(body: any) { + this.moreAvailable = body.more_available; + this.nextMaxId = body.next_max_id; + } + + async request(): Promise { + const { body } = await this.client.request.send({ + url: '/api/v1/feed/only_me_feed/', + qs: { + max_id: this.nextMaxId, + }, + }); + this.state = body; + return body; + } + + async items(): Promise { + const { items } = await this.request(); + return items; + } +} diff --git a/src/feeds/archived-stories.feed.ts b/src/feeds/archived-stories.feed.ts new file mode 100644 index 000000000..b1a883b3a --- /dev/null +++ b/src/feeds/archived-stories.feed.ts @@ -0,0 +1,30 @@ +import { Expose } from 'class-transformer'; +import { Feed } from '../core/feed'; +//import { ArchivedFeedResponseRootObject, ArchivedFeedResponseMedia } from '../responses'; // new +//import { SavedFeedResponseRootObject, SavedFeedResponseMedia } from '../responses'; + +export class ArchivedStoriesFeed extends Feed { + @Expose() + private nextMaxId: string; + + set state(body: any) { + this.moreAvailable = body.more_available; + this.nextMaxId = body.next_max_id; + } + + async request(): Promise { + const { body } = await this.client.request.send({ + url: '/api/v1/archive/reel/day_shells/', + qs: { + max_id: this.nextMaxId, + }, + }); + this.state = body; + return body; + } + + async items(): Promise { + const { items } = await this.request(); + return items; + } +} diff --git a/src/feeds/index.ts b/src/feeds/index.ts index a130f8540..57c96cd73 100644 --- a/src/feeds/index.ts +++ b/src/feeds/index.ts @@ -27,3 +27,5 @@ export * from './stories-insights.feed'; export * from './igtv.browse.feed'; export * from './igtv.channel.feed'; export * from './liked.feed'; +export * from './archived-stories.feed'; +export * from './archived-posts.feed'; diff --git a/src/responses/archived.feed.response.ts b/src/responses/archived.feed.response.ts new file mode 100644 index 000000000..cb5dd2a35 --- /dev/null +++ b/src/responses/archived.feed.response.ts @@ -0,0 +1,202 @@ +export interface ArchivedFeedResponseRootObject { + items: ArchivedFeedResponseItemsItem[]; + num_results: number; + more_available: boolean; + auto_load_more_enabled: boolean; + status: string; + next_max_id: string; +} +export interface ArchivedFeedResponseItemsItem { + media: ArchivedFeedResponseMedia; +} +export interface ArchivedFeedResponseMedia { + taken_at: number; + pk: string; + id: string; + device_timestamp: string | number; + media_type: number; + code: string; + client_cache_key: string; + filter_type: number; + image_versions2?: ArchivedFeedResponseImage_versions2; + original_width?: number; + original_height?: number; + user: ArchivedFeedResponseUser; + can_viewer_reshare: boolean; + caption_is_edited: boolean; + is_external_share_disabled?: boolean; + comment_likes_enabled: boolean; + comment_threading_enabled: boolean; + has_more_comments: boolean; + next_max_id: string; + max_num_visible_preview_comments: number; + preview_comments: ArchivedFeedResponsePreviewCommentsItem[]; + can_view_more_preview_comments: boolean; + comment_count: number; + inline_composer_display_condition: string; + inline_composer_imp_trigger_time: number; + like_count: number; + has_liked: boolean; + photo_of_you: boolean; + product_tags?: ArchivedFeedResponseProduct_tags; + can_see_insights_as_brand?: boolean; + caption: ArchivedFeedResponseCaption; + can_viewer_save: boolean; + has_viewer_saved: boolean; + saved_collection_ids: any[]; + organic_tracking_token: string; + usertags?: ArchivedFeedResponseUsertags; + is_dash_eligible?: number; + video_dash_manifest?: string; + video_codec?: string; + number_of_qualities?: number; + video_versions?: ArchivedFeedResponseVideoVersionsItem[]; + has_audio?: boolean; + video_duration?: number; + view_count?: number; + carousel_media_count?: number; + carousel_media?: ArchivedFeedResponseCarouselMediaItem[]; +} +export interface ArchivedFeedResponseImage_versions2 { + candidates: ArchivedFeedResponseCandidatesItem[]; +} +export interface ArchivedFeedResponseCandidatesItem { + width: number; + height: number; + url: string; + estimated_scans_sizes?: number[]; +} +export interface ArchivedFeedResponseUser { + pk: number; + username: string; + full_name: string; + is_private: boolean; + profile_pic_url: string; + friendship_status?: ArchivedFeedResponseFriendship_status; + is_verified: boolean; + has_anonymous_profile_picture?: boolean; + is_unpublished?: boolean; + is_favorite?: boolean; + show_shoppable_feed?: boolean; + shoppable_posts_count?: number; + can_be_reported_as_fraud?: boolean; + latest_reel_media?: number; + profile_pic_id?: string; +} +export interface ArchivedFeedResponseFriendship_status { + following: boolean; + outgoing_request: boolean; + is_bestie: boolean; + is_restricted: boolean; +} +export interface ArchivedFeedResponsePreviewCommentsItem { + pk: string; + user_id: number; + text: string; + type: number; + created_at: number; + created_at_utc: number; + content_type: string; + status: string; + bit_flags: number; + user: ArchivedFeedResponseUser; + did_report_as_spam: boolean; + share_enabled: boolean; + media_id: string; + has_liked_comment: boolean; + comment_like_count: number; + has_translation?: boolean; + parent_comment_id?: string; +} +export interface ArchivedFeedResponseProduct_tags { + in: ArchivedFeedResponseInItem[]; +} +export interface ArchivedFeedResponseInItem { + product?: ArchivedFeedResponseProduct; + position: string[] | number[]; + user?: ArchivedFeedResponseUser; + start_time_in_video_in_sec?: null; + duration_in_video_in_sec?: null; +} +export interface ArchivedFeedResponseProduct { + name: string; + price: string; + current_price: string; + full_price: string; + product_id: string; + merchant: ArchivedFeedResponseMerchant; + description: string; + retailer_id: string; + has_viewer_saved: boolean; + main_image: ArchivedFeedResponseMain_image; + thumbnail_image: ArchivedFeedResponseThumbnail_image; + review_status: string; + external_url: string; + checkout_style: string; + can_share_to_story: boolean; + full_price_stripped: string; + current_price_stripped: string; + variant_values?: ArchivedFeedResponseVariantValuesItem[]; +} +export interface ArchivedFeedResponseMerchant { + pk: number; + username: string; + profile_pic_url: string; +} +export interface ArchivedFeedResponseMain_image { + image_versions2: ArchivedFeedResponseImage_versions2; + preview: null; +} +export interface ArchivedFeedResponseThumbnail_image { + image_versions2: ArchivedFeedResponseImage_versions2; + preview: null; +} +export interface ArchivedFeedResponseVariantValuesItem { + id: string; + value: string; + name: string; + is_preselected: boolean; + visual_style: string; +} +export interface ArchivedFeedResponseCaption { + pk: string; + user_id: number; + text: string; + type: number; + created_at: number; + created_at_utc: number; + content_type: string; + status: string; + bit_flags: number; + user: ArchivedFeedResponseUser; + did_report_as_spam: boolean; + share_enabled: boolean; + media_id: string; + has_translation?: boolean; +} +export interface ArchivedFeedResponseUsertags { + in: ArchivedFeedResponseInItem[]; +} +export interface ArchivedFeedResponseVideoVersionsItem { + type: number; + width: number; + height: number; + url: string; + id: string; +} +export interface ArchivedFeedResponseCarouselMediaItem { + id: string; + media_type: number; + image_versions2: ArchivedFeedResponseImage_versions2; + original_width: number; + original_height: number; + pk: string; + carousel_parent_id: string; + usertags: ArchivedFeedResponseUsertags; + video_versions?: ArchivedFeedResponseVideoVersionsItem[]; + video_duration?: number; + is_dash_eligible?: number; + video_dash_manifest?: string; + video_codec?: string; + number_of_qualities?: number; +} diff --git a/src/responses/index.ts b/src/responses/index.ts index 56759e10d..3bc927003 100644 --- a/src/responses/index.ts +++ b/src/responses/index.ts @@ -67,6 +67,7 @@ export * from './media.repository.configure.response'; export * from './media.repository.configure-sidecar.response'; export * from './media.repository.configure-video.response'; export * from './saved.feed.response'; +export * from './archived.feed.response'; export * from './status.response'; export * from './reels-tray.feed.response'; export * from './music.repository.moods.response';