@@ -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