npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

instaflow

v1.6.1

Published

Headless Instagram automation powered by Playwright. Persistent sessions, human-like delays, built-in rate limiter. Post, story, like, comment, follow, DM, scrape reels and more — no API key required.

Readme

🌊 InstaFlow

Node.js için başsız (headless) Instagram otomasyonu — Playwright ile.
API anahtarı yok. OAuth yok. Sadece gerçek bir tarayıcı oturumu, insan benzeri davranış ve temiz bir async API.

npm version npm downloads license node

English · 🌐 Türkçe


✨ Özellikler

| Kategori | Eylemler | |---|---| | Yayınlama | Fotoğraf/video gönderisi, hikaye yükleme, profil düzenleme (ad/bio/website/avatar), gönderi silme | | Etkileşim | Beğen, beğeniyi geri al, yorum, kaydet, kaydı kaldır | | Sosyal | Takip et, takipten çık, DM gönder, DM mesajlarına tepki ver, hikaye görüntüle & tepki ver | | Kazıma (Scraping) | Profil istatistikleri, gönderi istatistikleri, yorumlar, takipçi/takip edilen, arama, hashtag gönderileri, gelen kutusu | | Reels & Gönderiler | Reels akışını kazı, reel/gönderi analizi — reel videosunu, ya da her carousel resmini + eklenen müziği indir — açıklama/beğeni/yorum ile | | Gerçek Zamanlı | DM mesaj dinleyici (messageReceived/userMessages), bahsetme/bildirim dinleyici (mentioned) | | Oturum | Ham çerezleri dışa aktar (ör. yt-dlp için) | | Güvenlik | Yerleşik hız sınırlayıcı, insan benzeri gecikmeler, tespit önleyici gizlilik, kalıcı oturumlar |


📦 Kurulum

npm install instaflow
npx playwright install chromium

Yalnızca Chromium tarayıcı ikilisi gereklidir.


🚀 Hızlı Başlangıç

const InstaFlow = require('instaflow');

const bot = new InstaFlow({
  sessionDir: './my-session',   // oturumu kalıcı kılar — yeniden giriş gerekmez
  headless: true,
  humanize: true,               // eylemler arasında rastgele insan benzeri gecikmeler
});

bot.on('ready', async () => {
  // Kendi profil istatistiklerini al
  const me = await bot.getMyStats();
  console.log(`@${me.username} — ${me.followers} takipçi`);

  // Bir gönderiyi beğen
  await bot.likePost('https://www.instagram.com/p/SHORTCODE/');

  // Açıklamalı bir fotoğraf paylaş
  await bot.post('InstaFlow ile merhaba 🌊', {
    media: ['./photo.jpg'],
  });

  await bot.close();
});

bot.init();

🔐 Kimlik Doğrulama

Kalıcı Oturum (önerilen)

En kolay yol — tarayıcıdan bir kez giriş yap, sonra oturumu sonsuza dek tekrar kullan:

const bot = new InstaFlow({
  sessionDir: './sessions/my_account',
  headless: false,   // ilk giriş için tarayıcıyı göster
});

Botu başlat, açılan tarayıcı penceresinden manuel giriş yap, ardından sonraki tüm çalıştırmalar için headless: true yap. Oturum sessionDir içinde saklanır ve yeniden başlatmalara dayanır.

Kimlik Bilgisiyle Giriş

const bot = new InstaFlow({
  username: 'kullanici_adin',
  password: 'sifren',
  sessionDir: './sessions/my_account',  // ilk girişten sonra oturumu kaydeder
});

Çerez (Cookie) ile Giriş

const bot = new InstaFlow({
  cookies: {
    sessionid:  'xxxx',
    csrftoken:  'yyyy',
    ds_user_id: 'zzzz',
  },
});

📖 API Referansı

Tüm metotlar async'tir ve eylem tamamlandığında çözülür (resolve).

bot.init() → InstaFlow

Tarayıcıyı başlatır ve kimlik doğrular. Bittiğinde ready olayını yayar.

bot.close()

Tarayıcıyı kapatır ve tüm kaynakları serbest bırakır.


Okuma — Profil

bot.getMyStats() → ProfileStats

Giriş yapılmış hesabın istatistiklerini döndürür (takipçi, takip edilen, gönderi, bio, avatar).

bot.getProfile(username) → ProfileStats

Herhangi bir hesabın herkese açık profil istatistiklerini döndürür. Instagram'ın web_profile_info JSON API'sini birincil kaynak olarak kullanır (DOM kazıma yedektir), bu yüzden ad, bio, sayılar, onaylı rozeti ve harici URL doğrudur.

const profile = await bot.getProfile('nasa');
// { username, fullName, bio, followers, following, posts, avatarUrl, isPrivate, isVerified, externalUrl }

Okuma — Gönderiler & Yorumlar

bot.getUserPosts(username, count?) → { posts, count }

Bir profil ızgarasından count (varsayılan 12) kadar gönderi URL'si + kısa kodu kazır.

bot.getPostStats(postUrl) → PostStats

Bir gönderi için beğeni, yorum sayısı, açıklama, yazar ve yayın tarihini döndürür.

bot.getPostComments(postUrl, count?) → Comment[]

Kullanıcı adı + metin + zaman damgasıyla count kadar yorumu kazır.


Okuma — Sosyal Grafik

bot.getFollowers(username, count?) → User[]

bot.getFollowing(username, count?) → User[]

Takipçi / takip edilen listelerini kazır. { username, avatar, fullName }[] döndürür.


Okuma — Keşif

bot.search(query) → { users, hashtags, places }

Genel arama — kullanıcı önerileri, hashtag önerileri ve yer sonuçları döndürür.

bot.searchUsers(query) → User[]

Yalnızca kullanıcıları arar.

bot.getHashtagPosts(hashtag, count?) → Post[]

Bir hashtag altındaki en iyi gönderileri kazır.


Okuma — Gelen Kutusu

bot.getInbox(count?) → { threads }

DM konularını listeler; her biri lastMessage ile (tür, metin/medya, sentAt, gönderen).

bot.getMessages(threadId, count?) → { messages }

Bir konudaki mesajları (thread API'siyle) okur. Her mesaj tam normalize — { itemId, from, fromId, fromSelf, type, text, media, repliedTo, timestamp, sentAt, sender } — yani tarih-saat (sentAt) ve alıntılanan mesaj (repliedTo) de gelir.


Okuma — Reels

bot.getReelsFeed(count?) → Reel[]

Gerçek reels akışında (instagram.com/reels/) ilerler ve reel kısa kodlarını toplar. { shortcode, type: 'reel', url }[] döndürür.

bot.getReelStats(postUrl) → ReelStats

Bir reel (veya herhangi bir gönderi) için zenginleştirilmiş istatistikler: kapak küçük resmi (multimodal yapay zeka analizine uygun), oynatma/izlenme sayısı, beğeni, yorum, açıklama, yazar ve varsa ham videoSrc.

const reel = await bot.getReelStats('https://www.instagram.com/reel/SHORTCODE/');
// { author, caption, thumbnail, videoSrc, plays, likes, comments, publishedAt }

bot.downloadReel(postUrl, destPath) → { path, url, bytes }

Bir reel'in video dosyasını destPath'e en iyi çabayla indirir. Instagram reel'leri MSE/blob + aralıklı CDN ile sunduğundan başarı garanti değildir — önce og:video ilerlemeli MP4'ünü, sonra <video> kaynağını, sonra yakalanan en büyük .mp4 ağ yanıtını dener.

bot.analyzeReel(input, options?) → ReelAnalysis

İleri/yapay zeka işleme için tam reel analizi — videoyu indirir ve açıklamayı, etkileşim sayılarını ve gerçek yorumlardan bir örneklemi döndürür (Instagram'ın media info/comments JSON API'leriyle, sayılar kesindir). input bir reel URL'si, kısa kod veya paylaşılan reel taşıyan bir messageReceived event nesnesi olabilir.

const a = await bot.analyzeReel('https://www.instagram.com/reel/SHORTCODE/', {
  download: true,           // .mp4'ü de kaydet (varsayılan true)
  downloadDir: './reels',   // nereye kaydedileceği
  commentCount: 12,         // kaç yorum örnekleneceği
});
// {
//   url, shortcode, mediaId, author, fullName, caption,
//   likes, comments, plays, durationSec, publishedAt,
//   thumbnail, videoUrl,
//   sampleComments: [{ username, text, likes, createdAt }],
//   download: { path, bytes, url },
//   timestamp,
// }

reelAnalyzed olayını yayar.

bot.analyzePost(input, options?) → PostAnalysis

analyzeReel gibi ama fotoğraf gönderileri ve carousel'ler için — her resmi (ve varsa videoyu) artı varsa eklenen müziği/sesi indirir; açıklama, sayılar ve örnek yorumları döndürür. input bir gönderi URL'si, kısa kod veya paylaşılan gönderi taşıyan bir messageReceived mesajı olabilir.

const a = await bot.analyzePost('https://www.instagram.com/p/SHORTCODE/', {
  download: true, downloadMusic: true, downloadDir: './posts', commentCount: 12,
});
// {
//   url, shortcode, mediaId, author, caption, likes, comments, plays,
//   mediaType, isCarousel, publishedAt,
//   music: { title, artist, audioType, downloadUrl, download:{ path, bytes } } | null,
//   items: [ { index, type:'image'|'video', url, download:{ path, bytes } } ],
//   sampleComments, timestamp,
// }

postAnalyzed olayını yayar.


Yazma — Yayınlama

bot.post(caption, options?) → PostResult

Fotoğraf veya video gönderisi yayınlar.

await bot.post('Şuna bir bak! #fotografcilik', {
  media: ['./photo.jpg'],      // yerel dosya yolu/yolları
});

bot.postStory(mediaPath) → StoryResult

Yerel bir görsel veya videodan hikaye yayınlar. Instagram masaüstü web sitesinden hikaye oluşturmayı kaldırdığı için, bu metot mevcut oturum çerezlerinle beslenen kısa ömürlü mobil-emülasyonlu bir tarayıcı bağlamı açar, mobil oluştur (+) → Hikaye akışıyla yayınlar ve bağlamı kapatır — ana oturumun etkilenmez. (headless: false iken kısa süreliğine ikinci bir Chromium penceresi görürsün.)

bot.setupProfile(options) → ProfileEditResult

Hesap düzenleme sayfasında profil meta verisini günceller. Her alan isteğe bağlıdır — yalnızca verdiklerine dokunulur.

await bot.setupProfile({
  name:    'InstaFlow Bot',
  bio:     '🌊 InstaFlow ile otomatikleştirildi',
  website: 'https://example.com',
  avatar:  './new-avatar.jpg',   // yerel görsel yolu
});
// → { name, bio, website, avatar, saved, timestamp }  (booleanlar neyin uygulandığını bildirir)

bot.deletePost(postUrl) → Result

Kendi gönderilerinden/reel'lerinden birini siler (gönderinin … menüsünü açar → Sil → onayla).

await bot.deletePost('https://www.instagram.com/p/SHORTCODE/');
// → { success: true, postUrl, timestamp }

Yazma — Etkileşim

bot.likePost(postUrl) → Result

bot.unlikePost(postUrl) → Result

Bir gönderiyi beğen / beğeniyi kaldır.

bot.savePost(postUrl) → Result

bot.unsavePost(postUrl) → Result

Bir gönderiyi kaydet / kaydı kaldır.

bot.comment(postUrl, text) → CommentResult

Bir gönderiye yorum yapar.

bot.replyToComment(postUrl, target, text) → Result

Belirli bir yoruma yanıt verir (threaded reply). target yorum id'si, bir yorumcu kullanıcı adı, yorum metni veya bir mentioned event nesnesi olabilir. Instagram'ın web yorum endpoint'i üzerinden gönderir ve yeni yanıtın commentId'sini döndürür. Mention dinleyiciyle mükemmel uyum:

bot.on('mentioned', (n) => {
  if (n.media?.url) bot.replyToComment(n.media.url, n.from, 'etiket için sağ ol! 🙌');
});

bot.searchAndLike(hashtag, count?) → { hashtag, liked, requested }

Bir hashtag altındaki en iyi gönderileri kazır ve count kadarını (varsayılan 5) beğeniler arası rastgele gecikmelerle beğenir.


Yazma — Sosyal

bot.followUser(username) → Result

bot.unfollowUser(username) → Result

Bir hesabı takip et / takipten çık.

bot.sendDM(username, message) → DMResult

Bir kullanıcıya direkt mesaj gönderir.

bot.viewStory(username) → Result

Bir kullanıcının aktif hikayesini açar ve izler (görüntüleme olarak sayılır).

bot.reactToStory(username, emoji) → Result

Bir kullanıcının aktif hikayesine emoji ile tepki verir.

bot.reactToMessage(threadId, target?, emoji?) → Result

Bir DM mesajına emoji ile tepki verir (hızlı set: ❤️ 😂 😮 😢 😡 👍; varsayılan ❤️). target mesajın metni, bir { text } veya bir messageReceived mesaj nesnesi olabilir; vermezsen thread'deki son gelen metin mesajına tepki verir. Listener ile doğal uyum:

bot.on('messageReceived', (msg) => {
  if (msg.type === 'reel') bot.reactToMessage(msg.threadId, msg, '😂');
});

Yardımcı

bot.getRateLimitStatus() → RateLimitStatus

Her eylem türü için saatlik / günlük kullanımı, yapılandırılmış limitlere karşı gösterir.

bot.getCookies() → Cookie[]

Mevcut oturum çerezlerini Playwright formatında döndürür — kimlik doğrulanmış bir oturumu yt-dlp gibi harici araçlara aktarmak için kullanışlıdır.


📨 Gerçek Zamanlı DM Dinleyici

DM gelen kutusunu yoklar ve gelen mesajlara anında tepki verir. Burst-güvenli: inbox thread başına yalnızca ~2 mesaj önizler, bu yüzden bir thread'de yeni hareket olunca tüm thread çekilir ve her yeni mesaj teslim edilir — iki yoklama arasında birden fazla mesaj gelse bile hiçbiri kaçmaz.

Her yoklamada iki olay tetiklenir — hangisini istersen onu dinle:

| Olay | Ne zaman | Yük | |---|---|---| | messageReceived | her yeni mesaj için bir kez | tek bir normalize mesaj | | userMessages | yeni mesajı olan her thread/kişi için bir kez | { threadId, threadTitle, from, fromId, sender, messages: [ … ] } |

Yani Alper bir döngüde 3, Mehmet 2 mesaj atarsa: 5 messageReceived ve 2 userMessages olayı alırsın (Alper'in 3'ü bir dizi, sonra Mehmet'in 2'si).

bot.startMessageListener(options?)

Yoklamayı başlatır. Seçenekler: interval (ms, varsayılan 6000), limit (yoklama başına thread, varsayılan 20), threadLimit (aktif thread başına çekilen mesaj, varsayılan 25), includeSelf (varsayılan false), emitExisting (başlangıçta mevcut birikimi yay, varsayılan false), enrichSender (sender'a bio/takipçi sayıları/hikaye durumu ekler, her yeni gönderen için +1 istek, varsayılan false).

bot.stopMessageListener()

Yoklamayı durdurur ve arka plan sekmesini kapatır.

// Mesaj bazlı: sana DM ile gelen her reel'i otomatik analiz et
bot.on('messageReceived', async (msg) => {
  console.log(`@${msg.from} bir ${msg.type} gönderdi — ${msg.sentAt}`);
  if (msg.repliedTo) console.log(`  ↳ şunu yanıtlıyor ${msg.repliedTo.from}: "${msg.repliedTo.text}"`);
  if (msg.media?.type === 'reel') {
    const reel = await bot.analyzeReel(msg, { download: true, downloadDir: './reels' });
    console.log(`  ↳ @${reel.author} — ${reel.likes} beğeni, ${reel.comments} yorum`);
  }
});

// Kişi bazlı: her gönderenin yeni mesajlarını tek seferde işle
bot.on('userMessages', ({ from, messages }) => {
  console.log(`@${from} ${messages.length} yeni mesaj gönderdi`);
});

bot.on('ready', () => bot.startMessageListener({ interval: 5000 }));
bot.init();

messageReceived yükü:

{
  threadId, threadTitle,
  itemId,            // benzersiz mesaj id'si (yinelenenleri ayıklamak için)
  from, fromId,      // gönderen kullanıcı adı + id
  fromSelf,          // mesajı sen gönderdiysen true
  type,              // 'text' | 'reel' | 'post' | ham IG item_type
  text,              // metin içeriği (veya null)
  media,             // { type:'reel'|'post', shortcode, url }  — veya null
  repliedTo,         // bir yanıtsa alıntılanan mesaj (aynı yapı) — değilse null
  timestamp,         // ms
  sentAt,            // ISO tarih-saat metni
  sender: {          // kimden geldiği (ücretsiz, doğrudan gelen kutusundan)
    username, fullName /* ad-soyad */, avatar /* profil foto */, isVerified, isPrivate,
    accountType, hasHighlights,
    friendship: { following, followedBy, isBestie, muting, blocking, restricted },
    lastActiveAt,    // ms — bu sohbette son görülme (web'de canlı "online" bilgisi yok)
    // enrichSender: true ile ayrıca:
    bio, followers, following, posts, externalUrl, hasActiveStory, storyCount,
  },
}

Yoklama ayrı bir arka plan sekmesinde çalışır, diğer eylemlerini asla aksatmaz. Handler'ın ağır iş yapıyorsa (indirme, gezinme), sayfa işlemlerinin çakışmaması için sıraya al (ör. bir kuyruk).


🔔 Bahsetmeler & Bildirimler

Aktivite akışını izler ve biri seni bir yorumda @ ile bahsedince (veya etiketleyince) tepki verirsin. Her yoklamada bildirimler sayfası (kimlik doğrulamalı GraphQL çağrısıyla yüklenen) okunup parse edilir.

bot.startMentionListener(options?) / bot.stopMentionListener()

Seçenekler: interval (ms, varsayılan 20000), emitExisting (varsayılan false), mentionsOnly (beğeni/takip gibi diğerlerini tamamen atla, varsayılan false), resolveComment (bahsetmeler için gerçek yorum id'sini + metnini bulur — +1 istek; varsayılan true). Yorum bahsetmeleri, gönderen seni takip etse de etmese de buraya düşer.

Her yeni öğe için notification, bahsetme/yorum/etiket alt kümesi için mentioned yayar:

bot.on('mentioned', async (n) => {
  console.log(`@${n.from} seni ${n.kind}: ${n.media?.url}`);   // kind: 'mention' | 'comment' | 'tag'
  // etiketlendiğin yorumun hemen altına yanıt ver
  if (n.media?.url) await bot.replyToComment(n.media.url, n.comment?.id || n.from, 'sağ ol! 🙌');
});
bot.on('ready', () => bot.startMentionListener({ interval: 20000 }));

Yük: { id, kind, type, storyType, from, fromId, text, media, comment, timestamp, sentAt }

  • kind: 'mention' | 'comment' | 'like' | 'follow' | 'tag' | 'other'
  • media (varsa): { id, shortcode, url } — etiketlendiğin gönderi/reel
  • comment (bahsetmelerde, resolveComment ile): { id, text, createdAt, likes } — gerçek yorum

⚙️ Yapılandırma

const bot = new InstaFlow({
  // Kimlik doğrulama
  sessionDir: './sessions/account',
  username:   'kullanici_adin',
  password:   'sifren',

  // Tarayıcı
  headless:   true,
  timeout:    60000,   // sayfa eylemi başına ms

  // Proxy (isteğe bağlı)
  proxy: {
    host:     'proxy.example.com',
    port:     8080,
    protocol: 'http',      // veya 'socks5'
    username: 'user',
    password: 'pass',
  },

  // Davranış
  humanize: true,   // eylemler arası rastgele gecikmeler

  // Hız limitleri (varsayılanları geçersiz kıl)
  rateLimits: {
    like:    { hour: 20, day: 100 },
    comment: { hour: 10, day: 40  },
    follow:  { hour: 5,  day: 20  },
    // post | story | like | comment | follow | unfollow | dm
  },
});

Varsayılan hız limitleri:

| Eylem | Saatlik | Günlük | |--------|----------|---------| | post | 3 | 10 | | story | 5 | 15 | | like | 30 | 150 | | comment | 15 | 60 | | follow | 10 | 40 | | unfollow | 10 | 40 | | dm | 10 | 40 |


📡 Olaylar (Events)

bot.on('ready',            ()       => console.log('Bot hazır'));
bot.on('loginRequired',    ()       => console.log('Giriş gerekiyor'));
bot.on('error',            (err)    => console.error('Hata:', err));
bot.on('rateLimitHit',     (info)   => console.warn('Hız limiti:', info));
bot.on('actionBlocked',    (info)   => console.warn('Engellendi:', info));
bot.on('challengeRequired',()       => console.warn('Doğrulama tetiklendi'));
bot.on('postLiked',        (result) => console.log('Beğenildi:', result));
bot.on('postCommented',    (result) => console.log('Yorum yapıldı:', result));
bot.on('commentReplied',   (result) => console.log('Yoruma yanıt verildi:', result.commentId));
bot.on('userFollowed',     (result) => console.log('Takip edildi:', result));
bot.on('userUnfollowed',   (result) => console.log('Takipten çıkıldı:', result));
bot.on('postPublished',    (result) => console.log('Yayınlandı:', result));
bot.on('postFailed',       (info)   => console.warn('Gönderi başarısız:', info));
bot.on('storyPublished',   (result) => console.log('Hikaye yayınlandı:', result));
bot.on('storyFailed',      (info)   => console.warn('Hikaye başarısız:', info));
bot.on('profileSetup',     (result) => console.log('Profil güncellendi:', result));
bot.on('postDeleted',      (result) => console.log('Gönderi silindi:', result));
bot.on('dmSent',           (result) => console.log('DM gönderildi:', result));
bot.on('messageReceived',  (msg)    => console.log('Yeni DM:', msg.from, msg.type, msg.sentAt));
bot.on('userMessages',     (grp)    => console.log(`${grp.from}: ${grp.messages.length} yeni`));
bot.on('messageReacted',   (result) => console.log('Tepki verildi:', result.emoji));
bot.on('reelAnalyzed',     (result) => console.log('Reel analiz edildi:', result.shortcode));
bot.on('postAnalyzed',     (result) => console.log('Gönderi analiz edildi:', result.shortcode));
bot.on('mentioned',        (n)      => console.log('Bahseden:', n.from));
bot.on('notification',     (n)      => console.log('Bildirim:', n.kind, n.from));

🛡️ Tespit Önleme

InstaFlow, tespit riskini azaltmak için birkaç teknik kullanır:

  • Gizlilik bayrakları — --disable-blink-features=AutomationControlled, yamalanmış navigator.webdriver
  • Kalıcı Chrome profili — çalıştırmalar arası aynı parmak izi, taze tarayıcı ipuçları yok
  • İnsan gecikmeleri — etkileşimler arası yapılandırılabilir rastgele duraklamalar (humanize: true)
  • Hız sınırlama — yerleşik saatlik/günlük limitler ani patlamaları önler
  • Gerçek tarayıcı — Playwright, Chromium'u sürer; gerçek bir kullanıcı oturumundan ayırt edilemez

⚠️ Bu kütüphane kişisel kullanım, araştırma ve test amaçlıdır. Instagram'da otomasyon kullanmak Hizmet Şartları'nı ihlal edebilir. Sorumlu kullan ve riski sana aittir.


🗂️ Proje Yapısı

instaflow/
├── index.js          # Giriş: InstagramBot sınıfı + mixin birleştirme (module.exports)
├── src/              # Uygulama, sorumluluğa göre bölünmüş
│   ├── constants.js  # User-agent, viewport, varsayılan hız limitleri
│   ├── utils.js      # delay() ve paylaşılan yardımcılar
│   ├── auth.js       # init / login / close (tarayıcı yaşam döngüsü)
│   ├── safety.js     # humanize, hız sınırlama, engel tespiti, korumalar
│   ├── content.js    # gönderi / hikaye / profil düzenleme / silme (yayınlama)
│   ├── engagement.js # yorum / beğeni / kaydetme / toplu hashtag beğenme
│   ├── social.js     # takip / takipten çıkma / DM / hikaye etkileşimleri
│   └── insights.js   # profil / gönderi / reel kazıma, arama, gelen kutusu, indirme
├── example.js        # Temel kullanım örneği
├── example_publish.js
├── example_interaction.js
├── tests/
│   ├── run.js        # Test düzenleyici (node tests/run.js)
│   └── test_*.js
└── sessions/         # Chrome profil dizinleri (gitignore'lu)

Genel API tek bir sınıftır (require('instaflow')). Dahili olarak src/ modüllerinden Object.assign(prototype, ...) ile oluşturulur, böylece her metot aynı this'i paylaşır (page, context, hız sınırlayıcı durumu).


🤝 Katkıda Bulunma

Pull request'ler memnuniyetle karşılanır. Büyük değişiklikler için lütfen önce bir issue açın.

git clone https://github.com/alpersamur3/instaflow.git
cd instaflow
npm install
npx playwright install chromium
node tests/run.js

📄 Lisans

MIT © 2026 alpersamur3