x-api-sdk-ts
Version:
TypeScript Library for the X (ex-twitter) API V2
125 lines • 5.48 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Media = void 0;
const IMedia_1 = require("../interfaces/api/IMedia");
class Media extends IMedia_1.AbstractMedia {
async upload(media, mimeType, category, additionalOwners = null, chunkSize, minWaitingTimeInSeconds) {
const initResponse = await this.initMediaUpload(media.length, mimeType, category, additionalOwners);
if (!this.requestClient.isSuccessResponse(initResponse)) {
return initResponse;
}
const mediaId = initResponse.data.data.id;
const minChunkSize = 1024 * 1024;
const maxChunkSize = 1024 * 1024 * 4;
const tenthOfMediaLength = Math.ceil(media.length / 10);
const defaultChunkSize = Math.min(maxChunkSize, Math.max(minChunkSize, tenthOfMediaLength));
const cs = chunkSize || defaultChunkSize;
const chunks = Math.ceil(media.length / cs);
for (let i = 0; i < chunks; i++) {
const start = i * cs;
const end = Math.min(start + cs, media.length);
const chunk = media.subarray(start, end);
const appendResponse = await this.appendMediaChunk(mediaId, i, chunk);
if (!appendResponse.ok) {
return appendResponse;
}
}
const finalizeResponse = await this.finalizeMediaUpload(mediaId);
if (!this.requestClient.isSuccessResponse(finalizeResponse)) {
return finalizeResponse;
}
if (finalizeResponse.data.data.processing_info) {
const waitingResponse = await this.waitForProcessing(mediaId, finalizeResponse, minWaitingTimeInSeconds);
return waitingResponse;
}
return finalizeResponse;
}
async getStatus(mediaId) {
const headers = await this.oAuth2.getHeaders();
return this.requestClient.get(`${this.baseUrl}/2/media/upload`, { command: 'STATUS', media_id: mediaId }, headers);
}
async addMetadata(mediaId, altText, allowDownload, originalId, originalProvider, uploadSource) {
const headers = await this.oAuth2.getHeaders();
const requestBody = {
id: mediaId,
metadata: {}
};
if (altText) {
requestBody.metadata.alt_text = {
text: altText
};
}
requestBody.metadata.allow_download_status = {
allow_download: allowDownload
};
if (originalId && originalProvider) {
requestBody.metadata.found_media_origin = {
id: originalId,
provider: originalProvider
};
}
if (uploadSource) {
requestBody.metadata.upload_source = {
upload_source: uploadSource
};
}
return this.requestClient.post(`${this.baseUrl}/2/media/metadata`, requestBody, {
...headers,
'Content-Type': 'application/json'
});
}
async initMediaUpload(totalBytes, mediaType, mediaCategory, additionalOwners = null) {
const headers = await this.oAuth2.getHeaders();
const formData = {
command: 'INIT',
total_bytes: totalBytes,
media_type: mediaType
};
if (mediaCategory) {
formData.media_category = mediaCategory;
}
if (additionalOwners && additionalOwners.length > 0) {
formData.additional_owners = additionalOwners;
}
return this.requestClient.post(`${this.baseUrl}/2/media/upload`, formData, headers, undefined, 'multipart/form-data');
}
async appendMediaChunk(mediaId, segmentIndex, chunk) {
const headers = await this.oAuth2.getHeaders();
const params = {
command: 'APPEND',
media_id: mediaId,
segment_index: segmentIndex,
media: new Blob([chunk])
};
return await this.requestClient.post(`${this.baseUrl}/2/media/upload`, params, headers, undefined, 'multipart/form-data');
}
async finalizeMediaUpload(mediaId) {
const headers = await this.oAuth2.getHeaders();
const formData = {
command: 'FINALIZE',
media_id: mediaId
};
return this.requestClient.post(`${this.baseUrl}/2/media/upload`, formData, headers, undefined, 'multipart/form-data');
}
async waitForProcessing(mediaId, initialResponse, minWaitingTimeInSeconds) {
var _a;
let response = initialResponse;
let data = response.data.data;
while (response && data && typeof data !== 'string' &&
data.processing_info &&
['pending', 'in_progress'].includes(data.processing_info.state)) {
const checkAfterSecs = Math.min(minWaitingTimeInSeconds || 0, ((_a = data.processing_info) === null || _a === void 0 ? void 0 : _a.check_after_secs) || 1);
await new Promise(resolve => setTimeout(resolve, checkAfterSecs * 1000));
const rcResponse = await this.getStatus(mediaId);
if (!this.requestClient.isSuccessResponse(rcResponse)) {
console.error('Error waiting for media processing to complete (status)', JSON.stringify(rcResponse, null, 2));
return rcResponse;
}
response = rcResponse;
data = response.data.data;
}
return response;
}
}
exports.Media = Media;
//# sourceMappingURL=media.js.map