Skip to content

Commit e85a0f6

Browse files
committed
Fix uploadPhoto (based on PR#144) (#165)
* Updated uploadPhoto without axios Authored-by: codexJoin <[email protected]>
1 parent 18ab832 commit e85a0f6

6 files changed

Lines changed: 380 additions & 414 deletions

File tree

README.md

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ const client = new Instagram({ username, password, cookieStore })
7777

7878
await client.login()
7979

80-
// Upload Photo
81-
const { media } = await client.uploadPhoto(photo)
80+
// Upload Photo to feed or story, just configure 'post' to 'feed' or 'story'
81+
const { media } = await client.uploadPhoto({ photo: photo, caption: 'testing', post: 'feed' })
8282
console.log(`https://www.instagram.com/p/${media.code}/`)
8383
})()
8484
```
@@ -98,8 +98,7 @@ const client = new Instagram({ username, password, cookieStore })
9898
* [.updateProfile({ name, email, username, phoneNumber, gender, biography, website, similarAccountSuggestions })](#updateprofileparams)
9999
* [.changeProfilePhoto({ photo })](#changeprofilephotoparams)
100100
* [.deleteMedia({ mediaId })](#deletemediaparams)
101-
* [.uploadPhoto({ photo, caption })](#uploadphotoparams)
102-
* [.uploadStory({ photo, caption })](#uploadstoryparams)
101+
* [.uploadPhoto({ photo, caption, post })](#uploadphotoparams)
103102
* [.getMediaFeedByLocation({ locationId })](#getmediafeedbylocationparams)
104103
* [.getMediaFeedByHashtag({ hashtag })](#getmediafeedbyhashtagparams)
105104
* [.locationSearch({ query, latitude, longitude })](#locationsearchparams)
@@ -244,22 +243,13 @@ await client.deleteMedia({ mediaId: '1442533050805297981' })
244243
### uploadPhoto(params)
245244
```js
246245
const photo = 'https://scontent-scl1-1.cdninstagram.com/t51.2885-15/e35/16465198_658888867648924_4042368904838774784_n.jpg'
247-
await client.uploadPhoto({ photo, caption: '❤️' })
246+
await client.uploadPhoto({ photo, caption: '❤️', post: 'feed' })
248247
```
249-
> Upload a photo to Instagram.
250-
- `params`
251-
- `photo`: A `String` of path file or URL
252-
- `caption`: The caption of photo. Default is ` `
253-
254-
### uploadStory(params)
255-
```js
256-
const photo = 'https://scontent-scl1-1.cdninstagram.com/t51.2885-15/e35/16465198_658888867648924_4042368904838774784_n.jpg'
257-
await client.uploadStory({ photo })
258-
```
259-
> Upload a story to Instagram, it only work for images (`jpg`)
248+
> Upload a photo to Instagram. Only jpeg images allowed.
260249
- `params`
261250
- `photo`: A `String` of path file or URL
262251
- `caption`: The caption of photo. Default is ` `
252+
- `post`: The local post, `feed` or `story`
263253

264254
### getMediaFeedByLocation(params)
265255
```js

helpers/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
module.exports = {
22
media: {
33
GraphImage: {
4-
id: '1442533050805297981',
4+
id: '2366929737360789025',
55
pk: 1442533050805297981,
6-
shortcode: 'BQE6Cq2AqM9',
7-
comments: [{ id: '17865614554065776' }]
6+
shortcode: 'CDZBg47ss4h',
7+
comments: [{ id: '17844885632304941' }]
88
}
99
},
1010
users: {

lib/index.js

Lines changed: 94 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ class Instagram {
8787
this.request = this.request.defaults({
8888
headers: { 'X-CSRFToken': csrftoken }
8989
})
90+
9091
this.credentials = {
9192
username,
9293
password,
@@ -360,29 +361,103 @@ class Instagram {
360361
}
361362

362363
async _uploadPhoto({ photo }) {
363-
return this.request.post('/create/upload/photo/', {
364-
formData: {
365-
upload_id: Date.now().toString(),
366-
photo: isUrl(photo) ? request(photo) : fs.createReadStream(photo),
367-
media_type: '1'
368-
}
369-
})
370-
}
364+
// Warning! don't change anything bellow.
365+
const uploadId = Date.now()
366+
367+
let file
371368

372-
async uploadStory({ photo, caption = '' }) {
373-
return this._uploadPhoto({ photo }).then(({ upload_id }) =>
374-
this.request.post('/create/configure_to_story/', {
375-
form: { upload_id, caption }
369+
// Needed to new method, if image is from url.
370+
if (isUrl(photo)) {
371+
// Enconding: null is required, only this way a Buffer is returned
372+
file = await request.get({ url: photo, encoding: null })
373+
} else {
374+
file = await fs.readFileSync(photo)
375+
}
376+
377+
const ruploadParams = {
378+
media_type: 1,
379+
upload_id: uploadId.toString(),
380+
upload_media_height: 1080,
381+
upload_media_width: 1080,
382+
xsharing_user_ids: JSON.stringify([]),
383+
image_compression: JSON.stringify({
384+
lib_name: 'moz',
385+
lib_version: '3.1.m',
386+
quality: '80'
376387
})
377-
)
388+
}
389+
390+
const nameEntity = `${uploadId}_0_${Math.random(1000000000, 9999999999)}`
391+
392+
const headersPhoto = {
393+
'x-entity-type': 'image/jpeg',
394+
offset: 0,
395+
'x-entity-name': nameEntity,
396+
'x-instagram-rupload-params': JSON.stringify(ruploadParams),
397+
'x-entity-length': file.byteLength,
398+
'Content-Length': file.byteLength,
399+
'Content-Type': 'application/octet-stream',
400+
'x-ig-app-id': `1217981644879628`,
401+
'Accept-Encoding': 'gzip',
402+
'X-Pigeon-Rawclienttime': (Date.now() / 1000).toFixed(3),
403+
'X-IG-Connection-Speed': `${Math.random(1000, 3700)}kbps`,
404+
'X-IG-Bandwidth-Speed-KBPS': '-1.000',
405+
'X-IG-Bandwidth-TotalBytes-B': '0',
406+
'X-IG-Bandwidth-TotalTime-MS': '0'
407+
}
408+
409+
// Json = false, must be important to post work!
410+
let responseUpload = await this.request({
411+
uri: `/rupload_igphoto/${nameEntity}`,
412+
headers: headersPhoto,
413+
method: 'POST',
414+
json: false,
415+
body: file
416+
})
417+
418+
try {
419+
responseUpload = JSON.parse(responseUpload)
420+
421+
if ('upload_id' in responseUpload) return responseUpload
422+
423+
throw new Error('Image upload error')
424+
} catch (e) {
425+
throw new Error(`Image upload error: ${e}`)
426+
}
378427
}
379428

380-
async uploadPhoto({ photo, caption = '' }) {
381-
return this._uploadPhoto({ photo }).then(({ upload_id }) =>
382-
this.request.post('/create/configure/', {
383-
form: { upload_id, caption }
384-
})
385-
)
429+
// Upload to story moved to uploadPhoto
430+
// Post: 'feed' or 'story'
431+
async uploadPhoto({ photo, caption = '', post = 'feed' }) {
432+
const dateObj = new Date()
433+
const now = dateObj
434+
.toISOString()
435+
.replace(/T/, ' ')
436+
.replace(/\..+/, ' ')
437+
const offset = dateObj.getTimezoneOffset()
438+
439+
const responseUpload = await this._uploadPhoto({ photo })
440+
441+
return this.request
442+
.post(
443+
`/create/${post === 'feed' ? 'configure/' : 'configure_to_story/'}`,
444+
{
445+
form: {
446+
upload_id: responseUpload.upload_id,
447+
caption,
448+
timezone_offset: offset,
449+
date_time_original: now,
450+
date_time_digitalized: now,
451+
source_type: '4',
452+
edits: {
453+
crop_original_size: [1080, 1080],
454+
crop_center: [0.0, -0.0],
455+
crop_zoom: 1.0
456+
}
457+
}
458+
}
459+
)
460+
.then(response => response)
386461
}
387462

388463
async getMediaFeedByLocation({ locationId }) {

0 commit comments

Comments
 (0)