instagram-private-api icon indicating copy to clipboard operation
instagram-private-api copied to clipboard

Added clips (aka reels) feed

Open NickCis opened this issue 2 years ago • 4 comments

This PR implements the Clips (aka reels) Feed (#1308 )

// ....
const feed = ig.feed.clips(targetUserPk);
const items = await feed.items();

for (const { media: item } of items) {
  console.log('Clip (aka reel)': item);
}

NickCis avatar Jul 19 '22 16:07 NickCis

Looks fine to me. Though I'm not sure if we should call it ClipsUserFeed, since there's also a clips explore page which would be ClipsExploreFeed (?).

Nerixyz avatar Jul 19 '22 16:07 Nerixyz

I could change the name, I really don't know how to name it as there is reelsMedia (which is the stories) feed, so using the term reel could also be confusing.

Please tell me what name should it have, so I can change it.

NickCis avatar Jul 19 '22 21:07 NickCis

import 'dotenv/config'; import { IgApiClient } from '../src'; import { promises as fs } from 'fs'; import * as path from 'path';

const sessionFilePath = path.resolve(__dirname, 'session.json'); console.log(Session file path: ${sessionFilePath});

async function getReelsByUsername(ig, username) { const targetUser = await ig.user.searchExact(username); console.log('targetuser', targetUser); const reelsFeed = ig.feed.clips(targetUser.pk); const allReels = []; console.log('reelsFeed', reelsFeed);

let reels = await reelsFeed.items(); allReels.push(...reels); console.log(Fetched ${reels.length} reels);

while (reelsFeed.isMoreAvailable()) { console.log('More reels are available, fetching...'); reels = await reelsFeed.items(); allReels.push(...reels); console.log(Fetched ${reels.length} more reels); }

// Log detailed information about each reel allReels.forEach((reel, index) => { const media = reel.media; console.log(Reel ${index + 1}:, { id: media.id, coverPhotoUrl: media.image_versions2?.candidates?.[0]?.url, clipUrl: media.video_versions?.[0]?.url, subtitle: media.caption?.text, likeCount: media.like_count, viewCount: media.view_count, playCount: media.play_count }); });

// Return the mapped array return allReels.map(reel => { const media = reel.media; const coverPhotoUrl = media.image_versions2?.candidates?.[0]?.url; const clipUrl = media.video_versions?.[0]?.url; const subtitle = media.caption?.text;

// Additional information
const likeCount = media.like_count;
const viewCount = media.view_count;
const playCount = media.play_count;

return {
  id: media.id,
  coverPhotoUrl: coverPhotoUrl,
  clipUrl: clipUrl,
  subtitle: subtitle,
  likeCount: likeCount,
  viewCount: viewCount,
  playCount: playCount
};

}); }

async function saveSession(data: object) { console.log('Saving session to file...'); await fs.writeFile(sessionFilePath, JSON.stringify(data)); console.log('Session saved successfully.'); }

async function sessionExists(): Promise { try { await fs.access(sessionFilePath); console.log('Session file exists.'); return true; } catch { console.log('Session file does not exist.'); return false; } }

async function loadSession(): Promise { try { const data = await fs.readFile(sessionFilePath, { encoding: 'utf8' }); console.log('Session data loaded successfully.'); return data; } catch (error) { console.error('Failed to read the session file:', error); return ''; // Return empty to signify failed loading } }

(async () => { const ig = new IgApiClient(); ig.state.generateDevice(process.env.IG_USERNAME);

if (process.env.IG_PROXY) { ig.state.proxyUrl = process.env.IG_PROXY; }

(ig.request.end$ as any).subscribe(async () => { try { const serialized = await ig.state.serialize(); delete serialized.constants; await saveSession(serialized); } catch (error) { console.error('Failed to serialize the session:', error); } });

if (await sessionExists()) { const sessionData = await loadSession(); if (sessionData) { try { await ig.state.deserialize(sessionData); } catch (error) { console.error('Failed to deserialize the session data:', error); // If deserialization fails, you may want to log in again here } } else { console.log('Session data is empty or invalid.'); // Log in again if there's no session data } } else { console.log('No valid session found, attempting to log in...'); if (!process.env.IG_USERNAME || !process.env.IG_PASSWORD) { console.error('No credentials provided.'); return; } await ig.account.login(process.env.IG_USERNAME, process.env.IG_PASSWORD); console.log('Login successful.'); } console.log('Login works.'); // The rest of your Instagram operations const usernameToFetch = 'mrbeast'; // Replace with the actual username try { const reels = await getReelsByUsername(ig, usernameToFetch); console.log(reels); } catch (err) { console.error('Error fetching reels:', err); } })(); here is the working example you can put in your doc or make example file

zakrian07 avatar Dec 02 '23 00:12 zakrian07

@NickCis plz let me know i have logged in user is these calls can be happen with non logged in users ? also can i use proxy with logged in users plz let me know what best practices to use this .Thanks for the work all you did

zakrian07 avatar Dec 02 '23 00:12 zakrian07