Skip to content

Commit

Permalink
request options can be modified in constructor. Added pagination in g…
Browse files Browse the repository at this point in the history
…etUserByUsername()
  • Loading branch information
k-miras committed May 28, 2018
1 parent 08af220 commit 8feca64
Show file tree
Hide file tree
Showing 5 changed files with 1,734 additions and 1,635 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
node_modules
test/credentials.json
test/cookies.json
111 changes: 93 additions & 18 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ const useragentFromSeed = require('useragent-from-seed')
const baseUrl = 'https://www.instagram.com'

class Instagram {
constructor({ username, password, cookieStore }, { language, proxy } = {}) {
constructor(
{ username, password, cookieStore },
{ language, proxy, requestOptions } = {}
) {
this.credentials = {
username,
password
Expand All @@ -22,21 +25,22 @@ class Instagram {
jar.getCookies(baseUrl).find(({ key }) => key === 'csrftoken') || {}

const userAgent = useragentFromSeed(username)

this.request = request.defaults({
baseUrl,
headers: {
'User-Agent': userAgent,
'Accept-Language': language || 'en-US',
'X-Instagram-AJAX': 1,
'X-CSRFToken': csrftoken,
'X-Requested-With': 'XMLHttpRequest',
Referer: baseUrl
},
proxy,
json: true,
jar
})
if (requestOptions === undefined) {
requestOptions = {}
}
requestOptions.baseUrl = baseUrl
requestOptions.headers = {
'User-Agent': userAgent,
'Accept-Language': language || 'en-US',
'X-Instagram-AJAX': 1,
'X-CSRFToken': csrftoken,
'X-Requested-With': 'XMLHttpRequest',
Referer: baseUrl
}
requestOptions.proxy = proxy
requestOptions.jar = jar
requestOptions.json = true
this.request = request.defaults(requestOptions)
}

async login({ username, password } = {}, { _sharedData = true } = {}) {
Expand Down Expand Up @@ -110,13 +114,66 @@ class Instagram {
return this.request('/?__a=1').then(data => data.graphql.user)
}

async getUserByUsername({ username }) {
return this.request({
async getUserByUsername({ username, takePostPages = 0, postsPerPage = 12 }) {
console.log('request')
const result = await this.request({
uri: `/${username}/?__a=1`,
headers: {
'x-instagram-gis': await this._getGis(`/${username}/`)
}
}).then(data => data.graphql.user)
if (postsPerPage > 50) {
postsPerPage = 50
}
if (postsPerPage < 12) {
postsPerPage = 12
}
const needMorePosts = takePostPages > 0 || postsPerPage > 12
const needToReturnCount = takePostPages * postsPerPage
if (
needMorePosts &&
result.edge_owner_to_timeline_media.page_info.has_next_page === true
) {
// We've decided, that we need more posts
let has_next_page = true
let nextPageToken =
result.edge_owner_to_timeline_media.page_info.end_cursor
const userId = result.id
const infiniteLoop = true
while (infiniteLoop) {
if (has_next_page === false) {
break
}
if (
result.edge_owner_to_timeline_media.edges.length >= needToReturnCount
) {
break
}

let perPage = postsPerPage

if (result.edge_owner_to_timeline_media.edges.length < postsPerPage) {
const fillFirstPage =
postsPerPage - result.edge_owner_to_timeline_media.edges.length
perPage = fillFirstPage // We have to fill first page posts count to postsPerPage
}
const page = await this._getPosts({
userId,
perPage,
nextPageToken
})

has_next_page =
page.edge_owner_to_timeline_media.page_info.has_next_page
nextPageToken = page.edge_owner_to_timeline_media.page_info.end_cursor
result.edge_owner_to_timeline_media.edges = [
...result.edge_owner_to_timeline_media.edges,
...page.edge_owner_to_timeline_media.edges
]
}
result.edge_owner_to_timeline_media.page_info.end_cursor = nextPageToken // We're giving possibility to use _getPosts() after all
}
return result
}

async getStoryReelFeed({ onlyStories = false } = {}) {
Expand Down Expand Up @@ -420,6 +477,24 @@ class Instagram {
search({ query, context = 'blended' }) {
return this.request('/web/search/topsearch/', { qs: { query, context } })
}

async _getPosts({ userId, perPage = 12, nextPageToken }) {
const variables = JSON.stringify({
id: userId,
first: perPage,
after: nextPageToken
})
const options = {
qs: {
query_hash: '42323d64886122307be10013ad2dcc44',
variables
}
}

return this.request
.get('/graphql/query/', options)
.then(response => response.data.user)
}
}

module.exports = Instagram
Loading

0 comments on commit 8feca64

Please sign in to comment.