From ba862c1736edd129bad7354dba3fc11a404db9b7 Mon Sep 17 00:00:00 2001 From: Rizka Nugraha <68932997+rizkanugrha@users.noreply.github.com> Date: Sat, 18 Jan 2025 22:13:24 +0700 Subject: [PATCH 1/9] add allFollower dan allFllowing add allFollower dan allFllowing by Rizka Nugraha --- src/index.ts | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/index.ts b/src/index.ts index 022fc9d..1680dc5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -109,6 +109,57 @@ export class igApi { return res?.data || res } + /** + * Fetch all followers of a user + * @param userId - The user ID of the target account + * @returns A list of usernames of all followers + */ +public getAllFollowers = async (userId: userId): Promise => { + let followers: string[] = []; + let nextMaxId: string | undefined = undefined; + + do { + const res = await this.FetchIGAPI( + config.instagram_api_v1, + `/friendships/${userId}/followers/`, + config.iPhone, + { params: { count: 50, max_id: nextMaxId } } // Adjust `count` if necessary + ); + + const data = res?.data; + followers.push(...data.users.map((user: any) => user.username)); + nextMaxId = data.next_max_id; // Set for next page + } while (nextMaxId); + + return followers; +}; + +/** + * Fetch all following of a user + * @param userId - The user ID of the target account + * @returns A list of usernames of all following + */ +public getAllFollowing = async (userId: userId): Promise => { + let following: string[] = []; + let nextMaxId: string | undefined = undefined; + + do { + const res = await this.FetchIGAPI( + config.instagram_api_v1, + `/friendships/${userId}/following/`, + config.iPhone, + { params: { count: 50, max_id: nextMaxId } } // Adjust `count` if necessary + ); + + const data = res?.data; + following.push(...data.users.map((user: any) => user.username)); + nextMaxId = data.next_max_id; // Set for next page + } while (nextMaxId); + + return following; +}; + + private _formatSidecar = (data: IRawBody): Array => { const gql = data.items[0] let urls: MediaUrls[] = [] From cc0b9276c14a397c272fdec18cc4ca0fa44836ca Mon Sep 17 00:00:00 2001 From: Rizka Nugraha <68932997+rizkanugrha@users.noreply.github.com> Date: Sun, 19 Jan 2025 00:33:01 +0700 Subject: [PATCH 2/9] add getAllFollowers & getAllFollowing add getAllFollowers & getAllFollowing dari Rizkanugrha --- src/index.ts | 109 ++++++++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 53 deletions(-) diff --git a/src/index.ts b/src/index.ts index 1680dc5..429c522 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,13 +1,13 @@ /* Muhamad Ristiyanto _ https://github.com/Gimenz * Created, Published at Selasa, 9 Maret 2021 - * Modified, Updated at Minggu, 20 Februari 2022 + * Modified, Updated at Minggu, 19 Januari 2025 */ import fs from 'fs' import FormData from 'form-data'; import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; import { bufferToStream, getPostType, parseCookie, randInt, shortcodeFormatter } from './utils/index'; -import { username, userId, seachTerm, url, IgCookie, ProductType, MediaType, IChangedProfilePicture, ISearchFollow, IGPostMetadata, PostGraphQL } from './types'; +import { username, userId, seachTerm, url, IgCookie, ProductType, MediaType, IChangedProfilePicture, ISearchFollow, IGPostMetadata, PostGraphQL, UserFollow } from './types'; import { IGUserMetadata, UserGraphQL } from './types/UserMetadata'; import { IGStoriesMetadata, ItemStories, StoriesGraphQL } from './types/StoriesMetadata'; import { highlight_ids_query, highlight_media_query, post_shortcode_query } from './helper/query'; @@ -94,7 +94,7 @@ export class igApi { public searchFollower = async (userId: userId, seachTerm: seachTerm): Promise => { const res = await this.FetchIGAPI( config.instagram_api_v1, - `/friendships/${userId}/followers/?count=12&query=${seachTerm}&search_surface=follow_list_page`, + `/friendships/${userId}/followers/?count=50&query=${seachTerm}&search_surface=follow_list_page`, config.iPhone, ); return res?.data || res @@ -109,55 +109,58 @@ export class igApi { return res?.data || res } - /** - * Fetch all followers of a user - * @param userId - The user ID of the target account - * @returns A list of usernames of all followers - */ -public getAllFollowers = async (userId: userId): Promise => { - let followers: string[] = []; - let nextMaxId: string | undefined = undefined; - - do { - const res = await this.FetchIGAPI( - config.instagram_api_v1, - `/friendships/${userId}/followers/`, - config.iPhone, - { params: { count: 50, max_id: nextMaxId } } // Adjust `count` if necessary - ); - - const data = res?.data; - followers.push(...data.users.map((user: any) => user.username)); - nextMaxId = data.next_max_id; // Set for next page - } while (nextMaxId); - - return followers; -}; - -/** - * Fetch all following of a user - * @param userId - The user ID of the target account - * @returns A list of usernames of all following - */ -public getAllFollowing = async (userId: userId): Promise => { - let following: string[] = []; - let nextMaxId: string | undefined = undefined; - - do { - const res = await this.FetchIGAPI( - config.instagram_api_v1, - `/friendships/${userId}/following/`, - config.iPhone, - { params: { count: 50, max_id: nextMaxId } } // Adjust `count` if necessary - ); - - const data = res?.data; - following.push(...data.users.map((user: any) => user.username)); - nextMaxId = data.next_max_id; // Set for next page - } while (nextMaxId); - - return following; -}; + public getAllFollowers = async (userId: string, searchTerm: string = ""): Promise => { + let followers: UserFollow[] = []; + let nextMaxId: string | undefined = undefined; + + do { + const res = await this.FetchIGAPI( + config.instagram_api_v1, + `/friendships/${userId}/followers/`, + config.iPhone, + { + params: { + count: 50, // Adjust `count` to the maximum allowed by Instagram + query: searchTerm, + max_id: nextMaxId, // Pagination parameter + search_surface: "follow_list_page", + }, + } + ); + + const data: ISearchFollow = res?.data || res; + followers.push(...(data.users || [])); + nextMaxId = data.next_max_id; // Update nextMaxId for the next page + } while (nextMaxId); + + return { users: followers, status: "success" }; + }; + + public getAllFollowing = async (userId: string, searchTerm: string = ""): Promise => { + let following: UserFollow[] = []; + let nextMaxId: string | undefined = undefined; + + do { + const res = await this.FetchIGAPI( + config.instagram_api_v1, + `/friendships/${userId}/following/`, + config.iPhone, + { + params: { + count: 50, // Adjust `count` to the maximum allowed by Instagram + query: searchTerm, + max_id: nextMaxId, // Pagination parameter + }, + } + ); + + const data: ISearchFollow = res?.data || res; + following.push(...(data.users || [])); + nextMaxId = data.next_max_id; // Update nextMaxId for the next page + } while (nextMaxId); + + return { users: following, status: "success" }; + }; private _formatSidecar = (data: IRawBody): Array => { @@ -456,7 +459,7 @@ public getAllFollowing = async (userId: userId): Promise => { return graphql.data.reels_media[0].items.map((item) => ({ owner: graphql.data.reels_media[0].owner, media_id: item.id, - mimetype: item.is_video ? 'video/mp4' || 'video/gif' : 'image/jpeg', + mimetype: item.is_video ? 'video/mp4' : 'image/jpeg', taken_at: item.taken_at_timestamp, type: item.is_video ? 'video' : 'image', url: item.is_video ? item.video_resources[0].src : item.display_url, From a44b1ecca440f5603ad65753dc5c94ff28d1d1dc Mon Sep 17 00:00:00 2001 From: Rizka Nugraha <68932997+rizkanugrha@users.noreply.github.com> Date: Sun, 19 Jan 2025 00:33:52 +0700 Subject: [PATCH 3/9] Update searchFollow.ts --- src/types/searchFollow.ts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/types/searchFollow.ts b/src/types/searchFollow.ts index 0aa7da1..d7edfff 100644 --- a/src/types/searchFollow.ts +++ b/src/types/searchFollow.ts @@ -1,18 +1,20 @@ import { User } from "./PostModels"; export interface ISearchFollow { - users?: UserFollow[]; - big_list?: boolean; - page_size?: number; - has_more?: boolean; + users?: UserFollow[]; + big_list?: boolean; + page_size?: number; + has_more?: boolean; should_limit_list_of_followers?: boolean; - use_clickable_see_more?: boolean; - show_spam_follow_request_tab?: boolean; - status?: string; + use_clickable_see_more?: boolean; + show_spam_follow_request_tab?: boolean; + status?: string; + next_max_id?: string; } export type UserFollow = User & { - pk_id?: string; + pk_id?: string; third_party_downloads_enabled?: number; - strong_id__?: string; -} \ No newline at end of file + strong_id__?: string; +} + From 30ebd0983dce47e0e4b3529cb090eb3c896bfce8 Mon Sep 17 00:00:00 2001 From: Rizka Nugraha <68932997+rizkanugrha@users.noreply.github.com> Date: Sun, 19 Jan 2025 19:25:28 +0700 Subject: [PATCH 4/9] Update index.ts --- src/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/index.ts b/src/index.ts index 429c522..deca35c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -25,6 +25,8 @@ import { IPaginatedPosts } from './types/PaginatedPosts'; export * from './utils' export * as InstagramMetadata from './types' export * from './helper/Session'; +const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); + export class igApi { /** * Recommended to set cookie for most all IG Request @@ -131,6 +133,7 @@ export class igApi { const data: ISearchFollow = res?.data || res; followers.push(...(data.users || [])); nextMaxId = data.next_max_id; // Update nextMaxId for the next page + await sleep(2000); } while (nextMaxId); return { users: followers, status: "success" }; @@ -157,6 +160,7 @@ export class igApi { const data: ISearchFollow = res?.data || res; following.push(...(data.users || [])); nextMaxId = data.next_max_id; // Update nextMaxId for the next page + await sleep(2000); } while (nextMaxId); return { users: following, status: "success" }; From c1178d6babaa40e26d4bc054f83851640348f4bf Mon Sep 17 00:00:00 2001 From: Rizka Nugraha <68932997+rizkanugrha@users.noreply.github.com> Date: Mon, 20 Jan 2025 10:20:08 +0700 Subject: [PATCH 5/9] Update index.ts --- src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index deca35c..9a977ef 100644 --- a/src/index.ts +++ b/src/index.ts @@ -122,7 +122,7 @@ export class igApi { config.iPhone, { params: { - count: 50, // Adjust `count` to the maximum allowed by Instagram + count: 12, // Adjust `count` to the maximum allowed by Instagram query: searchTerm, max_id: nextMaxId, // Pagination parameter search_surface: "follow_list_page", @@ -150,7 +150,7 @@ export class igApi { config.iPhone, { params: { - count: 50, // Adjust `count` to the maximum allowed by Instagram + count: 12, // Adjust `count` to the maximum allowed by Instagram query: searchTerm, max_id: nextMaxId, // Pagination parameter }, From e2509de0fee45d9c535b9eb6e26ed1ec0c0c13a0 Mon Sep 17 00:00:00 2001 From: Rizka Nugraha <68932997+rizkanugrha@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:16:14 +0700 Subject: [PATCH 6/9] Update index.ts 20/1/25 --- src/index.ts | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 9a977ef..228e52f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ /* Muhamad Ristiyanto _ https://github.com/Gimenz * Created, Published at Selasa, 9 Maret 2021 - * Modified, Updated at Minggu, 19 Januari 2025 + * Modified, Updated at Senin, 20 Januari 2025 */ import fs from 'fs' @@ -166,6 +166,61 @@ export class igApi { return { users: following, status: "success" }; }; + /* + * add new for automate view stories & like stories + * fitur dari Rizka Nugraha + */ + + public getStories = async (): Promise => { + try { + const res = await this.FetchIGAPI( + config.instagram_api_v1, + `/feed/reels_tray/`, + config.android + ); + return res?.data?.tray || []; + } catch (error) { + console.error("Error fetching stories:", error); + return []; + } + }; + + public viewStories = async (reelId: string, itemId: string): Promise => { + try { + const res = await this.FetchIGAPI( + config.instagram_api_v1, + `/media/seen/`, + config.android, + { + data: { + reels: { [`${reelId}_${itemId}`]: [0] }, // Reel ID and timestamp + reel_media_id: itemId, + reel_author_id: reelId, + view_source: "feed_timeline", + }, + method: "POST", + } + ); + return res; + } catch (error) { + console.error("Error viewing story:", error); + } + }; + + public likeStories = async (mediaId: string): Promise => { + try { + const res = await this.FetchIGAPI( + config.instagram_api_v1, + `/media/${mediaId}/like/`, + config.android, + { method: "POST" } + ); + return res; + } catch (error) { + console.error("Error liking story:", error); + } + }; + private _formatSidecar = (data: IRawBody): Array => { const gql = data.items[0] From 302df9bba6a670006f1d8c5066418c3e81ef715c Mon Sep 17 00:00:00 2001 From: Rizka Nugraha <68932997+rizkanugrha@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:26:32 +0700 Subject: [PATCH 7/9] Update index.ts --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 228e52f..4c51985 100644 --- a/src/index.ts +++ b/src/index.ts @@ -188,7 +188,7 @@ export class igApi { public viewStories = async (reelId: string, itemId: string): Promise => { try { const res = await this.FetchIGAPI( - config.instagram_api_v1, + config.instagram_api_v2, `/media/seen/`, config.android, { From 5ef651ca8167e271ef314ba6042f00938e111bce Mon Sep 17 00:00:00 2001 From: Rizka Nugraha <68932997+rizkanugrha@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:27:16 +0700 Subject: [PATCH 8/9] Update index.ts --- src/config/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/config/index.ts b/src/config/index.ts index 28f271b..2c74229 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -4,6 +4,8 @@ export const config = { instagram_base_z4: 'https://z-p4.www.instagram.com', /** Instagram Api v1 */ instagram_api_v1: 'https://i.instagram.com/api/v1', + /** Instagram Api v2 */ + instagram_api_v2: 'https://i.instagram.com/api/v2', /** Instagram API Search User */ instagram_search_url: 'https://www.instagram.com/web/search/topsearch/?query=', /** Android User-Agent */ @@ -12,4 +14,4 @@ export const config = { desktop: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36', /** iPhone User-Agent */ iPhone: 'Instagram 123.0.0.21.114 (iPhone; CPU iPhone OS 11_4 like Mac OS X; en_US; en-US; scale=2.00; 750x1334) AppleWebKit/605.1.15' -} \ No newline at end of file +} From d46b1506bbf0e8ecb9b434f1ba63835abf639069 Mon Sep 17 00:00:00 2001 From: Rizka Nugraha <68932997+rizkanugrha@users.noreply.github.com> Date: Mon, 20 Jan 2025 20:04:50 +0700 Subject: [PATCH 9/9] Update index.ts --- src/index.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 4c51985..35cddf6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ /* Muhamad Ristiyanto _ https://github.com/Gimenz * Created, Published at Selasa, 9 Maret 2021 - * Modified, Updated at Senin, 20 Januari 2025 + * Modified, Updated at Minggu, 19 Januari 2025 */ import fs from 'fs' @@ -185,6 +185,13 @@ export class igApi { } }; + public getStoryById = async (reelId: string): Promise => { + const res = await this.FetchIGAPI(config.instagram_api_v1, `/feed/reels_media/?reel_ids=${reelId}`, config.android) + if (res && res.data && res.data.reels_media && res.data.reels_media.length > 0) { + return res.data.reels_media[0]; + } + } + public viewStories = async (reelId: string, itemId: string): Promise => { try { const res = await this.FetchIGAPI(