Skip to content

Commit 2fedb9a

Browse files
committed
Use publish service
1 parent 671f8da commit 2fedb9a

7 files changed

Lines changed: 94 additions & 42 deletions

File tree

examples/live-replay-to-igtv.example.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,15 @@ async function login() {
8181
.toBuffer();
8282

8383
// Upload the thumbnail with a broadcast id for a replay and get uploadId
84-
let upload = await ig.upload.photo({file, broadcastId: broadcast_id});
85-
86-
let igtv = await ig.media.configureToIgtv({
87-
upload_id: upload.upload_id,
84+
let igtv = await ig.publish.liveIgtv({
85+
file,
86+
broadcastId: broadcast_id,
8887
title: 'A title',
8988
caption: 'A description',
90-
igtv_share_preview_to_feed: '1',
91-
}, 2000)
89+
igtv_share_preview_to_feed: '1'
90+
});
9291

93-
console.log(`Live posted to IGTV : ${igtv.upload_id}`));
92+
console.log(`Live posted to IGTV : ${igtv.upload_id}`);
9493
// now you're basically done
9594
})();
9695

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { IgResponseError } from './ig-response.error';
2+
import { IgResponse } from '../types';
3+
import { UploadRepositoryVideoResponseRootObject } from '../responses';
4+
5+
export class IgUploadLiveIgtvError extends IgResponseError {
6+
constructor(response: IgResponse<UploadRepositoryVideoResponseRootObject>) {
7+
super(response);
8+
}
9+
}

src/errors/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ export * from './ig-challenge-wrong-code.error';
2222
export * from './ig-exact-user-not-found-error';
2323
export * from './ig-user-id-not-found.error';
2424
export * from './ig-upload-video-error';
25+
export * from './ig-upload-live-igtv-error';
2526
export * from './ig-user-has-logged-out.error';
2627
export * from './ig-configure-video-error';

src/repositories/media.repository.ts

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import { MediaRepositoryConfigureResponseRootObject } from '../responses';
3030
import Chance = require('chance');
3131
import { MediaRepositoryCheckOffensiveCommentResponseRootObject } from '../responses';
3232
import { StoryMusicQuestionResponse, StoryTextQuestionResponse } from '../types/story-response.options';
33-
import { IgResponseError } from "../errors";
3433

3534
export class MediaRepository extends Repository {
3635
public async info(mediaId: string): Promise<MediaInfoResponseRootObject> {
@@ -577,7 +576,7 @@ export class MediaRepository extends Repository {
577576
return body;
578577
}
579578

580-
public async configureToIgtv(options: MediaConfigureToIgtvOptions, retryDelay: number = 1000) {
579+
public async configureToIgtv(options: MediaConfigureToIgtvOptions) {
581580
const form: MediaConfigureToIgtvOptions = defaultsDeep(options, {
582581
caption: '',
583582
date_time_original: new Date().toISOString().replace(/[-:]/g, ''),
@@ -600,38 +599,24 @@ export class MediaRepository extends Repository {
600599
const retryContext = options.retryContext;
601600
delete form.retryContext;
602601

603-
let body = null;
604-
let response = null;
605-
while (!body) {
606-
try {
607-
response = await this.client.request.send({
608-
url: '/api/v1/media/configure_to_igtv/',
609-
method: 'POST',
610-
qs: {
611-
video: '1',
612-
},
613-
headers: {
614-
is_igtv_video: '1',
615-
retry_context: JSON.stringify(retryContext),
616-
},
617-
form: this.client.request.sign({
618-
...form,
619-
_csrftoken: this.client.state.cookieCsrfToken,
620-
_uid: this.client.state.cookieUserId,
621-
_uuid: this.client.state.uuid,
622-
}),
623-
});
602+
const { body } = await this.client.request.send({
603+
url: '/api/v1/media/configure_to_igtv/',
604+
method: 'POST',
605+
qs: {
606+
video: '1',
607+
},
608+
headers: {
609+
is_igtv_video: '1',
610+
retry_context: JSON.stringify(retryContext),
611+
},
612+
form: this.client.request.sign({
613+
...form,
614+
_csrftoken: this.client.state.cookieCsrfToken,
615+
_uid: this.client.state.cookieUserId,
616+
_uuid: this.client.state.uuid,
617+
}),
618+
});
624619

625-
body = response.body;
626-
} catch (e) {
627-
// Endpoint can return an error "202 Accepted; Transcode not finished yet" if Instagram has not finished to process the upload, retry after a delay
628-
if (!(e instanceof IgResponseError && e.response.statusCode === 202)) {
629-
throw e;
630-
} else {
631-
await new Promise(resolve => setTimeout(resolve, retryDelay));
632-
}
633-
}
634-
}
635620
return body;
636621
}
637622

src/services/publish.service.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ import {
1919
UploadVideoOptions,
2020
} from '../types';
2121
import { PostingLocation, PostingStoryOptions } from '../types/posting.options';
22-
import { IgConfigureVideoError, IgResponseError, IgUploadVideoError } from '../errors';
22+
import { IgConfigureVideoError, IgResponseError, IgUploadLiveIgtvError, IgUploadVideoError } from '../errors';
2323
import { StatusResponse, UploadRepositoryVideoResponseRootObject } from '../responses';
2424
import { PostingIgtvOptions } from '../types/posting.igtv.options';
25+
import { PostingLiveIgtvOptions } from "../types/posting.live-igtv.options";
2526
import sizeOf = require('image-size');
2627
import Bluebird = require('bluebird');
2728
import Chance = require('chance');
@@ -52,6 +53,22 @@ export class PublishService extends Repository {
5253
};
5354
}
5455

56+
/**
57+
* @param transcodeDelayInMs The delay for instagram to transcode the video
58+
*/
59+
public static catchLiveIgtvTranscodeError(transcodeDelayInMs: number) {
60+
return error => {
61+
if (error.response.statusCode === 202) {
62+
PublishService.publishDebug(
63+
`Received trancode error: ${JSON.stringify(error.response.body)}, waiting ${transcodeDelayInMs}ms`,
64+
);
65+
return Bluebird.delay(transcodeDelayInMs);
66+
} else {
67+
throw new IgUploadLiveIgtvError(error.response as IgResponse<UploadRepositoryVideoResponseRootObject>);
68+
}
69+
};
70+
}
71+
5572
/**
5673
* Gets duration in ms, width and height info for a video in the mp4 container
5774
* @param buffer Buffer, containing the video-file
@@ -453,6 +470,39 @@ export class PublishService extends Repository {
453470
}
454471
}
455472

473+
public async liveIgtv(options: PostingLiveIgtvOptions) {
474+
const uploadedPhoto = await this.client.upload.photo({
475+
file: options.file,
476+
broadcastId: options.broadcastId,
477+
});
478+
479+
await Bluebird.try(() =>
480+
this.client.media.uploadFinish({
481+
upload_id: uploadedPhoto.upload_id,
482+
source_type: '4',
483+
}),
484+
).catch(IgResponseError, PublishService.catchLiveIgtvTranscodeError(options.transcodeDelay || 5000));
485+
486+
const configureOptions: MediaConfigureToIgtvOptions = {
487+
upload_id: uploadedPhoto.upload_id,
488+
title: options.title,
489+
caption: options.caption,
490+
igtv_share_preview_to_feed: options.igtv_share_preview_to_feed,
491+
length: 0
492+
};
493+
494+
for (let i = 0; i < 6; i++) {
495+
try {
496+
return await this.client.media.configureToIgtv(configureOptions);
497+
} catch (e) {
498+
if (i >= 5 || e.response.statusCode >= 400) {
499+
throw new IgConfigureVideoError(e.response, configureOptions);
500+
}
501+
await Bluebird.delay((i + 1) * 2 * 1000);
502+
}
503+
}
504+
}
505+
456506
private async regularVideo(options: UploadVideoOptions) {
457507
options = defaults(options, {
458508
uploadId: Date.now(),

src/types/media.configure-to-igtv.options.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export interface MediaConfigureToIgtvOptions {
22
upload_id: string;
33
title: string;
44
length: number;
5-
extra: { source_width: number; source_height: number };
5+
extra?: { source_width: number; source_height: number };
66
caption?: string;
77
// will be converted to a json-string
88
feed_preview_crop?:
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export interface PostingLiveIgtvOptions {
2+
file: Buffer;
3+
title: string;
4+
caption?: string;
5+
broadcastId: string;
6+
igtv_share_preview_to_feed?: '1' | '0';
7+
transcodeDelay?: number
8+
}

0 commit comments

Comments
 (0)