@@ -42,6 +42,40 @@ const logRateLimiter = {
4242 }
4343} ;
4444
45+ const USER_AGENTS = [
46+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36' ,
47+ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36' ,
48+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0' ,
49+ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15'
50+ ] ;
51+
52+ function getRandomUserAgent ( ) {
53+ return USER_AGENTS [ Math . floor ( Math . random ( ) * USER_AGENTS . length ) ] ;
54+ }
55+
56+ async function fetchWithRetry ( url , options , maxRetries = 3 ) {
57+ let lastError ;
58+
59+ for ( let attempt = 0 ; attempt < maxRetries ; attempt ++ ) {
60+ try {
61+ if ( attempt > 0 ) {
62+ await delay ( 1000 * attempt ) ;
63+ }
64+
65+ if ( attempt > 0 ) {
66+ options . headers [ 'User-Agent' ] = getRandomUserAgent ( ) ;
67+ }
68+
69+ return await fetch ( url , options ) ;
70+ } catch ( error ) {
71+ lastError = error ;
72+ console . error ( `${ color . yellow } [${ getTimestamp ( ) } ] [INSTA_NOTIFICATION] Fetch attempt ${ attempt + 1 } failed: ${ error . message } ${ color . reset } ` ) ;
73+ }
74+ }
75+
76+ throw lastError ;
77+ }
78+
4579function delay ( ms ) {
4680 return new Promise ( resolve => setTimeout ( resolve , ms ) ) ;
4781}
@@ -52,22 +86,33 @@ async function getLatestPost(username) {
5286 }
5387
5488 try {
55- const userResponse = await fetch ( `https://www.instagram.com/api/v1/users/web_profile_info/?username=${ username } ` , {
56- headers : {
57- 'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36' ,
58- 'Accept' : 'application/json' ,
59- 'Accept-Language' : 'en-US,en;q=0.9' ,
60- 'X-IG-App-ID' : '936619743392459' ,
61- 'X-Requested-With' : 'XMLHttpRequest' ,
62- 'Referer' : `https://www.instagram.com/${ username } /` ,
63- 'Cookie' : 'ig_did=1; csrftoken=1; mid=1;'
64- }
65- } ) ;
89+ const headers = {
90+ 'User-Agent' : getRandomUserAgent ( ) ,
91+ 'Accept' : '*/*' ,
92+ 'Accept-Language' : 'en-US,en;q=0.9' ,
93+ 'X-IG-App-ID' : '936619743392459' ,
94+ 'X-Requested-With' : 'XMLHttpRequest' ,
95+ 'Referer' : `https://www.instagram.com/${ username } /` ,
96+ 'Origin' : 'https://www.instagram.com' ,
97+ 'Sec-Fetch-Site' : 'same-origin' ,
98+ 'Sec-Fetch-Mode' : 'cors' ,
99+ 'Sec-Fetch-Dest' : 'empty' ,
100+ } ;
101+
102+ const encodedUsername = encodeURIComponent ( username ) ;
103+ const apiUrl = `https://www.instagram.com/api/v1/users/web_profile_info/?username=${ encodedUsername } ` ;
104+
105+ const userResponse = await fetchWithRetry ( apiUrl , { headers } ) ;
66106
67107 if ( ! userResponse . ok ) {
68- if ( userResponse . status !== 429 ) {
69- if ( logRateLimiter . shouldLog ( `api_error_${ username } ` , 60 ) ) {
70- console . error ( `${ color . yellow } [${ getTimestamp ( ) } ] [INSTA_NOTIFICATION] Warning: Instagram API returned ${ userResponse . status } for ${ username } ${ color . reset } ` ) ;
108+ const statusCode = userResponse . status ;
109+ if ( logRateLimiter . shouldLog ( `api_error_${ username } _${ statusCode } ` , 30 ) ) {
110+ console . error ( `${ color . yellow } [${ getTimestamp ( ) } ] [INSTA_NOTIFICATION] Instagram API returned ${ statusCode } for ${ username } ${ color . reset } ` ) ;
111+
112+ if ( statusCode === 429 ) {
113+ console . error ( `${ color . red } [${ getTimestamp ( ) } ] [INSTA_NOTIFICATION] Rate limited by Instagram${ color . reset } ` ) ;
114+ } else if ( statusCode === 401 || statusCode === 403 ) {
115+ console . error ( `${ color . red } [${ getTimestamp ( ) } ] [INSTA_NOTIFICATION] Authentication error for Instagram API${ color . reset } ` ) ;
71116 }
72117 }
73118 return null ;
@@ -83,9 +128,10 @@ async function getLatestPost(username) {
83128
84129 const userData = await userResponse . json ( ) ;
85130
86- if ( ! userData || ! userData . data || ! userData . data . user ) {
131+ if ( ! userData ? .data ? .user ) {
87132 if ( logRateLimiter . shouldLog ( `no_user_data_${ username } ` , 60 ) ) {
88- console . error ( `${ color . yellow } [${ getTimestamp ( ) } ] [INSTA_NOTIFICATION] Warning: No user data found for ${ username } ${ color . reset } ` ) ;
133+ const errorDetails = userData ?. status === 'fail' ? ` - Reason: ${ userData . message } ` : '' ;
134+ console . error ( `${ color . yellow } [${ getTimestamp ( ) } ] [INSTA_NOTIFICATION] Warning: No user data found for ${ username } ${ errorDetails } ${ color . reset } ` ) ;
89135 }
90136 return null ;
91137 }
@@ -110,7 +156,7 @@ async function getLatestPost(username) {
110156 const now = Date . now ( ) ;
111157 const lastErrorTime = rateLimiter . lastWarning [ `error_${ username } ` ] || 0 ;
112158 if ( now - lastErrorTime > 60 * 60 * 1000 ) {
113- console . error ( `${ color . red } [${ getTimestamp ( ) } ] [INSTA_NOTIFICATION] Error fetching Instagram posts for ${ username } : ${ color . reset } ` , error ) ;
159+ console . error ( `${ color . red } [${ getTimestamp ( ) } ] [INSTA_NOTIFICATION] Error fetching Instagram posts for ${ username } : ${ error . message } ${ color . reset } ` ) ;
114160 rateLimiter . lastWarning [ `error_${ username } ` ] = now ;
115161 }
116162 return null ;
0 commit comments