UNPKG

tiktok-private-api-suyank

Version:

Unofficial TikTok API wrapper for scraping user info and posts.

171 lines 8.12 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.UserRepository = void 0; const qs_1 = __importDefault(require("qs")); const debug_1 = __importDefault(require("debug")); const repository_1 = require("../core/repository"); const errors_1 = require("../errors"); class UserRepository extends repository_1.Repository { constructor(client) { super(); this.client = client; this.userDebug = (0, debug_1.default)("tiktok:user"); this._defaultApiParams = { aid: "1988", app_name: "tiktok_web", device_platform: "web_mobile", region: "US", os: "ios", cookie_enabled: "true", screen_width: "1065", screen_height: "1623", browser_language: "en-gb", browser_platform: "iPhone", browser_name: "Mozilla", browser_version: this.client.state.mobileUserAgent, browser_online: "true", timezone_name: "Asia/Karachi", is_page_visible: "true", focus_state: "true", is_fullscreen: "false", history_len: null, language: "en", count: null, id: null, cursor: null, type: "1", secUid: null, sourceType: "8", appId: "1233", priority_region: "US", verifyFp: "verify_khr3jabg_V7ucdslq_Vrw9_4KPb_AJ1b_Ks706M8zIJTq", device_id: null, }; } /** * Get user info * * @param username * @returns */ info(username) { return __awaiter(this, void 0, void 0, function* () { const url = `https://www.tiktok.com/@${username}?lang=en`; this.userDebug(`Sending request to ${url}`); const headers = { accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "accept-encoding": "gzip, deflate, br", "accept-language": "en-US,en;q=0.9", "sec-ch-ua": '" Not A;Brand";v="99", "Chromium";v="103", "Google Chrome";v="103"', "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": '"macOS"', "sec-fetch-dest": "document", "sec-fetch-mode": "navigate", "sec-fetch-site": "none", "sec-fetch-user": "?1", "upgrade-insecure-requests": "1", "user-agent": this.client.state.webUserAgent, }; const response = yield this.client.request.send(url, headers); const parsed = yield this.parseHtmlContent(response.body); if (parsed) { const obj = JSON.parse(parsed); const userModule = obj["UserModule"]; const itemModule = obj["ItemModule"]; return { userInfo: Object.assign(Object.assign({}, userModule.users[username]), { stats: userModule.stats[username], itemList: Object.values(itemModule) }), seoProps: { metaParams: obj["SEO"]["metaParams"], }, }; } return null; }); } /** * Get user videos * * @param id * @param secUid * @param count * @param cursor * @returns */ videos(id, secUid, count, cursor) { return __awaiter(this, void 0, void 0, function* () { const deviceId = this.client.helper.generateDeviceId(); let url = new URL(`https://m.tiktok.com/api/post/item_list/?${qs_1.default.stringify(Object.assign(Object.assign({}, this._defaultApiParams), { id: id, secUid: secUid, count: count, cursor: cursor, device_id: deviceId, history_len: this.client.helper.getRandomInt(1, 5) }))}`); const signature = this.client.signer.sign(url.toString()); url.searchParams.append("_signature", signature); this.userDebug(`Generated signed url ${url.toString()}`); const bogus = this.client.signer.bogus(url.searchParams.toString()); url.searchParams.append("X-bogus", bogus); this.userDebug(`Generated bogus url ${url}`); const xTTParams = this.client.signer.xttparams(url.searchParams.toString()); const response = yield this.client.request.send(url.toString(), Object.assign(Object.assign({}, this.client.state.defaultApiHeaders), { "user-agent": this.client.state.mobileUserAgent, "x-tt-params": xTTParams })); const responseBody = JSON.parse(response.body); if (responseBody.statusCode === 0 && responseBody.itemList) { return responseBody; } throw new errors_1.GenericError("Generic API error happened."); }); } /** * Get user liked videos * * @param id * @param secUid * @param count * @param cursor * @returns */ liked(id, secUid, count, cursor) { return __awaiter(this, void 0, void 0, function* () { const deviceId = this.client.helper.generateDeviceId(); let url = new URL(`https://m.tiktok.com/api/favorite/item_list/?${qs_1.default.stringify(Object.assign(Object.assign({}, this._defaultApiParams), { id: id, secUid: secUid, count: count, cursor: cursor, device_id: deviceId, history_len: this.client.helper.getRandomInt(1, 5) }))}`); const signature = this.client.signer.sign(url.toString()); url.searchParams.append("_signature", signature); this.userDebug(`Generated signed url ${url.toString()}`); const bogus = this.client.signer.bogus(url.searchParams.toString()); url.searchParams.append("X-bogus", bogus); this.userDebug(`Generated bogus url ${url}`); const xTTParams = this.client.signer.xttparams(url.searchParams.toString()); const response = yield this.client.request.send(url.toString(), Object.assign(Object.assign({}, this.client.state.defaultApiHeaders), { "user-agent": this.client.state.mobileUserAgent, "x-tt-params": xTTParams })); const responseBody = JSON.parse(response.body); if (responseBody.statusCode === 0 && responseBody.itemList) { return responseBody; } throw new errors_1.GenericError("Generic API error happened."); }); } /** * Parse TikTok response and return sigi_state * * @param content * @returns */ parseHtmlContent(content) { return __awaiter(this, void 0, void 0, function* () { if (content.includes("SIGI_STATE")) { const rawVideoMetadata = content .split('<script id="SIGI_STATE" type="application/json">')[1] .split("</script>")[0]; return rawVideoMetadata; } }); } } exports.UserRepository = UserRepository; //# sourceMappingURL=user.repository.js.map