tiktok-private-api-suyank
Version:
Unofficial TikTok API wrapper for scraping user info and posts.
171 lines • 8.12 kB
JavaScript
;
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